<    April 2017    >
Su Mo Tu We Th Fr Sa  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
00:00 bydo joined
00:00 wroathe joined
00:00 atk joined
00:02 Ferdirand joined
00:07 wroathe joined
00:08 filterfish joined
00:10 erisco joined
00:13 splanch joined
00:16 <joneshf-laptop> Is there a way in wai to get the request body without consuming it?
00:16 acidjnk22 joined
00:20 Lord_of_Life joined
00:25 <EvanR> joneshf-laptop: im not sure that would make sense
00:26 <joneshf-laptop> Why's that?
00:26 tripped joined
00:27 <EvanR> you want to read from a socket without disturbing the socket
00:28 <EvanR> they just dont work like that
00:29 jbiesnecker joined
00:29 <joneshf-laptop> So it's something specific to the implementation of wai that makes it impossible?
00:30 <geekosaur> ?
00:30 <EvanR> the request you get is not complete, the body maybe streaming, infinite
00:30 andyhuzhill joined
00:30 <geekosaur> what do you believe is going on that you can do this?
00:31 <EvanR> you can ask for the next chunk, and that dequeues it logically from the sockets secret buffer
00:31 <EvanR> now you can do what you want with it
00:31 cschneid_ joined
00:32 katychuang_ joined
00:32 <joneshf-laptop> geekosaur, I hadn't looked into the internals of wai. I didn't know that the `IO ByteString` was a direct socket, rather than it "just" being a `ByteString` "in" `IO`.
00:33 Ferdirand joined
00:33 <joneshf-laptop> EvanR, thanks, tht makes sense.
00:33 <joneshf-laptop> I mean, the explanation makes sense.
00:34 <joneshf-laptop> That's interesting though
00:35 <boxscape> @pl \(x,y,z) -> x y z -- what is that supposed to mean
00:35 <lambdabot> (line 1, column 7):
00:35 <lambdabot> unexpected "z"
00:35 <lambdabot> ambiguous use of a non associative operator
00:36 <joneshf-laptop> I'd figure there'd be something holding on to the `ByteString` once the request is "complete"
00:36 <boxscape> I suppose lambdabot doesn't allow pattern matching on higher tuples than paris
00:36 <boxscape> pairs*
00:37 <geekosaur> it's pointfree that can't do it
00:37 andyhuzhill joined
00:37 <geekosaur> since there are no standard combinators for it, yeh
00:37 <joneshf-laptop> Does that mean that somebody's middleware can just hijack the request body and your application might never get data?
00:37 <boxscape> geekosaur: er, right, that's what I meant
00:38 <geekosaur> joneshf-laptop, I would really hope nothing is holding onto it if it's a PUT with a 5GB body
00:38 Jeanne-Kamikaze joined
00:39 <EvanR> joneshf-laptop: you are holding onto it
00:39 <joneshf-laptop> geekosaur, I feel like I'm thinking about this all wrong. How do you do things like send the request body to multiple programs?
00:40 <EvanR> once you have the body (assuming its not infinite) you can do that
00:40 <joneshf-laptop> who?
00:40 nighty-- joined
00:40 <joneshf-laptop> a middleware?
00:40 <joneshf-laptop> or the application?
00:40 <EvanR> whatever is handling the request
00:40 <geekosaur> either one
00:40 <joneshf-laptop> how's that?
00:40 sleffy joined
00:41 benl23 joined
00:41 <geekosaur> a middleware could capture a PUT to file and pass that on, or your application can do so or do something else with it
00:41 Ferdirand joined
00:41 Lord_of_Life joined
00:41 cyborg-one joined
00:42 <joneshf-laptop> But like, if one middleware in the chain decides to consume the body and not make it available, doesn't the whole thing fall down?
00:42 <geekosaur> but, for wai, your application got invoked based on the path in the request. it's your application that decides what to do; nothing else will be invoked
00:43 <geekosaur> yes, but the middleware should be under your control as well
00:43 jgt2 joined
00:43 <geekosaur> otherwise I think you're doing something very wrong just from a security standpoint
00:44 <geekosaur> "Middleware is a component that sits between the server and application. It can do such tasks as GZIP encoding or response caching."
00:45 <geekosaur> so, say, a Middleware handles gunzipping a gzip stream. if something goes wrong you get no body --- but you weren't going to get anything useful anyway in that case
00:46 jedws joined
00:46 <joneshf-laptop> Hmm.
00:46 <joneshf-laptop> I'll buy that.
00:46 <joneshf-laptop> So, here's my deal.
00:47 <joneshf-laptop> I want to catch 500s and log them
00:47 <joneshf-laptop> Ideally I'd like to log the request body as well
00:47 <joneshf-laptop> Is there a pattern for doing that without breaking things?
00:47 <joneshf-laptop> like, tee-ing off the socket or something?
00:48 capuk joined
00:48 StoneToad joined
00:48 <geekosaur> sounds to me like a Middleware is exactly what you want here, then: one that captures the request, possibly throwing if it's not a fixed size (and it can log itself in that case), and what it passes on is a file containing the data
00:48 <geekosaur> you cant tee off a socket, you're getting the data as it is passed on from the network
00:49 <geekosaur> once it's been read, it's gone
00:49 <Koterpillar> you can save it to a file and pass a handle to that file as the new body?
00:49 <Koterpillar> (assuming WAI allows that, which I don't know)
00:49 <geekosaur> you'd have to pass the filename, I think
00:49 <joneshf-laptop> Am i too low level here?
00:49 <geekosaur> but otherwise, yes, that's what I am thinking
00:50 <geekosaur> yes, wai is very low level for this stuff
00:50 sophiag joined
00:50 <joneshf-laptop> I'm happy to go higher, if you have a suggestion.
00:50 <geekosaur> a Middleware to save to file and pass that on is one way to make it higher level
00:51 <joneshf-laptop> Is there a conduit thing that might be of use?
00:52 <geekosaur> http://hackage.haskell.org/package/wai-conduit ?
00:52 <geekosaur> which gives you a pipeline in the application which might or might not help you, yes
00:52 wroathe joined
00:56 bhiliyam joined
00:56 plutoniix joined
00:57 plutoniix joined
01:00 feynhat joined
01:01 javjarfer joined
01:03 eazar001 joined
01:05 <joneshf-laptop> hmm
01:05 <joneshf-laptop> Thanks. I'll play with it a bit.
01:06 vaibhavsagar joined
01:10 {emptyset} joined
01:11 <EvanR> any ideas for ways to visualize an arbitrary Double value in a small amount of screen area
01:14 soLucien joined
01:14 harfangk joined
01:14 tathougies joined
01:16 cpennington joined
01:16 Stanley00 joined
01:18 Argue__ joined
01:19 dhruvio joined
01:24 <sophiag> can anyone help me debug the eval function in the following paste? it takes two records, each with Maybe Strings and one with list and the other with lambdas representing boolean conditions. ideally it should return every permutation of the lists and filter based on lambdas when the strings match (including Nothing). i'm trying to go back and build it up incrementally, i.e. first just returning unfiltered permutations, but since i
01:24 <sophiag> needed such complicated ADTs i keep getting the type signature wrong even for that: http://lpaste.net/354469
01:25 takle joined
01:26 louispan joined
01:28 jbiesnecker joined
01:28 latencyloser joined
01:29 <joneshf-laptop> sophiag, what is the error?
01:29 jedws joined
01:30 <sophiag> joneshf-laptop: i added them at the bottom: http://lpaste.net/354469
01:32 <sophiag> on second thought it should maybe be eval :: [Amb] -> [[MultiList]] ...but that also returns a type error
01:32 steeze joined
01:34 pyx joined
01:35 sleffy joined
01:36 ubsan_ joined
01:42 marcopullo joined
01:43 cmsmcq joined
01:43 des_ joined
01:44 acarrico joined
01:44 jokester joined
01:45 <joneshf-laptop> geekosaur, EvanR So, I was greatly overthinking it, and I'm not sure why. Naively, can do `dup r = (\x -> (r { requestBody = pure x }, r { requestBody = pure x })) <$> requestBody r`
01:46 <joneshf-laptop> But that probably leaks memory or something.
01:46 abhixec joined
01:47 splanch joined
01:47 edvorg joined
01:48 <EvanR> that probably doesnt do what you think
01:48 <EvanR> it doesnt duplicate a request
01:48 <joneshf-laptop> what does it do?
01:49 <Koterpillar> rather, it doesn't do what you need, which is to log the body
01:49 <EvanR> it creates a request with a copy of the first chunk recieved
01:49 <EvanR> received
01:49 <joneshf-laptop> Ah!
01:49 pera joined
01:50 Supersonic112_ joined
01:50 <EvanR> and the original request will be affected
01:50 <joneshf-laptop> Koterpillar, right, I've got the logging taken care of, but noticed that the application was consuming the requestand the logger getting nothing. Which sent me down this rabbit hole :)
01:51 <joneshf-laptop> I find it a little hard to swallow that this doesn't exist somewhere already.
01:51 <joneshf-laptop> It make sme thing that I'm doing something REALLY wrong.
01:51 <EvanR> how are you logging a 500 when 500 is a response, not a request
01:52 <joneshf-laptop> in the handler
01:53 <joneshf-laptop> I was giving the initial request to the app, and constructing a new handler where I check what the response is, and log accordingly.
01:53 takle joined
01:53 <joneshf-laptop> then calling the initial handler with the response
01:54 <joneshf-laptop> wow, my English is pretty bad right now.
01:54 <joneshf-laptop> sorry :|
01:56 bhiliyam joined
01:57 <geekosaur> you need to rethink this, I think. the whole notion of duplicating a request is dubious when a request is indefinite length
01:57 <geekosaur> and invoking requestBody just gets you whatever the network has available right now from it --- the sender may well still be sending it at that time!
01:57 <EvanR> you could "tee" it, except sockets dont have that
01:58 <geekosaur> that is, you can't get the next chunk because it hasn't been sent yet
01:58 <geekosaur> this stuff runs *live*, it is not a completed request that you receive but the ongoing and quite possibly incomplete request, which can be dispatched via its header
01:59 <joneshf-laptop> Okay.
01:59 <joneshf-laptop> What might be a better way?
02:00 sdrodge joined
02:00 hucksy joined
02:02 <Sornaensis> > [toDyn 4.1, toDyn "blorps"]
02:02 <lambdabot> [<<Double>>,<<[Char]>>]
02:05 <geekosaur> joneshf-laptop, uh... I think you have to figure that out yourself, including what to do if the connection aborts after you have read a chunk (this is not necessarily the same as getting an empty chunk back; it may be sent as an exception)
02:06 <EvanR> getting an empty chunk = body complete
02:06 <EvanR> hopefully its not like getContents and you also get empty in case of error
02:07 <joneshf-laptop> this is thoroughly disappointing.
02:08 <geekosaur> so you are imagining that magic happens somewhere?
02:08 kadobanana joined
02:08 <geekosaur> do you understand that, fundamentally, this is all happening *online* and you do not at any point have "a single completely read request", and no wrapper can help you with this because the concept itself does not exist?
02:09 exferenceBot joined
02:09 <geekosaur> I kinda feel like trying to teach serial terminals to someone who's only worked with block mode
02:09 <joneshf-laptop> Yeah, I get th eunderlying model.
02:10 <joneshf-laptop> I'm just disappointed that there's not an off-the-shelf way to tee the request.
02:11 nh2 joined
02:11 ContessaTP joined
02:11 <EvanR> so log the body to a file, later if you response is 500, remember where you put that file and use it as part of the log
02:11 <EvanR> otherwise delete it
02:12 <EvanR> i guess the application also must now use that file
02:12 <geekosaur> I'm not even sure how teeing the request would work. you capture to file, or you have to use something like a Chan/TChan
02:12 nh2 joined
02:12 <geekosaur> you can't do it with a socket because a socket is a firehose fed by a remote system, it doesn't "do" teeing, it just sprays data
02:13 <joneshf-laptop> writing to a file isn't an option
02:13 <geekosaur> so you need to refigure your model somewhere because what you want to do is not streaming but streaming is what HTTP is
02:13 <joneshf-laptop> Right.
02:13 <joneshf-laptop> Im fine with it being streaming.
02:13 hexagoxel joined
02:14 <Koterpillar> why can't you drain the socket first?
02:14 <joneshf-laptop> I don't have to have it be chunked
02:14 <joneshf-laptop> like with `strictRequestBody`?
02:14 <EvanR> seems like a mistake
02:14 <monochrom> strict I/O is a DDoS vulnerability.
02:15 <joneshf-laptop> sure.
02:15 hybrid joined
02:16 <joneshf-laptop> At the end of the day, I just want a function `MonadIO f => Request -> f (Request, Request)`.
02:16 <joneshf-laptop> But I think since this is way too deep of a hole. I'm going to be satisfied with not logging the request.
02:17 <joneshf-laptop> for now
02:17 sanett joined
02:17 louispan joined
02:17 <EvanR> Handle -> IO (Handle, Handle) is possible, somehow
02:18 {emptyset} joined
02:18 <monochrom> Actually, why is it not Request -> (Request, Request), in fact forall a. a -> (a, a) ?
02:18 <EvanR> it can spawn a worker and two fifos dedicated to reading and dumping the first socket
02:19 <EvanR> which are opened as two new handles
02:19 <EvanR> kind of over the top for what youre trying to do
02:19 <geekosaur> EvanR, only if a different process (or maybe thread) is reading the original and writing every chunk to the other handles
02:19 <EvanR> right
02:19 <geekosaur> which can have its own problems, especially if the processors are supposed to be synchronized somehow
02:19 <EvanR> dont mess with the original handle after that point, "or else"
02:20 <EvanR> er, not a file system fifo, but two anonymous pipes
02:21 manda joined
02:21 armyriad joined
02:22 infinity0_ joined
02:22 infinity0_ joined
02:22 takle joined
02:23 <geekosaur> oh, also your duplicator will block if nothing is reading one of the Handles
02:24 <EvanR> that would be some unfortunately interaction
02:24 <EvanR> unfortunate
02:25 <Koterpillar> can you log as the request body is consumed?
02:25 <Koterpillar> if it's crashed on first 3 bytes, fine, those should be enough to reproduce the error :)
02:26 infinity0_ joined
02:26 filterfish joined
02:26 infinity0_ joined
02:27 <joneshf-laptop> No logging should happen until the response is sent.
02:27 <joneshf-laptop> So if the request becomes bunk, aren't there bigger problems?
02:28 _significance joined
02:29 infinity0 joined
02:29 plutoniix joined
02:30 plutoniix joined
02:30 <geekosaur> you have to decide that, including what to do if you're getting a slowloris attack that sends 3 bytes per minute forever
02:31 <geekosaur> again this is a stream, not a completed request
02:31 <geekosaur> you want something that will make ti look like a complete request. you can only do this by reading the entire request (and possibly aborting if you decide it's too long) yourself.
02:31 infinity0 joined
02:32 <EvanR> have to say i had the idea that "middleware" had some nice composability properties, this doesnt sound like it does
02:32 <joneshf-laptop> right?
02:33 <EvanR> it sounds like any "ware" inserted here will mess everything up
02:33 <geekosaur> personally I question the whole idea, logging a possibly infinite request doesn't sound very viable
02:33 <EvanR> unless you redesign the whole thing
02:33 louispan joined
02:33 brynedwards joined
02:33 <geekosaur> it really does sound like you don't fundamentally get "stream", and are looking for something that will turn it into not-stream for you and magically deal with sytream behaviors like huge, indefinite, or infinite data
02:34 splanch joined
02:34 <geekosaur> ("indefinite" being that slowloris thing where not much data but the sender is malicious and keeping the request open forever)
02:34 infinity0 joined
02:34 sanett joined
02:34 <joneshf-laptop> I don't know how to explain that I do get "stream".
02:35 xall joined
02:35 <geekosaur> you could start by asking for a behavior that is not fundamentally contradictory to streams
02:35 <joneshf-laptop> like teeing?
02:35 <geekosaur> ,,,
02:35 <geekosaur> duplicaitng a stream is duplicating infinity
02:36 <EvanR> nothing really illogical about that
02:36 <EvanR> storing the whole thing on a disk is
02:36 <joneshf-laptop> ^
02:36 <geekosaur> duplicaitng a stream *is not a fundamental stream operation* unless you are separately processing each stream. You cannot do it to hold a "copy", because that means somehting is now committed to infinitely buffering data
02:36 <geekosaur> forever
02:37 <geekosaur> this is the point where your understanding of stream falls apart
02:37 <Koterpillar> geekosaur: for a push-based stream, tee is a possible operation
02:37 <joneshf-laptop> geekosaur, Can you explain it then?
02:37 infinity0 joined
02:37 <geekosaur> I just did
02:37 <geekosaur> if you didn;t get it then I'm not sure what else to say except "good luck"
02:37 <joneshf-laptop> K
02:39 <geekosaur> I fear that you will come up with an Obviously Correct solution.. and then discover first hand what kind of denial of service attacks are opened by such
02:40 infinity0 joined
02:41 bntr joined
02:41 <joneshf-laptop> Nope, I'm just not going to deal with logging the body.
02:41 <joneshf-laptop> This is way too far off in the weeds for me to care about anymore.
02:41 <joneshf-laptop> Specifically for all the stuff you brought up.
02:43 splanch joined
02:44 mzf joined
02:44 splanch_ joined
02:47 splanch joined
02:51 tput- joined
02:52 plutoniix joined
02:53 _significance joined
02:53 teggi joined
02:54 plutoniix joined
02:55 meandi_2 joined
02:57 bhiliyam joined
02:58 pera joined
03:02 bntr joined
03:02 jbiesnecker joined
03:03 Luna521 joined
03:04 thunderrd_ joined
03:05 louispan joined
03:07 DoubleLeft joined
03:11 Luna521 joined
03:13 cschneid_ joined
03:13 iqubic joined
03:14 <iqubic> So, is there a way to pass in a '-' or '.' as a char to a parameter? Like not as a minus sign or fuction composition, but a char?
03:14 <EvanR> > ord '-'
03:15 <lambdabot> 45
03:15 <iqubic> Cool. Just like Java
03:15 <EvanR> :t '-'
03:15 <lambdabot> Char
03:15 <iqubic> Got it.
03:16 <iqubic> I just found a neat library. It has only a few functions, but I still like it.
03:16 <iqubic> @hackage MorseCode
03:16 <lambdabot> http://hackage.haskell.org/package/MorseCode
03:16 takle joined
03:17 <monochrom> Neat.
03:18 <iqubic> Yeah, I like that.
03:18 <iqubic> The functions all do exactly what they say they will.
03:18 <EvanR> should be hooked up to sound
03:18 sellout- joined
03:19 imalison joined
03:19 <iqubic> That's my task.
03:19 Koterpillar left
03:19 Koterpillar joined
03:19 <iqubic> I have to use CSound-Expression to hook it up to sound output.
03:19 <iqubic> I'm also going to want a GUI, but that'll be the last thing I do.
03:20 <iqubic> How hard is Haskell GUI to make?
03:20 <EvanR> theres three-penny-gui
03:21 <iqubic> What I need is something that will provide a simple Front-End that I can hook up to my Morse Code back end.
03:21 <EvanR> https://hackage.haskell.org/package/threepenny-gui
03:21 <EvanR> apparently no - between three and penny
03:21 felixsch_ joined
03:22 <iqubic> So, why does this thing use the web???
03:22 <EvanR> it explains that
03:22 <iqubic> And will I be able to play sound from the web with this and CSound-Expression?
03:22 <EvanR> no
03:22 <EvanR> it will play from your haskell program
03:23 <EvanR> the browser is just for the gui
03:23 falafel joined
03:23 <iqubic> So people will still need to have CSound C library to be installed.
03:23 <iqubic> Are there any other GUIs that I can use?
03:24 <iqubic> Also, I have homework that needs doing.
03:24 <Koterpillar> Gtk, if relevant, is relatively nice with gi-gtk
03:24 <iqubic> Is GTK simple to use?
03:24 <EvanR> not really
03:25 <Koterpillar> not hard, IMO
03:25 steeze joined
03:26 <Koterpillar> https://github.com/koterpillar/tianbar/blob/master/src/System/Tianbar.hs I think this shows a few things you might want to do
03:27 ebsen joined
03:28 <imalison> I often find myself writing stuff like
03:28 <imalison> my3ArgumentFunction <$> getSomeValue <*> (pure True) <*> (pure 10)
03:28 <imalison> where
03:28 <imalison> my3ArgumentFunction :: String -> Bool -> Int -> String
03:28 <imalison> getSomeValue :: IO String
03:28 ebsen joined
03:28 <imalison> But this feels sort of wrong to me because a) applicative is not strictly needed for this (functor is enough) b) It feels like there should be an operator that does what <*> and pure are doing together. I realize that I could do something like
03:28 <imalison> (\input -> my3ArgumentFunction input True 10) <$> getSomeValue
03:28 <imalison> but I would much prefer something like
03:28 <imalison> infixl 4 <$$>
03:28 <imalison> (<$$>) :: Functor f => f (a -> b) -> a -> f b
03:28 <imalison> functor <$$> value = ($ value) <$> functor
03:28 <imalison> my3ArgumentFunction <$> getSomeValue <$$> True <$$> 10
03:28 <imalison> As you can see, it is easy enough to write the operator that I want, but I'm wondering if it exists somewhere/has an accepted name, or is perhaps generalized by some concept that I don't know about.
03:28 <EvanR> what
03:29 <EvanR> liftA3 my3ArgFunc getSomeValue (pure True) (pure 10)
03:29 <Koterpillar> imalison: maybe you need to flip your function arguments instead
03:29 <Koterpillar> imalison: so that the ones you want constant come first
03:29 <imalison> yeah that occured to me as well, but sometimes you just cant do that
03:29 <imalison> (its a library function or something)
03:30 _significance_ joined
03:30 takle joined
03:30 Luna521 joined
03:31 <EvanR> :t liftA3
03:31 <lambdabot> Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
03:31 <Axman6> I sometimes wish we had the syntax a few languages have where you could write fmap (my3ArgFunc _ True 10) getSomeValye
03:31 <Axman6> I think Swift has that?
03:32 chenshen joined
03:32 <imalison> EvanR: that's not really what I want though, I mean fmap does just as well here, and is actually a better thing to use because it doesn't require applicative
03:34 <glguy> Axman6: I know it's not actually a replacement for what you're talking about, but...
03:34 <glguy> (\f -> f ?? True ?? 10) :: (a -> Bool -> Int -> b) -> a -> b
03:35 moet joined
03:36 <moet> what's `mkWeakMVar` mean in haskell? does that mean the mvar's reference won't prevent the referent from being GC'd?
03:37 <glguy> http://hackage.haskell.org/package/base-
03:37 Jimmy_ joined
03:37 <glguy> Make a Weak pointer to an MVar, using the second argument as a finalizer to run when MVar is garbage-collected
03:37 <moet> yeah, i clicked through to `Weak` and found the explanation http://hackage.haskell.org/package/base-
03:37 <moet> i always ask questions about things i was reading last night instead of re-reviewing docs first
03:38 otto_s joined
03:39 <glguy> The reason you have a special operation for making Weak wrappers of MVars is so that it's the underlying mvar that the weak reference refers to
03:39 <glguy> and not the "box" around that weak reference (which is much more likely to not exist due to optimizations, or not be consistently the same box due to optimizations
03:39 <moet> ah..
03:40 <glguy> data MVar a = GHC.MVar.MVar (GHC.Prim.MVar# GHC.Prim.RealWorld a)
03:40 <glguy> So mkWeakMVar grabs onto that inner MVar#
03:42 nomicflux joined
03:43 <imalison> glguy: oh wow, ?? is exactly what I wanted
03:44 <imalison> seems to be exactly the same as the function that I described above
03:44 <imalison> 20:28 <imalison> (<$$>) :: Functor f => f (a -> b) -> a -> f b
03:44 <imalison> 20:28 <imalison> functor <$$> value = ($ value) <$> functor
03:44 xall joined
03:45 jedws joined
03:46 sellout-1 joined
03:48 sellout- joined
03:50 isenmann joined
03:50 raycoll joined
03:53 <iqubic> So what's is the best GUI to use in Haskell?
03:53 <iqubic> > :t ??
03:53 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
03:54 <iqubic> :t ??
03:54 <lambdabot> error: parse error on input ‘??’
03:54 gcross_ joined
03:54 <iqubic> :t <$>
03:54 <lambdabot> error: parse error on input ‘<$>’
03:54 <pacak> :t (<$>)
03:54 <lambdabot> Functor f => (a -> b) -> f a -> f b
03:54 <pacak> :t (??)
03:54 <lambdabot> Functor f => f (a -> b) -> a -> f b
03:54 sellout- joined
03:54 Xanather joined
03:55 <Koterpillar> iqubic: OS requirements?
03:55 <iqubic> Wait a minut, (??) looks like (>>=) with the parameters in the other order.
03:55 zcourts joined
03:55 <iqubic> Koterpillar: Preferable Linux and Windows.
03:55 jedws joined
03:55 <glguy> iqubic: Look closer
03:55 <pacak> :t (>>=)
03:55 <lambdabot> Monad m => m a -> (a -> m b) -> m b
03:55 <pacak> Not quite.
03:55 <imalison> iqubic: not really
03:56 <Koterpillar> iqubic: how complex an UI?
03:56 <imalison> because the function is inside the context
03:56 <iqubic> Though I am using CSound as a C library, so I might not be able to run my application on Windows.
03:57 <iqubic> Koterpillar: Not too complex. Maybe just a single text box, one set of radio buttons, a regular button, and a place to output text.
03:57 <iqubic> I might use GTK bindings, if I had a guide for that.
03:57 <imalison> glguy: so ?? is a lens thing I see. I'm assuming that since its defined there its not defined anywhere else
03:58 <pacak> @src (??)
03:58 <lambdabot> Source not found. You speak an infinite deal of nothing.
03:58 <pacak> lambdabot: :-P
03:58 <iqubic> @src (<$>)
03:58 <lambdabot> f <$> a = fmap f a
03:58 <Koterpillar> iqubic: https://github.com/haskell-gi/haskell-gi here's an example
03:58 <iqubic> @src fmap
03:58 <lambdabot> Source not found. I've seen penguins that can type better than that.
03:59 <EvanR> iqubic: it certainly works on windows
03:59 <iqubic> CSound, GTK, or both?
03:59 <pacak> iqubic: fmap is defined by Functor so different functors have different implementations.
03:59 <EvanR> GTK works on windows
03:59 <EvanR> i was talking about csound
03:59 <Koterpillar> I don't know if gi-gtk does, though
03:59 bhiliyam joined
04:00 fakenerd joined
04:00 <iqubic> Why might gi-gtk fail on Windows?
04:01 <Koterpillar> because you need GI, not just Gtk
04:01 <Koterpillar> IDK if that's an issue, never tried Windows
04:01 <iqubic> So maybe gtk2hs would be better.
04:01 <imalison> As someone who has dealt with it quite a bit I can tell you that gtk2hs kinda sucks
04:01 <iqubic> According to the Haskell wiki, it runs on all OSes.
04:02 <iqubic> imalison: why do you say that?
04:02 sleffy joined
04:02 splanch joined
04:02 <Koterpillar> it's incomplete
04:03 <iqubic> Ah.
04:03 <Koterpillar> iqubic: try gi-gtk, if it works, fine, if not, ask again :)
04:03 <Koterpillar> iqubic: aha! https://github.com/haskell-gi/haskell-gi/wiki/Using-haskell-gi-in-Windows
04:04 jgt2 joined
04:07 <vaibhavsagar> I'm trying to follow this presentation http://halvm-talk.bitballoon.com/#/halvm but I'm getting a linker error when trying to compile the executable with halvm-ghc
04:07 <vaibhavsagar> at this step specifically: http://halvm-talk.bitballoon.com/#/building
04:07 <vaibhavsagar> has anyone encountered this before?
04:09 mizu_no_oto joined
04:10 <iqubic> Is GI-GTK more complete than GTK2HS?
04:11 <iqubic> Also, looks like GI-GTK is cross-platform.
04:11 <Koterpillar> it is as complete as Gtk, by definition
04:11 javjarfer joined
04:12 <iqubic> What does that mean?
04:12 <iqubic> https://hackage.haskell.org/package/gi-gtk
04:12 <iqubic> That provides no link to the modules in that library.
04:13 <iqubic> Why is that
04:13 e_svedang joined
04:13 <iqubic> Is that the wrong library page?
04:13 ubsan_ joined
04:15 <Koterpillar> that means it introspects your version of Gtk at compile time
04:15 <Koterpillar> and generates all the functions it finds
04:15 <iqubic> Oh, that's wonderful?
04:15 <iqubic> Do I need to get the gi library as well?
04:15 mda1 joined
04:15 <Koterpillar> there is a link in README at the bottom
04:16 <iqubic> Yeah, but not in the modules section. Why is this formatting weird?
04:16 <geekosaur> you were just told why
04:16 <iqubic> geekosaur: What does that mean?
04:16 <Koterpillar> Hackage probably doesn't have Gtk
04:16 <geekosaur> normally documentation would be generated by an automatic test build, but the builder does not have gtk installed
04:16 <Koterpillar> and without Gtk, it can't introspect or build anything
04:16 <iqubic> Ah. I see
04:17 <geekosaur> so the docs were uplkoaded manulally and a link put in the README
04:17 <iqubic> Oh. I see now. Thanks.
04:17 <iqubic> So, do I need the gi library to use gi-gtk?
04:17 <Koterpillar> you need haskell-gi, yes
04:18 <iqubic> Is that also on Hackage?
04:18 <iqubic> is gi-gtk hard to use?
04:18 <iqubic> Or is it simple
04:18 <geekosaur> stuff like gi is kinda an extreme case that the builder and doc builder can;t deal with properly, so the result is a bit hacky
04:18 <geekosaur> moreover the uploaded docs may not match what you get when you install it since you are not guaranteed to have the same Gtk installed
04:18 <iqubic> how difficult is gi-gtk to use?
04:19 <iqubic> It seems rather difficult from what I hear.
04:19 <geekosaur> (but, Gtk devs don't believe in stability so there is nothing to be done about that)
04:19 tristanp joined
04:19 <Koterpillar> iqubic: see the README here: https://github.com/haskell-gi/haskell-gi
04:20 <Koterpillar> iqubic: there is a complete example displaying a button and something
04:20 <geekosaur> they're the gnome devs now, not the gimp devs who made gtk2 and had a notion of stability
04:20 <glguy> gi-gtk is about as easy to use as gtk is, it binds the API directly
04:20 <glguy> understanding gtk will make understanding gi-gtk easy
04:20 {emptyset} joined
04:20 <iqubic> I'll look into gtk then.
04:20 <geekosaur> as for what's wrong with gnome 3, ... I gave up trying to figure it out. they just don't care about anyone but themselves, and made that pretty clear when they announced they were abandoning all pretense at API stability
04:20 <glguy> and I mean gtk the underlying library
04:20 <glguy> not the Haskell one
04:21 <iqubic> Koterpillar: that readme doesn't tell me how to install haskell-gi.
04:21 <Koterpillar> iqubic: from cabal/stack
04:22 <iqubic> I am stupid.
04:22 <iqubic> So how do I link up the GTK front-end to my Haskell back-end?
04:23 <iqubic> With a special library, or what?
04:23 wroathe joined
04:23 <Koterpillar> you link to gtk
04:24 <iqubic> Just like that? I don't need FRP to connect my logic to my GUI?
04:24 <Koterpillar> no
04:24 <Koterpillar> so, about the same way you link a console front-end (fprintf) to your Haskell back-end: with a "special library" called putStrLn
04:25 <iqubic> So how will I know if certain GUI events have happened, and how will I poll the GUI state?
04:25 <Koterpillar> iqubic: search for "on button" on that page
04:25 <iqubic> Wait a minute, you can bind actions to buttons.
04:26 <glguy> I'm got a small gi-gtk app you can look at that does use any extra library, it looks like this http://imgur.com/a/ISOxN
04:26 <glguy> https://github.com/glguy/CookieCalculator/blob/master/gui/Main.hs
04:26 <iqubic> the function set button can really be anything there, right?
04:26 halogenandtoast joined
04:26 <halogenandtoast> Is there a more clear way to write this? getMove = fromMaybe <$> getMove <*> (parseMove <$> getInput)
04:26 <Koterpillar> iqubic: yes
04:26 _significance_ joined
04:27 <halogenandtoast> where getMove :: IO Move
04:27 <iqubic> Right, I just have to get the type right.
04:27 <Koterpillar> iqubic: it's all in IO
04:28 <iqubic> @src liftA2
04:28 <lambdabot> liftA2 f a b = f <$> a <*> b
04:29 kamog joined
04:29 <iqubic> halogenandtoast: why not try "liftA2 fromMaybe getMove (parseMove <$> getInput)"
04:29 <iqubic> Not sure that's any cleaner, but it should still work.
04:30 <halogenandtoast> hrm usually if I end up using liftA2 I assume I've done something wrong :p
04:30 bkboggy joined
04:30 <halogenandtoast> because it's very hard to read.
04:30 <glguy> You don't have to feel like that
04:31 <iqubic> What does a .ui file do? Is that part of gtk's inner workings?
04:32 <iqubic> What does fromMaybe do?
04:32 <glguy> iqubic: You can build a window layout using the Glade tool and then save that
04:32 <iqubic> @src fromMaybe
04:32 <lambdabot> fromMaybe d Nothing = d
04:32 <lambdabot> fromMaybe _ (Just v) = v
04:32 <iqubic> I see converts Maybe a into a, or returns a default value.
04:33 <iqubic> > :t getInput
04:33 <lambdabot> <hint>:1:1: error: parse error on input ‘:’
04:33 <halogenandtoast> getInput is my own func
04:33 <glguy> iqubic: The glade tool editing a .ui file http://imgur.com/a/na7WL
04:33 <halogenandtoast> getInput :: IO String
04:33 <halogenandtoast> parseMove :: String -> Maybe Move
04:34 <iqubic> Ah. I see.
04:34 <iqubic> hence why you need <$> there.
04:35 <iqubic> Why am I getting this error?
04:36 <lpaste> iqubic pasted “stack repl error” at http://lpaste.net/8855615865861701632
04:36 hamishmack joined
04:36 rcschm joined
04:36 <iqubic> Only happened after I added "haskell-gi and gi-gtk" to my build depends list.
04:38 <iqubic> Anyone know what's going on?
04:38 vlatkoB joined
04:40 splanch joined
04:40 ichor joined
04:41 <iqubic> Anyone at all know what's up?
04:41 <halogenandtoast> iqubic: I'm not sure, going on a limb here, but maybe try `stack clean`
04:42 <Koterpillar> iqubic: do you have Gtk and GI libraries?
04:42 <iqubic> I'm not sure.
04:42 <imalison> Koterpillar: I saw that you forked taffybar. Why did you decide to do that?
04:42 <Koterpillar> imalison: my way is prettier
04:43 <iqubic> Koterpillar: what versions of gtk and GI do I need?
04:43 <iqubic> My package manager has a thing called dev-haskell/gtk
04:43 <Koterpillar> iqubic: I mean the system libraries... what OS are you on?
04:43 <iqubic> Gentoo Linux
04:43 <Koterpillar> ooooooooo
04:43 <iqubic> What's up??
04:44 <pacak> Gento is fun :)
04:44 <Koterpillar> iqubic: https://github.com/koterpillar/tianbar/blob/master/Dockerfile.base#L19-L20
04:44 <iqubic> Everyone has told me that all day.
04:44 <Koterpillar> iqubic: try searching for something like those
04:44 <iqubic> I have.
04:44 <iqubic> I found that I could install gtk+
04:44 <iqubic> That's a start.
04:44 <iqubic> Since this is gentoo, that'll take a bit of time.
04:45 <halogenandtoast> So this is a little interesting to me and maybe someone can explain, I have getInput = putStr "> " >> hFlush stdout >> getLine, and if I try to do liftA2 fromMaybe getMove (parseMove <$> getInput)
04:45 <halogenandtoast> then I don't see the "> "
04:45 <halogenandtoast> but if I do mMove <- parseMove <$> getInput
04:45 <halogenandtoast> liftA2 fromMaybe getMove $ pure mMove
04:45 <halogenandtoast> then I do
04:46 <iqubic> halogenandtoast: Where are you printing the "> " from?
04:46 Guest81707 joined
04:46 <halogenandtoast> from getInput (see the definition above)
04:46 <jle`> halogenandtoast: it might be buffering
04:46 <halogenandtoast> jle`: isn't that what hFlush is for?
04:46 Wizek_ joined
04:46 <jle`> oh, mised that
04:47 <iqubic> Wait, I am super confused now.
04:47 <iqubic> Why isn't that being printed properly?
04:47 <halogenandtoast> I'll post the full source
04:48 <iqubic> I don't think that's needed, but sure, go ahead.
04:48 Ferdirand joined
04:48 <halogenandtoast> https://gist.github.com/halogenandtoast/f6cb02d94c44c54404299243d3cc4e6c
04:48 boxscape joined
04:49 rcschm joined
04:49 sdothum joined
04:49 mizu_no_oto joined
04:49 <iqubic> Where are you printing in that code?
04:49 <iqubic> I don't see that anywhere?
04:49 <halogenandtoast> #23
04:50 <iqubic> I see that now.
04:50 <halogenandtoast> and subsequently #41 and #43
04:50 <halogenandtoast> s/subsequently/additionally/
04:50 <jle`> halogenandtoast: does it even do anything if you wrote the liftA2 fromMaybe getMove (...) ?
04:50 <halogenandtoast> jle`: define do anything?
04:51 <halogenandtoast> I can type stuff, hit enter, nothing happens
04:51 <iqubic> I see
04:51 <jle`> yeah, it looks like you have an infinite loop
04:51 <iqubic> Where do you call getInput from?
04:51 al-damiri joined
04:51 <jle`> you're defining getMove as lifA2 _ getMove blah
04:51 <iqubic> Wait, I see that.
04:52 <halogenandtoast> and getMove has to be evaluated because IO
04:52 <jle`> `liftA2 f x y` will execute x, then execute y, and then return the result of x and y applied to f
04:52 osa1 joined
04:52 <jle`> so the first thing that getMove does is call getMove
04:52 <jle`> which then does getMove
04:52 <jle`> which then does getMove, etc.
04:52 <iqubic> How can that be fixed?
04:52 <jle`> but it never gets to a point where it would get to parseMove
04:52 takle joined
04:52 <jle`> it's like:
04:53 <jle`> > let foo = foo ++ [1,2,3]
04:53 <lambdabot> <no location info>: error:
04:53 <lambdabot> not an expression: ‘let foo = foo ++ [1,2,3]’
04:53 <jle`> > let foo = foo ++ [1,2,3] in foo
04:53 <lambdabot> mueval-core: Time limit exceeded
04:53 <halogenandtoast> Right
04:53 <iqubic> Is there any way he can fix that? or not.
04:53 <halogenandtoast> I have a "similar" problem if I do
04:53 <halogenandtoast> mMove <- parseMove <$> getInput
04:53 <halogenandtoast> fromMaybe <$> getMove <*> pure mMove
04:53 <jle`> well, what do you want to do?
04:54 <halogenandtoast> if mMove is Nothing recurse
04:54 <jle`> do you want to perform parseMove until you get a valid move?
04:54 darkbot-rc4 joined
04:54 <jle`> then you should do that
04:54 <halogenandtoast> otherwise return the wrapped Just
04:54 <jle`> case mMove of
04:54 <jle`> Just x -> x
04:54 <jle`> Nothing -> getMove
04:54 <iqubic> That will work.
04:54 <jle`> once you explain the solution in english, it's clear to see :o
04:54 <halogenandtoast> jle`: well kind of
04:55 <halogenandtoast> I need `return x`
04:55 <halogenandtoast> but close enough
04:55 <jle`> mhm
04:55 <iqubic> Why do you need "return x"
04:55 <iqubic> if your calling makeMove until you get a valid move, then you will never be returning nothing.
04:55 <halogenandtoast> iqubic: because it's in IO
04:56 <jle`> well, x :: Move
04:56 <jle`> but the result should be IO Move
04:56 <iqubic> Ah.
04:56 <jle`> so return :: a -> IO a
04:56 <halogenandtoast> I can also use ` maybe getMove return mMove
04:56 <halogenandtoast> but people seem polarized on that one.
04:56 <halogenandtoast> I happen to like it
04:56 <iqubic> What does that do?
04:56 <jle`> it sounds like that kind of cleverness might have been what got you into this mess in the first place :)
04:57 <iqubic> How will maybe getMove return mMove work?
04:57 raycoll joined
04:57 <Myrl-saki> How does ghc compile main?
04:57 <halogenandtoast> :t maybe
04:57 <lambdabot> b -> (a -> b) -> Maybe a -> b
04:57 <jle`> iqubic: do you know what 'maybe' does?
04:57 <iqubic> I do now.
04:57 <jle`> so, you should know how that would work :)
04:57 <jle`> @src maybe
04:57 <lambdabot> maybe n _ Nothing = n
04:57 <lambdabot> maybe _ f (Just x) = f x
04:58 <jle`> all you need to do is unroll the definition
04:58 <iqubic> what library do I need to get haskell-gi to work?
04:58 <iqubic> Is there a reuqired library?
04:58 <jle`> iqubic: what is haskell-gi
04:58 <iqubic> @hackage haskell-gi
04:58 <lambdabot> http://hackage.haskell.org/package/haskell-gi
04:59 <iqubic> I'm using it in tandem with gi-gtk
04:59 <jle`> are you asking what haskell libraries you need?
04:59 <jle`> because that information is in the description of the package
04:59 <jle`> under 'dependencies'
04:59 SimpleL joined
04:59 <iqubic> No, I think I need a certain system library to make that work.
04:59 <Koterpillar> iqubic: https://github.com/haskell-gi/haskell-gi/blob/master/haskell-gi.cabal#L27
04:59 <EvanR> so gmp integers require some messy memory managment, they arent immutable values, they are like IORefs of their own that can be modified, as if you could change the value of the number 2
04:59 <EvanR> how does ghc keep all that straight?
04:59 <jle`> Myrl-saki: what sort of answer are you looking for?
04:59 <halogenandtoast> Thanks for the help and explaination jle` that made perfect sense.
04:59 <jle`> halogenandtoast: noproblem!
04:59 <Koterpillar> iqubic: not being familiar with Gentoo, that's all I can say. Do you have some tool that can search for pkg-config?
05:00 <jle`> the important thing is that liftA2 doesn't change effects
05:00 <jle`> so it doesn't "short-circuit"
05:00 <Koterpillar> iqubic: maybe take that line to #gentoo to figure out which package (?) you have to install
05:00 <jle`> liftA2 f leaves effects unchanged
05:00 <halogenandtoast> jle`: yeah I didn't realize that.
05:00 boxscape joined
05:00 <halogenandtoast> I don't really use liftA2
05:00 <jle`> halogenandtoast: you can also try something inspired from parser combinators, though
05:00 <halogenandtoast> I thought I would try it out to see what happened
05:00 <Myrl-saki> jle`: Hmmm. How does main work under the hood, to be more exact?
05:00 <jle`> parser combinator style
05:00 <boxscape> is there a good way to write `view' only once here? Result <$> (view lastIns) <*> (view cpuRegs) <*> (view output) <*> (view cpuSteps)
05:00 bhiliyam joined
05:00 <halogenandtoast> and the result was interesting to me
05:00 <halogenandtoast> I'm fine with my cleverness: getMove = parseMove <$> getInput >>= maybe getMove return
05:00 <jle`> halogenandtoast: getMove = MaybeT parseMove <|> getMove
05:01 <jle`> or well, getMove = parseMove <|> getMove
05:01 <halogenandtoast> oh that looks spiffy
05:01 <jle`> where getMove :: MaybeT IO Move; parseMove :: MaybeT IO Move
05:01 <iqubic> :t (<|>)
05:01 <lambdabot> Alternative f => f a -> f a -> f a
05:01 <halogenandtoast> lol Alternative
05:01 <iqubic> What is an alternative?
05:01 <jle`> in this case it describes "choice"
05:02 <iqubic> I see.
05:02 <boxscape> > Nothing <|> Just x
05:02 <lambdabot> Just x
05:02 <jle`> "this or that"; return the first part if it's succesful, or if it's a 'failure', do the next
05:02 <boxscape> > [1..5] <|> [6..10]
05:02 <lambdabot> [1,2,3,4,5,6,7,8,9,10]
05:02 <jle`> `MaybeT IO a` wraps an IO (Maybe a), and considers a success to be a Just result, and a Nothing to be a failure
05:03 <jle`> so `x <|> y` for MaybeT IO's instance will execute x, and, if it's Just, stop there; and if it's Nothing, do y
05:03 <halogenandtoast> jle`: does parseMove need to be in IO?
05:03 <halogenandtoast> my current implementation doesn't do anything in IO
05:03 <jle`> iqubic: like for any typeclass, you just need to understand that specific instance's behavior to understand the code
05:03 <jle`> iqubic: you don't need to understand the typeclass in general
05:04 <iqubic> Yeah, I get that.
05:04 <iqubic> The state monad is quite different from the writer monad.
05:04 <jle`> halogenandtoast: oh sorry, i meant (parseMove <$> getInput) <|> getMove
05:05 <iqubic> shouldn't getInput come first in the parenthesis?
05:05 <jle`> hm
05:05 Guest81707 joined
05:05 fakenerd joined
05:05 <jle`> (MaybeT (parseMove <$> getInput)) <|> getMove
05:05 dec0n joined
05:06 <halogenandtoast> It's also weird that getMove would need to be a MaybeT as well.
05:06 <iqubic> Why do you need it to wrapped in a MaybeT?
05:06 bntr joined
05:06 <jle`> it's what gives it the right Alternative instance
05:06 <jle`> sort of like:
05:06 <jle`> > Sum 1 <> Sum 10
05:06 <lambdabot> Sum {getSum = 11}
05:06 <jle`> MaybeT is a newtype wrapper that gives the thing the appropriate Alternative instance
05:07 <jle`> without it, you're using the Alternative instance for IO
05:07 <jle`> which is...very different
05:07 <jle`> > Any True <> Any False
05:07 <lambdabot> Any {getAny = True}
05:07 <jle`> > All True <> All False
05:07 <lambdabot> All {getAll = False}
05:07 <iqubic> What does that do? The Alternative IO instance?
05:07 <iqubic> Also, what is <>?
05:08 <jle`> the Alternative IO instance only considers an IO exception to be 'failure'
05:08 yellowj joined
05:08 <jle`> and everything else to be success
05:08 <iqubic> Oh wow.
05:08 <jle`> MaybeT IO's instance consuders Nothing's to be failures
05:08 <iqubic> That's quite different
05:08 <jle`> <> is from the Monoid typeclass
05:08 <iqubic> I assume EitherT IO exists as well?
05:08 <jle`> EitherT e IO, yes
05:09 <iqubic> right, because you can only give a typeclass one parameter.
05:09 <iqubic> what does <> do?
05:09 <boxscape> :t (<>)
05:09 <lambdabot> Monoid m => m -> m -> m
05:09 <jle`> it's a part of the Monoid typeclass, so every instance gets to define it however it wants
05:09 <halogenandtoast> I'm glad I was able to answer my own question before I asked it.
05:09 <halogenandtoast> I was about to ask, "How do I unwrap a MaybeT"
05:09 <jle`> which is why Any True <> Any False gives different results than All True <> All False
05:10 a3Dman joined
05:10 <halogenandtoast> But I figured it out by guessing
05:10 <jle`> halogenandtoast: congrats :)
05:10 <iqubic> halogenandtoast: How do you unwrap that?
05:10 <jle`> iqubic: monoid is one of the more ubiquitous haskell typeclasses so it might be nice to look at different examples
05:10 <halogenandtoast> iqubic: runMaybeT
05:10 {emptyset} joined
05:10 <halogenandtoast> :t runMaybeT
05:10 <iqubic> alrighty then.
05:10 <lambdabot> error: Variable not in scope: runMaybeT
05:10 <jle`> most haskell courses talk about monoid
05:10 <jle`> http://ozark.hendrix.edu/~yorgey/pub/monoid-pearl.pdf
05:11 <iqubic> Yeah, like LYAH
05:11 <iqubic> Wait, <> is infix mappend. Right?
05:11 <jle`> the reason i brought it up here was because by using Any or All, you can take advantage of the monoid instance of different types
05:11 <iqubic> I know what that does then.
05:12 <jle`> so you can effectively "choose" the monoid instance you want to use
05:12 <jle`> yes, (<>) = mappend
05:12 <halogenandtoast> jle`: the use of `All` and `Any` is really awesome.
05:12 <iqubic> Is there an infix mconat?
05:12 <iqubic> :t any
05:12 <lambdabot> Foldable t => (a -> Bool) -> t a -> Bool
05:12 <jle`> iqubic: mconcat only takes one argument, so it wouldn't really make sense to have an infix version
05:12 <iqubic> I get that now.
05:13 <iqubic> :t mconcat
05:13 <lambdabot> Monoid a => [a] -> a
05:14 <iqubic> So is there a instance of monoid for num?
05:14 <jle`> Num isn't a type, so, it wouldn't really make sense to have one
05:14 <jle`> at least not a kind-* type
05:14 <halogenandtoast> Is there a subjectively better way to write: https://gist.github.com/halogenandtoast/f6cb02d94c44c54404299243d3cc4e6c#file-minesweeper-hs-L30
05:14 <iqubic> Right.
05:14 <iqubic> What is the kind of Num?
05:14 <jle`> * -> Constraint
05:14 <jle`> it takes a type and returns a constraint
05:14 mda1 joined
05:15 <jle`> :k Num Int
05:15 <lambdabot> Constraint
05:15 <iqubic> :k Num a
05:15 <jle`> there isn't a Monoid instance for numeric types, though, typically. like Int or Double or Float
05:15 <lambdabot> error: Not in scope: type variable ‘a’
05:15 <jle`> that's because it isn't clear which one should be used by default
05:15 <jle`> there is more than one way to have a monoid on Ints
05:15 <iqubic> You can run readMaybe over a list of things?
05:16 <jle`> instead, by default, haskell gives us newtype wrappers to let us chose which monoid instance we want
05:16 <jle`> > Sum 10 <> Sum 13
05:16 <lambdabot> Sum {getSum = 23}
05:16 <jle`> > Product 10 <> Product 13
05:16 <lambdabot> Product {getProduct = 130}
05:16 _sg joined
05:16 <iqubic> I see.
05:16 <jle`> iqubic: 'run' how
05:16 <jle`> > traverse readMaybe ["1","2","3"] :: Maybe [Int]
05:16 <lambdabot> error:
05:16 <lambdabot> Variable not in scope: readMaybe :: [Char] -> Maybe Int
05:16 <jle`> @let import Text.Read
05:16 <lambdabot> Defined.
05:16 <jle`> > traverse readMaybe ["1","2","3"] :: Maybe [Int]
05:17 <lambdabot> Just [1,2,3]
05:17 <iqubic> jle`: Yeah, you can do something like that.
05:17 <iqubic> What does that do?
05:17 <iqubic> Why are you not using map there?
05:17 <jle`> traverse for (a -> Maybe b) applies the (a -> Maybe b) to every item in the list
05:17 <halogenandtoast> Could do `readMaybe <$> words "1 2"`
05:17 <jle`> and collects the results
05:17 <jle`> iqubic: traverse is map + sequence
05:17 <iqubic> Ah, I see.
05:17 <jle`> if any of the results are Nothin,g the whole thing is NOthing
05:18 <jle`> > traverse readMaybe ["1","hello","3"] :: Maybe [Int]
05:18 <lambdabot> Nothing
05:18 <jle`> alternative:
05:18 peddie joined
05:18 <jle`> > mapMaybe readMaybe ["1","hello","3"] :: [Int]
05:18 <lambdabot> [1,3]
05:18 <iqubic> Wait, doesn't map already return a list?
05:18 <jle`> mapMaybe applies an (a -> Maybe b) to every item, and collects the Just's
05:18 <jle`> you can use map too, yes
05:19 <jle`> > map readMaybe ["1","hello","3"] :: [Maybe Int]
05:19 <lambdabot> [Just 1,Nothing,Just 3]
05:19 <iqubic> What os the difference between traverse and map?
05:19 <jle`> a third possible interpretation of your original question
05:19 <jle`> map :: (a -> Maybe b) -> [a] -> [Maybe b]
05:19 <jle`> traverse :: (a -> Maybe b) -> [a] -> Maybe [b]
05:19 kody joined
05:20 <iqubic> so travese is an all or nothing kind of deal, whereas map gives you a list every single time?
05:20 caumeslasal joined
05:20 <jle`> yes, map just applies the function
05:20 <halogenandtoast> Is there anything good for [a] -> Maybe (a, a)
05:20 <jle`> traverse is a map + apply
05:20 <jle`> er, map + sequence
05:21 <iqubic> Yeah, I get that now.
05:21 <jle`> > sequence [Just 10, Just 3, Nothing]
05:21 <lambdabot> Nothing
05:21 <iqubic> nothing.
05:21 <jle`> > sequence [Just 10, Just 3, Just 2]
05:21 <lambdabot> Just [10,3,2]
05:21 <iqubic> I see.
05:21 <jle`> traverse f = sequence . map f, for lists
05:21 <iqubic> Just like you said earlier.
05:21 fergusnoble joined
05:22 <iqubic> But why add the for list constraint there, if map only works on lists.
05:22 <iqubic> does map have to return something of type (maybe a)?
05:22 <jle`> :t map
05:22 <lambdabot> (a -> b) -> [a] -> [b]
05:22 <iqubic> > map (+5) [1..
05:22 <lambdabot> <hint>:1:14: error:
05:22 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
05:22 <jle`> it doesn't
05:22 <iqubic> > map (+5) [1..]
05:22 <lambdabot> [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,3...
05:22 <jle`> it returns whatever the mapping function returns
05:23 <jle`> if the mapped function returns Int, it returns a list of Ints
05:23 <jle`> if the mapped function returns String, then the whole map returns a list of Strings
05:23 <jle`> if the mapped function returns Maybe Int, then the whol empa returns a list of Maybe Int's
05:23 <iqubic> Why did you write than??? map :: (a -> Maybe b) -> [a] -> [Maybe b]
05:23 ubsan_ joined
05:24 <jle`> i specialized it for this specific situation
05:24 armyriad joined
05:24 <iqubic> Wait, that is the type of map, where b = Maybe b
05:24 <jle`> if i'm using map with an (a -> Maybe b), then that is what it specializes too
05:24 <jle`> *to
05:24 path[l] joined
05:24 <iqubic> :t traverse
05:24 <monochrom> "b = Maybe b" is very sad.
05:24 <lambdabot> (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
05:24 systemfault joined
05:24 <iqubic> why is that monochrom?
05:24 <jle`> indeed it might not have been the best choice of names
05:25 <jle`> i might have done map :: (String -> Maybe Int) -> [String] -> [Maybe Int]
05:25 <jle`> i juse 'Maybe b' for the comparison to traverse
05:27 <jle`> iqubic: you can use any type for 'a' and 'b' in map, and the fucntion will specialize to make it work
05:27 <jle`> map :: (Int -> Bool) -> [Int] -> [Bool], etc.
05:27 <halogenandtoast> map :: ((a -> b) -> (b -> a)) -> [(a -> b)] -> [(b -> a)]
05:27 <jle`> if you give map an (Int -> Bool), it'll take a list of Int's and return a list of Bool's
05:28 _sras_ joined
05:28 <jle`> if iyou gave map an (a -> Maybe b), it'll take a list of a's and return a list of Maybe b's
05:28 <jle`> hence the type signature
05:29 jedws joined
05:30 bl0w3d_0ut joined
05:32 <iqubic> I see. I'm not dumb, you know.
05:33 Guest81707 joined
05:34 <jle`> i'm not assuming you're dumb :o these things aren't necessarily obvious or intuitive, and i also don't want to make any assumptions about your haskell background
05:34 sleffy joined
05:34 <jle`> besides, it's easier to explain all of the details up-front than to assume incorrectly what parts can be left out
05:35 danvet joined
05:36 piyush-kurur joined
05:36 Destol joined
05:36 BartAdv joined
05:39 <iqubic> How does one view the documentation for gi-gtk?
05:39 ali_bush joined
05:39 ali_bush joined
05:40 <iqubic> Since it needs to poll my GTK version, I assume local docs is all I get.
05:40 <Koterpillar> they are stable _enough_ to go by the docs you see on hackage
05:40 <iqubic> Really? I'm not sure I want to try that right now.
05:41 <iqubic> And I assume I should stay away from deprecated stuff
05:41 <Koterpillar> also, once you figure out the mapping, you should be able to just use the Gtk docs
05:41 <iqubic> Is the mapping simple?
05:41 <iqubic> Or is that a pain to understand?
05:42 <glguy> http://hackage.haskell.org/package/gi-gtk-3.0.11/docs/
05:42 <glguy> I find the mapping easy to understand
05:42 <iqubic> What is the mapping?
05:42 <iqubic> Is it a simple rule, you can just tell me?
05:42 <glguy> sorry, it's a secret
05:43 <Koterpillar> iqubic: it's mostly snake_case to camelCase
05:43 <iqubic> really?
05:43 <iqubic> What does that mean?
05:44 <iqubic> What's up with the # and the := in this example?
05:44 <iqubic> https://github.com/haskell-gi/haskell-gi
05:44 <Koterpillar> iqubic: that's OverloadedLabels if I understand correctly; I didn't use them
05:45 <iqubic> Then how do you use gi-gtk?
05:45 <Koterpillar> I'll just use my example again: https://github.com/koterpillar/tianbar/blob/master/src/System/Tianbar.hs
05:45 <Koterpillar> see this function: https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen-get-primary-monitor
05:46 <Koterpillar> it's called gdk_screen_get_primary_monitor
05:46 <iqubic> Also, OverloadedLabels breaks my syntax highlighter.
05:46 <Koterpillar> and it was converted to displayGetPrimaryMonitor
05:47 <iqubic> Koterpillar: how would you write something like "on win #destroy Gtk.mainQuit"
05:48 <Koterpillar> just like that?
05:48 <iqubic> But doesn't that use OverloadedLables?
05:48 <iqubic> And don't you avoid those?
05:48 <Koterpillar> Ah
05:49 <iqubic> What?
05:49 <Koterpillar> I did when I wrote that code, I might give it a try now. But to answer your question...
05:49 <Koterpillar> onWindowDestroy win Gtk.mainQuit
05:49 <iqubic> What do you mean, when I wrote that code???
05:50 f-a joined
05:50 <iqubic> And what does "#showAll win" correspond to?
05:50 <Koterpillar> I mean that was a while ago, and I didn't feel like figuring out OverloadedLabels
05:50 <halogenandtoast> How do I add a constraint for a data constructor? For example: data Game = EmptyGame Int Int RandomGen
05:50 <halogenandtoast> I'm assuming I want RandomGen a => EmptyGame Int Int a
05:50 <iqubic> Just like that I'd assume?
05:50 <jle`> halogenandtoast: you aren't supposed to
05:50 <Koterpillar> iqubic: probably windowShowAll win
05:51 <jle`> halogenandtoast: why not just pick a specific type?
05:51 <jle`> Game = EmptyGame Int Int StdGen
05:51 <jle`> or, use it as a type paraemter? data Game g = EmptyGame Int Int g
05:51 splanch joined
05:51 <iqubic> Koterpillar: do you have a list of these functions, or will I have to search from them myself?
05:51 <halogenandtoast> jle`: okay I'll just use StdGen for now.
05:52 <halogenandtoast> Thanks
05:52 <jle`> np
05:52 <Koterpillar> iqubic: https://developer.gnome.org/gtk3/stable/
05:53 <iqubic> Oh, it really is a one to one corralation of the functions.
05:53 <iqubic> And I assume I can use ghci to get the right types.
05:54 f-a left
05:54 mszczygiel joined
05:54 <iqubic> Or is it all IO, since this is mostly just a heaping pile of side-effects?
05:55 splanch_ joined
05:56 juhp joined
05:56 <Koterpillar> It's all IO
05:57 <glguy> and thus no side effects
05:57 path[l] joined
05:57 <iqubic> But doesn't IO mean side effects by definition.
05:57 dan_f joined
05:57 _significance_ joined
05:58 nick_h joined
05:58 doomlord joined
05:58 SimpleL joined
05:59 <dibblego> No.
05:59 splanch joined
06:00 ThomasLocke joined
06:00 <iqubic> Doesn't IO break referential transparency?
06:01 <jle`> can you show an example of when you think it would?
06:01 <Koterpillar> iqubic: no, because all the effects are happening outside the Haskell evaluation
06:01 <Cale> Execution of IO actions isn't referentially transparent, but evaluation of them is.
06:01 <iqubic> Oh.
06:01 bhiliyam joined
06:01 caumeslasal joined
06:01 <iqubic> I just think that running getLine will always return different results.
06:01 <jle`> let x = putStrLn "hello" in x >> x is the same as putStrLn "hello" >> putStrLn "hello"
06:01 <jle`> let x = getLine in x >> x is the same as getLine >> getLine
06:01 <Cale> iqubic: But merely *evaluating* getLine doesn't do anything too visible.
06:02 JoelMcCracken joined
06:02 <jle`> referential transparency at its finiest
06:02 <iqubic> Right, but getLine let's the user enter input.
06:02 <Cale> > getLine `seq` ()
06:02 <lambdabot> ()
06:02 <jle`> iqubic: let x = getLine in x >> x is the same as getLine >> getLine; getLine is a pure value
06:02 Swizec joined
06:03 <Cale> Of course, the distinction is a little bit subtle, because IO is abstract, so we can't talk about pattern matching IO actions.
06:03 eatman joined
06:03 <jle`> it's a pure value of type IO String
06:03 <iqubic> Oh, so it is.
06:03 <iqubic> And that makes use of the fact that IO is a monad.
06:03 <Cale> Well, it needn't be >> there
06:04 <Cale> For any function f, let x = getLine in f x x will be the same as f getLine getLine
06:04 <jle`> well, IO the type is referntially transparent even if there was no monad instance or it wasn't a monad
06:04 <jle`> te fact tiat it's referntially transparent comes from the fact that we're in haskell
06:04 sw1nn joined
06:04 <jle`> well, hm, maybe that's not the best description
06:04 <jle`> it comes from the fact that the IO type's API is pure
06:05 <iqubic> Right, but grabbing the value from within is a side-effect.
06:05 <jle`> you can't grab values from within IO
06:05 <jle`> there are no values inside an IO action
06:05 <iqubic> Like trying to extract a String from and IO String
06:05 Guest81707 joined
06:05 <Cale> It's weird to say it like that. Carrying out the described actions has an effect.
06:05 <jle`> you cannot extract a String from an IO String, because there is no String inside an IO String
06:05 <jle`> it's not a box containing a String
06:06 <Cale> The difference between an IO String and a String is like the difference between /bin/ls and a list of files in your home directory.
06:06 hurkan joined
06:06 <Cale> You can open up /bin/ls in a hex editor without causing a list of files to be printed to the screen, just as IO actions might be evaluated without causing their effects to occur.
06:06 <iqubic> Right, but running the IO action is the part that has a side-effect
06:06 <Cale> Right.
06:07 <Cale> Or, perhaps it's not even right to call it a side effect anymore.
06:07 <jle`> at that point it isn't really a side-effect
06:07 <jle`> it's just an effect
06:07 <iqubic> But running the same IO action might produce different results at different times.
06:07 jgt2 joined
06:08 Tourist joined
06:08 <jle`> that is true; we just don't run IO actions inside haskell
06:08 <Cale> I wouldn't say that
06:08 <Cale> Execution of IO actions is part of Haskell.
06:08 <iqubic> You ask the underlying C code to run the IO action?
06:08 <Cale> It's just not part of evaluation.
06:08 zeroed joined
06:08 <jle`> we use haskell to define an IO action, and then ghc compiles it to bytecode
06:08 <Cale> You have to understand how IO actions are executed in order to fully understand a Haskell program.
06:08 <jle`> and then we let a computer/CPU evaluate it for us
06:09 <Cale> So it's certainly "part of Haskell"
06:09 <jle`> yes, thanks for clarifying
06:09 ogrady joined
06:09 <Cale> Also... that's not entirely true either. If you want to talk about how GHC does things... it compiles IO actions to native code along with everything else.
06:09 <iqubic> LOL.
06:10 <iqubic> Yeah, that's true.
06:10 <iqubic> But we don't really care about that now, do we?
06:10 sw1nn joined
06:10 <jle`> in haskell, you spend your time defining an IO action, using IO's pure interface
06:10 <jle`> that's why IO is referentially transparent
06:10 <jle`> every time you define an IO action, you define the same IO action
06:10 <iqubic> Yep. And you can run that IO action if you wish.
06:10 <Cale> I think it's important to make the distinction here between what part of it is referentially transparent.
06:10 <jle`> the actual definition of the IO action is a pure/referentially transparent process
06:11 <qmm> should i use <$> and <*> or liftA2, are there best practices for this?
06:11 saurabhnanda joined
06:11 <cocreature> qmm: I tend to use <$> and <*> because it’s easier to add more arguments
06:11 <jle`> qmm: i think both are equally ok
06:11 <Cale> Also, in order to talk about referential transparency, you really need to specify the context in which something is referentially transparent, otherwise, there are aspects of evaluation which are not referentially transparent either.
06:11 sw1nn joined
06:11 <Cale> A simple variable like x for instance, does not always refer to the same thing.
06:11 <iqubic> Now how does stuff like "Do x <- getLine; putStrln (x ++ x)" work?
06:12 <iqubic> Is that an IO action?
06:12 <qmm> thanks cocreature and jle`
06:12 <jle`> iqubic: yes; what is its type? :)
06:12 <Cale> Yes, modulo case
06:12 <saurabhnanda> Can anyone help me with lenses here? https://stackoverflow.com/questions/43314855/shorter-way-to-traverse-nested-record-with-maybe/43315062 Especially this part -- `^. _Just` over a `Maybe Text` results in a "" However `^. _Just` over a `Maybe Int` results in the following error -- No instance for (Monoid Int) arising from a use of ‘_Just’ Is it possible to traverse over a Maybe in such a way that the entire traversal results in
06:12 <saurabhnanda> a Maybe without depending on Monoid magic?
06:12 <glguy> liftA2 is good for cases like : f (liftA2 g)
06:12 <Cale> do notation works like this:
06:12 <jle`> iqubic: you're defining an IO action that gets a line and prints the result concatenated to itself
06:12 <glguy> it's like how we have sum and foldl (+) 0, both
06:12 <Cale> do { v <- x; <stmts> } = x >>= \v -> do { <stmts> }
06:13 <Cale> do { x; <stmts> } = x >> do { <stmts> }
06:13 <iqubic> I understand how the desuguring fo notation works.
06:13 <Cale> etc. etc. you apparently get it :)
06:13 <jle`> in haskell, we define IO complex actions by manipulating/sequencing/combining simpler primitives that GHC gives us
06:13 <jle`> so if i have an IO action that reads frmo the disk, and an IO action that launches missiles, I can combine them using (>>) to make a new IO action that reads from the disk *and* launches missiles
06:14 <Cale> Here, let's build a small toy version of the IO monad, and then write an executor for it which will turn it into a proper IO action.
06:14 <cocreature> > Just 1 ^? _Just -- saurabhnanda
06:14 <lambdabot> Just 1
06:14 <cocreature> > Nothing ^? _Just
06:14 <lambdabot> Nothing
06:14 <Cale> data MyIO a = Done a | PutStrLn String (MyIO a) | GetLine (String -> MyIO a)
06:14 zeroed joined
06:14 <iqubic> Technically every Haskell program ever is one large IO action. Just look at the type of Main.
06:14 <iqubic> :t Main
06:14 <lambdabot> error: Data constructor not in scope: Main
06:15 <jle`> iqubic: well, every haskell executable is an IO action
06:15 <jle`> that's what you do when you define a haskell executable
06:15 <iqubic> Cale: What is that data good for?
06:15 <jle`> you're defining an IO action
06:15 <Cale> The intention here is that we're going to represent programs which do line-based terminal I/O
06:15 <cocreature> saurabhnanda: note that this will only give you the first value if your traversal targets multiple elements.
06:15 <saurabhnanda> cocreature: thank you :)
06:15 <jle`> haskell libraries are not one large IO action, though, ofc. just haskell executables
06:15 <iqubic> Yep.
06:15 <Cale> This is heavily oversimplified, but hopefully if we understand this, it's possible to imagine extending it indefinitely to include everything else.
06:15 <saurabhnanda> cocreature: here's how I'm using it in real code -- fromMaybe "" (bi ^? bookerContact._Just.fullName) -- should I be careful about something?
06:15 bntr joined
06:16 Itkovian joined
06:16 <iqubic> Cale, I understand how IO works now.
06:16 <cocreature> saurabhnanda: looks fine. although in that case the Monoid instance would probably work?
06:16 <Cale> So, a MyIO action can either produce a simple result immediately without causing any effect, which is represented by Done x
06:16 ev0lord joined
06:16 <saurabhnanda> cocreature: it seems too magical and I'm afraid no newcomer would be able to figure out where the empty string is coming from.
06:17 orbifx joined
06:17 <cocreature> saurabhnanda: yeah I agree that the solution you have is clearer
06:17 <Cale> Or it can start off by printing some line s to the terminal, and be followed up with another MyIO action x, which is represented by PutStrLn s x
06:17 <Myrl-saki> Oh whoops. Internet disconnected.
06:17 a3Dman joined
06:17 <Myrl-saki> Cale: Right.
06:17 balor joined
06:17 <Cale> Or it can start off by reading a line of input from the user, and then using the resulting String to determine which MyIO action should be carried out thereafter
06:17 <glguy> saurabhnanda: you can even define your own ^. that doesn't allow the monoid behavior
06:17 <Myrl-saki> Luckily, we're talking about IO right now.
06:17 Xanather joined
06:17 <Myrl-saki> How does ghc compile IO, which is "data"?
06:18 <Cale> which is represented by GetLine f, where f :: String -> MyIO a is a function describing what to do if the input was any given string
06:18 <saurabhnanda> glguy: cocreature: generally speaking, is depdending on the monoid behaviour **as a default** a wise choice by the lens library?
06:18 <Cale> Myrl-saki: Note that I'm not actually talking about GHC's implementation here, which involves low-level hackery
06:18 Itkovian joined
06:19 raichoo joined
06:19 <iqubic> :t interact
06:19 <Cale> Just a useful mental model and a possible implementation (though getting it to compile nicely to quality machine code would be harder, most likely)
06:19 <lambdabot> (String -> String) -> IO ()
06:19 <qmm> > let x = [1,2,3] y = [4,5,6] in sum <$> (liftA2 (,) x y) -- is shorter than
06:19 <Cale> So, let's write the Monad instance for MyIO
06:19 <lambdabot> <hint>:1:19: error:
06:19 <lambdabot> parse error on input ‘=’
06:19 <lambdabot> Perhaps you need a 'let' in a 'do' block?
06:19 <iqubic> What does interact do?
06:19 <Myrl-saki> Cale: Can I get info either way? I'm interested in making a programming language.
06:19 <cocreature> saurabhnanda: depends on who you ask I guess. personally I’m not a big fan of it.
06:19 <glguy> saurabhnanda: I argued against it. we already have foldOf, view doesn't need to support it
06:19 <qmm> > let x = [1,2,3] ; y = [4,5,6] in sum <$> (liftA2 (,) x y) -- is shorter than
06:19 <lambdabot> [4,5,6,4,5,6,4,5,6]
06:19 <Cale> iqubic: It reads stdin and passes that to the function in order to obtain stdout
06:19 <* seequ_> remembers defining things like MyIO for animation compositions even in procedural languages.
06:20 takle joined
06:20 <iqubic> So it's only useful in Main?
06:20 <qmm> that is strange
06:21 <Cale> iqubic: basically. It's only useful for writing fairly simplistic programs which only do simple terminal I/O
06:21 <Myrl-saki> :t sum
06:21 <jle`> qmm: did you leave out a word
06:21 <lambdabot> (Num a, Foldable t) => t a -> a
06:21 <saurabhnanda> cocreature: glguy: thanks... good to know my intuition about haskell code is shaping up :)
06:21 <Cale> and even at that, it's tricky to do anything too complicated with it
06:21 <cocreature> I seem to recall that GHC supports something like "{-# ATTRIBUTE … #-}" where the attributes can then be read in the compiler but I can’t find any documentation on it. am I missremembering here?
06:21 <qmm> if you set to x = [1,2,3] and y = [4,5,6], sum <$> (liftA2 (,) x y) results in Just 2, but for some reason let x = [1,2,3] ; y = [4,5,6] in sum <$> (liftA2 (,) x y) results in [4,5,6,4,5,6,4,5,6]
06:21 <glguy> cocreature: ANN
06:21 <cocreature> glguy: ah I just found it
06:21 <cocreature> thanks
06:22 <Cale> Well, before we even get to the monad instance, let's write
06:22 <Cale> execute :: MyIO a -> IO a
06:22 mbuf joined
06:22 <Cale> execute (Done v) = return v
06:22 <Cale> execute (PutStrLn s x) = do putStrLn s; execute x
06:22 <jle`> qmm: i'm not sure how the first one is Just 2
06:23 <Cale> execute (GetLine f) = do s <- getLine; execute (f x)
06:23 <Cale> oops
06:23 <Cale> execute (GetLine f) = do s <- getLine; execute (f s)
06:23 <iqubic> Cale, why are we doing this?
06:23 <qmm> jle`: me either
06:23 <iqubic> What is the point?
06:23 <Myrl-saki> iqubic: Why not
06:23 <Cale> Basically for fun, and to see a possible implementation of this sort of thing
06:23 <jle`> qmm: what are you compiling?
06:23 <Cale> This kind of interpreter pattern is pretty useful in a lot of cases
06:23 <jle`> what do you expect the result to be?
06:23 <Myrl-saki> Cale: We had a discussion about this a few days ago. :D
06:23 zeroed joined
06:24 <qmm> oh, i didn't set x to [1,2,3] and y to [4,5,6]
06:24 <qmm> that's why
06:24 <halogenandtoast> lol
06:24 <qmm> they Just 3 and Just 2
06:24 <jle`> heh
06:24 Ferdirand joined
06:24 <jle`> anyway using Foldable for tuples makes me uncomfortable
06:24 <Cale> We can also implement Monad/Applicative/Functor for this type.
06:25 <iqubic> How do I run a thing I've built with Stack?
06:25 <Myrl-saki> > sum (2,3)
06:25 <lambdabot> 3
06:25 <Myrl-saki> > wutface
06:25 <lambdabot> error: Variable not in scope: wutface
06:25 <Myrl-saki> ohwhoops
06:25 <iqubic> > sum (1,2)
06:25 <lambdabot> 2
06:25 <iqubic> > sum (2,1)
06:25 <lambdabot> 1
06:25 <Myrl-saki> Why not Foldable (a, a)
06:25 <Cale> iqubic: stack build and then run the resulting executable
06:26 <Myrl-saki> That's saner, isn't it?
06:26 <iqubic> But I don't know where it put the executable.
06:26 eklavya joined
06:26 <iqubic> :t sum
06:26 <Myrl-saki> iqubic: `stack path`
06:26 <lambdabot> (Num a, Foldable t) => t a -> a
06:26 <Myrl-saki> or osmething
06:26 <Cale> It should tell you
06:26 revprez_atlanta joined
06:26 <Koterpillar> iqubic: stack path --local-install-root or something
06:26 <Koterpillar> iqubic: stack help path
06:27 <jle`> Myrl-saki: you can't really write that instance
06:27 <Cale> stack path --help rather
06:27 <jle`> try it
06:27 <jle`> you'll see why :)
06:28 MoALTz joined
06:28 <Myrl-saki> • Expecting one fewer argument to ‘(a, a)’
06:28 <Myrl-saki> Expected kind ‘* -> *’, but ‘(a, a)’ has kind ‘*’
06:28 <Myrl-saki> ; ^ ;
06:28 <jle`> yup. you could make maybe a
06:28 <jle`> newtype Join f a = Join (f a a)
06:28 <Myrl-saki> type D f a = f
06:28 <Myrl-saki> Welp
06:28 <jle`> instance Foldable (Join (,)) where ...
06:29 <Myrl-saki> jle`: What I was about to say.
06:29 bab joined
06:29 <iqubic> So there is no simple way to run a stack project?
06:29 <jle`> iqubic: if you stack install, you can just type in the name of the executable
06:29 <jle`> in the command line
06:29 jennyrgb joined
06:29 <jle`> for exampl,e if i hav ean executable called f'foo'
06:29 <Cale> You can also stack exec <executablename>
06:30 <jle`> i can stack install => type 'foo'
06:30 <Myrl-saki> jle`: IIRC, FlexibleInstances is evil?
06:30 pellenation joined
06:30 <jle`> FlexibleInstances is pretty normal
06:30 quchen joined
06:30 <jennyrgb> how do you interpret (+3)?
06:30 <iqubic> I like "stack exec executablename"
06:30 <iqubic> you can't jennyrgb.
06:30 <jle`> stack exec xecutablename won't re-install
06:30 <jle`> jennyrgb: it's an operator section
06:30 <jennyrgb> (+3)2 makes no sense to me, but it's 5
06:30 <tsahyt> jennyrgb: (+3) == \x -> x + 3
06:30 <srhb> jennyrgb: It's an operator section where the left hand argument is elided.
06:31 <jle`> it's syntactic sugar for \x -> x + 3
06:31 <iqubic> Right.
06:31 <jle`> jennyrgb: you can imagine that it's "waiting" for something on the left hand side of the +
06:31 <Myrl-saki> jle`: Get the type
06:31 <srhb> jennyrgb: Similarly, (3+) is an operator section where the right hand argument is elided, so, \y -> 3 + y
06:31 <jle`> Myrl-saki: FlexibleInstances is actually the more intuitive behavior for how typeclasses should work, i believe
06:31 <Myrl-saki> jennyrgb: *
06:31 <tsahyt> for (+), left and right sections happen to do the same (because addition is commutative), but that's of course not always the case
06:31 <iqubic> What does FlexibleInstances do?
06:31 <jle`> Myrl-saki: the reason why it's an extension is because the haskell report is a bit restritive in what is allowed for typeclass resolution and stuff
06:32 <jennyrgb> oh right, I forgot this. Can you make your own such "sugar" for your own operators/functions?
06:32 <jle`> jennyrgb: what kind of sugar do you mean?
06:32 <srhb> jennyrgb: It's there automatically
06:32 SpaceGazebo3 joined
06:32 <jle`> you can use sections for any operator
06:32 <tsahyt> jennyrgb: sections work just fine on any operator, including your own
06:32 Snircle joined
06:32 <iqubic> You can define your own operator however you want.
06:32 <iqubic> What does FlexibleInstances do?
06:32 <tsahyt> jennyrgb: they also work for functions used infix by writing them in backticks
06:32 <srhb> jennyrgb: The rule is: Anything that is a symbol-only name is an operator by default.
06:32 <jle`> @let x &*$#@ y = x * y + y in (&*$#@ 5) 10
06:32 <lambdabot> Parse failed: Parse error: in
06:32 <tsahyt> jennyrgb: e.g. (`mod` 5)
06:32 <Cale> iqubic: In Haskell 98 (and 2001, which barely changed anything in H98), there was an arbitrary restriction that instances of type classes must be for a type constructor applied to some list of distinct type variables *only*
06:33 <jle`> >let x &*$#@ y = x * y + y in (&*$#@ 5) 10
06:33 <tsahyt> :t (`mod` 5)
06:33 <lambdabot> Integral a => a -> a
06:33 <Cale> iqubic: e.g. if you wanted to write an instance of some class for Foo Bar, that's not allowed, you'd have to be able to write it for Foo a
06:33 <halogenandtoast> Let's say I had a grid of positions and I want to place mines at random spots, but I want to guarantee a certain number of mines were placed. Is there a better way of doing this than say
06:33 <iqubic> Cale, what does that mean?
06:33 <halogenandtoast> gen <- newStdGen
06:34 <halogenandtoast> shuffle xs = map snd $ sortOn fst $ zip (randoms gen) xs
06:34 <halogenandtoast> take 9 $ shuffle [[x, y] | x <- [0..9], y <- [0..9]]
06:34 <jle`> iqubic: when in doubt, you can also just look at the ghc user manual
06:34 <jle`> iqubic: which is usually pretty clear
06:34 <jle`> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#ghc-flag--XFlexibleInstances
06:34 <jle`> it covers every extension :)
06:34 <Cale> iqubic: One place where this is especially painful is that it means that you can't just write an instance of some class for String specifically, since String is a synonym for [Char] which is the [] type constructor applied to Char
06:34 <srhb> halogenandtoast: nub and randoms ?
06:35 <Cale> Char being a type constructor and not a type variable, this falls foul of that rule
06:35 shafox joined
06:35 <jennyrgb> why isn't (-3) working?
06:35 <jle`> jennyrgb: because we can't have good things
06:35 <srhb> jennyrgb: - is special for prefix minus
06:35 <Koterpillar> jennyrgb: because it's special cased
06:35 <srhb> jennyrgb: Sadly. :(
06:35 <halogenandtoast> srhb: but how would I ensure I get 9 good results?
06:35 <jle`> jennyrgb: the haskell parser treats - as a special case :'(
06:35 <Cale> So FlexibleInstances just turns off that rule, and lets you write instances specialised to particular type arguments
06:35 <jle`> jennyrgb: that's why we have subtract, so you can write (subtract 3) instead
06:35 <srhb> halogenandtoast: "good" ?
06:36 <halogenandtoast> 9 total results, none of which are duplicates
06:36 <halogenandtoast> nub would remove duplicates, but doesn't ensure 9
06:36 <srhb> halogenandtoast: take 9 . nub
06:36 <tsahyt> :t (3 -)
06:36 <lambdabot> Num a => a -> a
06:36 <tsahyt> that works though ^
06:36 <jle`> jennyrgb: haskell treats (-3) as the number "negative three"
06:36 kosorith joined
06:36 <srhb> halogenandtoast: You get an infinite list of (Int,Int), so you just want to make sure those are unique, so you nub them, then you take nine of the nubbed (unique) values?
06:36 <jle`> instead of a section \x -> x - 3
06:36 <halogenandtoast> srhb: interesting, trying it out
06:36 <Myrl-saki> :t (- 3)
06:36 <lambdabot> Num a => a
06:36 <Cale> The place where those *Instances extensions start to become evil is with OverlappingInstances
06:36 <Myrl-saki> jennyrgb: ^
06:37 <jle`> > 8 + (-3)
06:37 a3Dman joined
06:37 <lambdabot> 5
06:37 <Myrl-saki> Ohhh. It was OverlappingInstances that was evil.
06:37 <Myrl-saki> Not Flexible.
06:37 bungoman joined
06:37 <tsahyt> OverlappingInstances can be abused, but can also be okay
06:37 <Myrl-saki> Mixing up muh extensions.
06:37 <tsahyt> but in most cases is not what you want anyhow
06:37 edsko joined
06:37 <jle`> one of those "you should only use it if you know why you shouldn't use it" things
06:38 <Myrl-saki> I guess I'll change my question.
06:38 azahi joined
06:38 swalladge joined
06:38 <Myrl-saki> I'm interested in making a Haskell-like language for Arduino. Should I use monadic main or nah?
06:38 <Cale> If you're going to use it, I recommend confining all the instances of the type class in question to a single module.
06:39 <Cale> Myrl-saki: I don't know what that question means?
06:39 <Cale> Myrl-saki: If you support type classes, you should have a Monad instance for IO.
06:39 <Myrl-saki> Cale: I'm considering doing something like `main :: World -> World`
06:39 <jle`> as a pure function?
06:39 <qmm> let x = [1,2,3] ; y = [4,5,6] in liftA2 (,) x y
06:39 <jle`> does that...make sense?
06:39 <qmm> > let x = [1,2,3] ; y = [4,5,6] in liftA2 (,) x y
06:39 <lambdabot> [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
06:40 <qmm> > let x = [1,2,3] ; y = [4,5,6] in lookup 1 (liftA2 (,) x y)
06:40 <lambdabot> Just 4
06:40 <Myrl-saki> jle`: No idea.
06:40 <Cale> Myrl-saki: I doubt there's any reasonable type World for which that would make really good sense.
06:40 <qmm> how would i say fmap (lookup 1) (liftA2 (,) x y)
06:40 <Cale> Myrl-saki: You might be able to get by with something like what old-timey-Haskell had
06:40 <jle`> Myrl-saki: if you want to build a pure language over an impure low-level one, look at purescript for a good example
06:40 <Cale> main :: [Response] -> [Request]
06:40 <Myrl-saki> Cale: Isn't that what old Haskell did?
06:40 <Myrl-saki> Oh.
06:41 <Cale> That was kind of awful to program though.
06:41 <jle`> its IO system is a very close-to-the-metal wrapper over javascript semantics
06:41 <iqubic> How does that even work?
06:41 <Cale> If we still had that today, people would define an IO monad pretty quickly.
06:41 <Myrl-saki> Cale: lmao
06:41 <jle`> and it has a monadic interface
06:41 <iqubic> How does the old style work?
06:41 guiben joined
06:42 <jle`> iqubic: your program is a function that takes inputs and returns outputs
06:42 <Cale> iqubic: Your function produces a list of requests, which describe I/O to be performed.
06:42 <Myrl-saki> Cale: I'll be including typeclasses
06:42 <Cale> and it gets a list of responses, which are basically the results of performing that I/O
06:42 <Myrl-saki> Cale: My problem is how to compile main.
06:42 <lpaste> qmm pasted “question” at http://lpaste.net/354472
06:42 <Cale> and the nth response corresponds to the nth request
06:42 <jle`> Myrl-saki: first you have to think about what you really mean when you say 'main'
06:42 <jle`> because main isn't anything special
06:43 <jle`> you probably are asking about how you want to compile your actual programs?
06:43 <halogenandtoast> Is there a method that takes a list and gives you them in groups like x = [1,2,3,4,5,6]; f 2 x == [[1,2],[3,4],[5,6]]
06:43 <Myrl-saki> jle`: Compiling individual functions makes sense.
06:43 <jle`> halogenandtoast: chunksOf from the split package
06:43 <monochrom> halogenandtoast: Data.List.Split has it.
06:43 <Myrl-saki> jle`: But compiling main is different, if we're considering Cale's earlier definition in `MyIO`
06:44 <iqubic> Shouldn't the request be on LHS of the old time main type signature.
06:44 <halogenandtoast> thanks jle` monochrom
06:44 <jle`> Myrl-saki: so you mean, how to hook your individual functions to what your arduino actually executes?
06:44 <Cale> iqubic: That would mean that it was getting a list of requests from the outside world
06:44 <Myrl-saki> jle`: Right.
06:45 <jle`> Myrl-saki: i consider purescript's approach to be nice here
06:45 <Cale> You have something like
06:45 <Myrl-saki> jle`: Which is?
06:45 <iqubic> Cale, Isn't that what happens? You request your program do something, and it give a reponse back to you.
06:45 <Cale> data Request = ReadFile FilePath | WriteFile FilePath String | ...
06:46 <iqubic> Ah. I see now.
06:46 <iqubic> I'm wrong.
06:46 <Cale> data Response = Success | Str String | Failure IOError | ... some other misc cases
06:46 <Cale> It wasn't terribly pretty
06:46 <jle`> Myrl-saki: it's a thin wrapper over ffi calls that can be composed using a monadic/functor/applicative interface
06:47 <jle`> huh i guess that's similar to haskell, just with a much smaller RTS
06:47 <Cale> https://www.haskell.org/definition/haskell-report-1.2.ps.gz
06:47 fantasticsid joined
06:47 <Myrl-saki> jle`: I see.
06:47 <Cale> That was the last Haskell report which included the old-style I/O. It's in section 7 starting on physical page 69
06:47 <Myrl-saki> jle`: Thanks.
06:48 <jle`> Myrl-saki: so if you had two data types wrapping an FFI call, you can write a function that returns a sequenced one in a disciplined way
06:49 <jle`> i'm not exactly sure how purescript does it, but i think you can look into it; the language is written in haskell
06:49 <Cale> Anyway, they arranged it so that you'd write stuff like readFile fileName (\err -> errorHandler) (\contents -> ...)
06:49 takuan joined
06:49 <jle`> purescript is nice because the generated code is pretty low-level close to what you'd expect
06:49 <jchia> I want to convert tuples of up to 10 elements and for each element that's a String, I want to convert it to Text. How could I go about writing a function for this conversion? Seems like I need a typeclass for the different tuple types that the function can take as input? How do I get String converted to Text but all other types left untouched? Do I need type families?
06:49 <Cale> and the upshot of it was very similar to programming directly in that MyIO type I defined before.
06:50 <jchia> e.g. (1 :: Int, "abc" :: String) gets converted to (1 :: Int, "abc" :: Text)
06:50 <Cale> Except that you were really manipulating these functions of lists.
06:50 <jle`> jchia: haskell's type system isn't meant for dealing with big tuples
06:50 <jle`> your best bet is to change the source of the tuple to return a reasonable data type instead
06:50 <jchia> jle`: I could explicitly define stuff for each tuple size in [1, 10]
06:50 <Cale> jchia: You notice that you already know where the Strings occur, and you write a lambda which packs those.
06:51 <jchia> Cale: I want to generalize it so that any element in a tuple can be String.
06:51 danvet joined
06:51 oish joined
06:51 <Cale> What problem are you actually solving?
06:51 <jle`> are you just generalizing it for fun?
06:53 <Cale> It would be possible to write something that worked on tuples of Typeable-typed things.
06:53 <Cale> For each tuple size individually.
06:54 <Cale> er...
06:54 jokester joined
06:54 <Cale> actually, no, nevermind
06:54 <jchia> I have an actual use case. That was just a simple example to illustrate the use case. I'm calling Python from Haskell by passing arguments in a tuple, using MessagePack serialization and deserialization (data-msgpack). The legacy Python code takes str, not unicode, so where the Python function takes a str and I have a Text or String in Haskell, I need to convert it into a ByteString, which Data.MessagePack correctly presents as a str to Python. That's why I w
06:54 <Cale> It's possible to make the decisions based on that, but then what's the result type?
06:55 <Cale> Message got cut off at "That's why I w"
06:55 <jchia> (String & Text gets presented as unicode to Python, and my legacy Python code was written for str, not unicode)
06:55 <Cale> But this sounds like a use-case for a new type class.
06:55 <jchia> ... That's why I want automatic Text/String->ByteString conversion of tuple elements.
06:56 <halogenandtoast> Is there some way to do something like this: take 4 $ [[x, y] | x <- randomRs (0, 9) gen, y <- randomRs (0, 9) gen]
06:56 Ferdirand joined
06:56 <Cale> However, I don't know why you should need to convert tuples to other tuples
06:56 <jchia> requiring the callers in haskell to manually do the conversion is quite a bit of boilerplate and an eyesore.
06:56 <halogenandtoast> that gives me two sets of random numbers (in potentially different ranges) from the same random number generator?
06:56 <jle`> halogenandtoast: you see the problem, right?
06:56 <halogenandtoast> jle`: I know what the problem is, but not the solution
06:56 <jle`> halogenandtoast: you can use randomRs for tuples
06:56 <jchia> Text/String in Haskell gets passed to Python as unicode. I want to pass str to Python, so I need to pass ByteString, hence, the need for Text/String -> ByteString conversion.
06:56 <Cale> jchia: You should just have instances of some class for String and Text which do the right thing.
06:56 <jle`> take 4 $ randomRs ((0,0), (9,9) gen
06:57 <Cale> jchia: and then you have another instance for tuples which relies on the instances for each of the components
06:57 <halogenandtoast> > take 4 $ randomRs ((0,0), (9,9) gen
06:57 <lambdabot> <hint>:1:36: error:
06:57 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
06:57 <halogenandtoast> > take 4 $ randomRs ((0,0), (9,9)) gen
06:57 <lambdabot> error:
06:57 <lambdabot> • Variable not in scope: gen
06:57 <lambdabot> • Perhaps you meant one of these:
06:57 zeroed joined
06:57 <halogenandtoast> of course
06:57 <jle`> > take 4 $ randomRs ((0,0), (9,9)) (mkStdGen 10) :: [(Int, Double)]
06:57 <lambdabot> error:
06:57 <lambdabot> • No instance for (Random (Int, Double))
06:57 <lambdabot> arising from a use of ‘randomRs’
06:58 <jchia> Cale: Let's say String and Text are instances of Convert. Do other types get to have instances of Convert? If not, when I process the tuple, how do I rely on Convert?
06:58 <halogenandtoast> jle`: I'm not sure that's how randomRs works...
06:58 <halogenandtoast> randomRs :: (RandomGen g, Random a) => (a, a) -> g -> [a]
06:59 detrumi joined
06:59 <Cale> jchia: Yes, all the types you want to be serialise need instances of the class.
06:59 <Cale> jchia: are you using the msgpack package?
06:59 iomonad joined
06:59 <Cale> This class already exists.
06:59 <Cale> and it appears to have appropriate instances
07:00 <halogenandtoast> Or I guess the problem is that there is no instance of Random for (Int, Int)
07:00 <Cale> jchia: https://hackage.haskell.org/package/msgpack-1.0.0/docs/Data-MessagePack-Object.html#t:MessagePack
07:02 Mysterious_Light joined
07:02 bhiliyam joined
07:02 ragepanda joined
07:04 magthe joined
07:04 thc202 joined
07:05 Itkovian joined
07:05 takle joined
07:05 teggi joined
07:06 <jennyrgb> wtf, does "context" have a real meaning or is it some analogous woo woo in tutorials for retards?
07:07 <monochrom> Both.
07:07 <jennyrgb> the analogies are sometimes so dumb that they cease to have any meaning
07:07 <monochrom> But 70% the latter.
07:07 aarvar joined
07:07 <monochrom> But I wouldn't say "retard".
07:07 <jennyrgb> does the word "context" mean anything in the following context? fmap (+3) (Just 2)
07:08 fizruk joined
07:08 <monochrom> People are not retard. People are more sinister than that. Self-deception.
07:08 <monochrom> No.
07:08 rcschm joined
07:08 <monochrom> Maybe and [] are better off with the container analogy.
07:08 <cocreature> the meaning of context depends on the context
07:08 <tsahyt> context is context-sensitive
07:08 <jennyrgb> I never trust texts that have a lot of exclamation marks in them
07:09 <tsahyt> jennyrgb: there are all sorts of analogies for that. context, environment, boxes, tortillas... you name it.
07:09 <monochrom> Reader and State are the ones that benefit from the context analogy.
07:09 xificurC joined
07:09 <monochrom> And Writer basically elludes both.
07:09 <tsahyt> for reader I prefer "environment"
07:10 <jennyrgb> something about boxes and contexts regarding functors.. and a lot of exclamation marks and "bam!" "boom!"
07:10 hdeshev joined
07:10 <monochrom> And IO is like "none of the above".
07:10 <jennyrgb> and instead of writing out actual numbers, they have numbers hand drawn with happy faces and different colors
07:10 <monochrom> And lastly, free monads are like "all of the above".
07:11 <tsahyt> jennyrgb: Functors are rather simple though. fmap takes a function a -> b and gives you a function f a -> f b. and on the type level, f :: * -> * takes a type and gives you another.
07:11 vlatkoB_ joined
07:11 <tsahyt> and it all obeys the laws that fmap id = id, and fmap f . fmap g = fmap (f . g)
07:11 <tsahyt> and that's really all there is to it
07:12 <jennyrgb> functors in general are functions that returns functions based on a parameter
07:12 <tsahyt> so the f (on the type level) maps types to types, and fmap takes functions and maps them to functions under f.
07:12 <monochrom> This is a strange event. Just 13-14 hours ago, we had the opposite conversation, people were claiming "inaccurate fuzzy fast intuition is so helpful!"
07:12 <tsahyt> and the mapping preserves structure
07:13 <jle`> halogenandtoast: yes, that was the problem, heh
07:13 <jennyrgb> monochrom: only if you know what you're doing. you learn the real thing first and then make up simplified models in your head to process it faster. But you don't teach it in the first place with bullshit analogies with talking cats and dogs
07:13 adimit joined
07:13 <tsahyt> I for one am rather fond of the burrito april fools paper
07:13 <jennyrgb> "hi, I'm a higg bozon, I can speak and I am a gat... here's a cheese and it represents a quark" WTF! Kill yourself, do it.
07:13 <monochrom> And unsurprisingly, our #1 prosecutor of nitpickers stroke again with "you hate it because you are over-nitpicking".
07:14 <tsahyt> monochrom: I think both have value. the problem I have with fuzzy fast intuition is that some are looking for other people's intuitions, and that never works well
07:15 <Hakim-OP> burrito for the hungry mathematician
07:15 <tsahyt> once you've build your own intuition about a concept, you also know where it fails. when you try to mirror that of another, say through some box analogy, you simply don't know where it stops being useful and starts being outright wrong
07:16 <tsahyt> Hakim-OP: still my favorite april fools paper
07:16 <monochrom> My bottomline is predictive power. In the same sense as in science. The predictive power of your model.
07:16 raichoo joined
07:17 atiti joined
07:17 <cocreature> is "-pgmlc clang" a thing that’s supposed to work? it fails because of unsupported options for me
07:17 <jchia> Cale: The problem is that I want to convert, say, (1 :: Int, "abc" :: Text) to (1 :: Int, "abc" :: ByteString) before I give it to Data.MessagePack.
07:18 <tsahyt> :t fmap @(Int,a)
07:18 <lambdabot> error:
07:18 <lambdabot> Pattern syntax in expression context: fmap@(Int, a)
07:18 <lambdabot> Did you mean to enable TypeApplications?
07:18 mstruebing joined
07:18 <tsahyt> hmpf
07:18 <Myrl-saki> jle`: Should I consider having an interpreter for my first programming language?
07:18 <MarcelineVQ> she doesn't to type applications
07:18 rcschm joined
07:18 <MarcelineVQ> that's not a valid type application anyway though
07:19 <monochrom> If you have a model that gets you correct code and correct predictions for, say, both Maybe and [], then it is a fairly valuable model, and you get to say "I haven't treated State yet and I know the limitation of my model".
07:19 <tsahyt> MarcelineVQ: @((,) Int)?
07:19 <tsahyt> I still have to get the hang of that
07:19 <Myrl-saki> Hmmm. If i'll be writing an interpreter, that'd still be compiling.
07:19 <Myrl-saki> jle`: Nyeh, just ignore that.
07:19 Gurkenglas_ joined
07:19 <monochrom> That is a good sense of "inaccurate fast" model. But it is not fuzzy, it actually makes precise predictions.
07:19 <MarcelineVQ> tsahyt: yeah @((,) Int) should show what you were after
07:20 <monochrom> I don't think fuzzy has value until you are broadly experienced.
07:20 <cocreature> ah nvm pgmlc is the llvm compiler and not the C compiler
07:22 <MarcelineVQ> cocreature: ah okay, I was wondering if there was some sort of other options you had to pass to 'enable llvm' or something that it wanted
07:23 ventonegro joined
07:24 <jle`> halogenandtoast: any more compplicated and it might be easier to use MonadRandom's interface, which wraps over System.Random
07:25 <jle`> halogenandtoast: then you can use (,) <$> replicateM 10 (getRandomR (0,9)) <*> replicateM 10 (getRandomR (0,9))
07:25 <jle`> basically those compositional combinators we all know and love
07:26 eklavya joined
07:27 <Cale> jchia: But why do you want to do that? Is it choosing the wrong encodings for some types?
07:28 <Cale> jchia: You might just want to define your own version of the type class with your own instances.
07:28 <jchia> when I have a String/Text, I want to convert it to a ByteString first before giving it to Data.MessagePack so that when it goes to Python, it gets presented as a str instead of unicode
07:29 raichoo joined
07:29 <jchia> String/Text on the Haskell side gets presented as unicode, not str, to the Python side
07:30 <Cale> jennyrgb: fwiw, I've never managed to figure out what people mean when they say "context" with respect to functors.
07:30 richi235 joined
07:30 <quchen> jchia: Data.Text.Encoding
07:31 juhp joined
07:31 <Cale> jchia: Yeah, I think your problem is just that the Text and String instances for that class aren't doing the thing you want.
07:31 <quchen> jchia: Text does not have a ByteString representation and more than a picture has. Text is abstract text, and you can choose to represent it in different ways as bytes, just like pixels are coloured things that you can choose to represent via JPEG, PNG, …
07:31 <quchen> s/and/any/
07:31 takle joined
07:31 prophile joined
07:31 <Cale> quchen: I think jchia wants to ignore the problem of characters outside ASCII
07:32 <jchia> quchen: I'm trying to do the conversion automatically for tuple elements, e.g. (1 :: Int, "abc" :: Text) -> (1 :: Int, "abc" :: ByteString), ("xyz" :: String, False) -> ("xzy" :: ByteString, False)
07:32 <jennyrgb> Cale: I just stopped reading the text when a bunny jumped into a hat.. I have no idea where they were going with that.
07:32 <quchen> Cale: Excellent! .Encoding has a function for this as well. ;-)
07:33 <jchia> quchen: My use case excludes non-ASCII.
07:33 <halogenandtoast> jle`: I might have missed an intermediate message, what do you mean by more complicated?
07:33 <quchen> jchia: Wonderful! Then use UTF-8, which is compatible with ASCII.
07:34 shafox joined
07:34 <quchen> Unless you want to save that bit per character.
07:34 <Cale> quchen: Right, jchia would just want to use *that* instead of whatever it is that the MessagePack instance is doing.
07:34 <monochrom> Python supports UTF-8 too.
07:34 <jchia> This is all about the python side. The Python legacy code expects str, so I want to make sure I give it a str.
07:34 <monochrom> What does "str" mean, at the metal level?
07:35 <jchia> monochrom: Python has str & unicode types
07:35 <jchia> unicode is the standard string type in Python 3. In Python 2, str is the standard string type.
07:35 doomlord joined
07:35 <jchia> ...although Python 2 also has unicode.
07:35 <Cale> jchia: So I think the answer to your problem is just to make a new type class which mimics the MessagePack class closely, but which handles these types the way you actually want them handled.
07:36 <Cale> That, or make a newtype that can have the appropriate instances
07:36 <Cale> (of MessagePack)
07:37 <jle`> halogenand
07:38 <jle`> halogenandtoast: more complicated sequences of getting random stuff
07:38 <jle`> than just simple uses of randomRs
07:39 Swizec_ joined
07:39 <halogenandtoast> jle`: Does that mean I should make a Random instance for (Int, Int) ?
07:40 <jle`> orphan instances are usually a bad idea
07:40 <jle`> replicateM 5 (getRandomR (0,9)) will get you 5 randomR's, from the MonadRandom library
07:40 govg joined
07:40 <jle`> and you can use liftA2 zip to combine two such lists together
07:40 <jle`> hm, or even
07:41 <jchia> Cale: The msgpack package you linked to seems to be unmaintained. Hence, I'm using the data-msgpack package.
07:41 <halogenandtoast> right: I like (,) <$> replicateM 10 (getRandomR (0,9)) <*> replicateM 10 (getRandomR (0,9)) as a solution but I'm not in a monad at the moment.
07:41 <jle`> replicateM 5 ((,) <$> getRandomR (0,9) <*> getRandomR (0,9))
07:41 <Cale> jchia: ah, okay, let me look at that one
07:41 albertid joined
07:41 <jle`> i'm talking about using the Rand monad from MonadRandom
07:41 <monochrom> IIRC (Int,Int) is already a Random instance.
07:42 <jle`> we tried earlier and it doesn't seem like there was
07:43 <jle`> > take 4 $ randomRs ((0,0), (9,9)) (mkStdGen 10) :: [(Int, Int)]
07:43 <lambdabot> error:
07:43 <lambdabot> • No instance for (Random (Int, Int))
07:43 <lambdabot> arising from a use of ‘randomRs’
07:43 <jchia> Cale: If I adapt MessagePack but handle String & Text differently, like you said, isn't that a lot of code to copy? Isn't it simpler to convert the String & Text elements in the tuples directly?
07:43 <Cale> jchia: Not if you want to handle that generically.
07:44 nilg joined
07:44 mthek joined
07:44 <Cale> jchia: Think about it this way: what's the type of the function you want to write?
07:44 <halogenandtoast> It would have been nice and easy if there was an instance for that.
07:45 <MarcelineVQ> halogenandtoast: if it'll make a big difference for you you can create the instance for your use
07:45 <jchia> I don't know. If I can somehow put String, Text and everything else in a type class, say Convert, and then be able to get a type ConvertTarget out of each Convert instance type, then I think I'm golden.
07:45 <jchia> Cale: Would that be type families?
07:45 <Cale> jchia: btw, version 0.0.9 of data-msgpack looks awful
07:45 <jle`> if it's for an exectuable, oprhan instances aren't too bad
07:45 <Cale> 0.0.8 looks more sensible
07:45 <halogenandtoast> Maybe I'm going about this the entirely wrong way. Any suggestions for creating a minesweeper board with random mines?
07:46 <jle`> it's when they are in libraries that you should try to avoid them
07:46 <halogenandtoast> That's the problem I'm trying to solve
07:46 <jchia> Cale: I haven't looked closely. What's wrong with it?
07:46 <Cale> https://hackage.haskell.org/package/data-msgpack-0.0.9
07:46 <Cale> https://hackage.haskell.org/package/data-msgpack-0.0.8
07:46 <Cale> They didn't expose most of the modules
07:46 <jle`> halogenandtoast: you can create `Rand g a` that generates a random tile, and then replicateM it or sequence it across all your tiles
07:46 <Cale> So you can't even write instances of the MessagePack class in 0.0.9, since the class itself isn't exported
07:47 mmn80 joined
07:47 <Cale> (That'll also be super annoying because you won't be able to write the type signatures of functions which are polymorphic with MessagePack constraints)
07:47 <halogenandtoast> jle`: What is Rand g a?
07:48 <halogenandtoast> Ah I think I found it: https://hackage.haskell.org/package/MonadRandom-0.1.3/docs/Control-Monad-Random.html#t:Rand
07:48 <jle`> halogenandtoast: a computation tha tproduces a random 'a', using seed of type g
07:48 <jchia> Cale: I think it's just a haddock problem. In the code, there's still Data.MessagePack.Class, which experts MessagePack
07:48 <jchia> 'exports'
07:48 <Cale> It's a cabal packaging problem
07:49 <jle`> s/a seed/seeds
07:49 <Cale> https://hackage.haskell.org/package/data-msgpack-0.0.9/src/data-msgpack.cabal
07:49 <Cale> Only 3 of the modules are listed under "exposed-modules"
07:49 <Cale> The others are still there, but not exposed.
07:49 <jchia> Cale: You're right, only three modules are exported with 'exposed-modules'. Data.MessagePack.Class is 'other-modules'
07:50 bollu joined
07:50 <jle`> halogenandtoast: Rand is a basic wrappver over the functionality of System.Random to give you the ability to sequence/compose random generation with your favorite functor/applicative/monad combinators like replicateM/traverse/mapM
07:51 <jchia> Cale: Maybe they just want to stick to the official MessagePack spec and prevent users from adding their own types.
07:52 <halogenandtoast> jle`: Seems neat, going to take me a bit to figure out how to use it
07:52 <jle`> halogenandtoast: gerAndom :: Rand g a
07:52 <halogenandtoast> I had been using the structure EmptyGame Int Int StdGen so I have a generator width and height packaged into 1
07:52 <jle`> so to get two random things, you can do (,) <$> getRandom <*> getRandom
07:52 <halogenandtoast> so I want to somehow do something like (getRandomR (0, height), getRandomR (0, width))
07:53 <jle`> to get a random three-ple, do x <- getRandom; y <- getRandom; z <- getRandom; return (x,y,z)
07:53 <jle`> a list of random things, replicateM 10 getRandom
07:53 <jle`> just your typical friendly neighborhood monadic interface :)
07:53 phyrex1an joined
07:54 tabaqui1 joined
07:54 <jennyrgb> what is a concrete type?
07:55 <jle`> depending on who you ask, it's a term that is 'considered harmful'
07:55 <jle`> because there is no accepted meaning
07:55 bollu joined
07:55 <jle`> it means whatever the person who is using it intends for it to mean
07:56 <Cale> I'll risk a definition: A concrete type is a type expression consisting entirely of type constructors and applications.
07:57 <opqdonut> of kind *?
07:57 <Cale> But I don't know if that's the sense that it got used in whatever it is that you're reading :)
07:57 <Cale> Not necessarily of kind *
07:57 <Cale> But maybe in some cases you'd want that too.
07:57 <jle`> so...a monomorphic type, you mean?
07:58 <Cale> It's a little more specific than that, since it has to do with the form in which the type is written.
07:58 laz joined
07:59 takle joined
08:00 <halogenandtoast> fg
08:00 <cocreature> I would have expected a concrete type to be the opposite of an abstract type
08:00 Salih joined
08:00 <cocreature> i.e. a type where the constructors are not hidden
08:00 <Cale> Oh, that's a completely different sense of the term, and maybe more deserving :)
08:01 ryxai joined
08:01 <cocreature> but I don’t think I’ve ever heard that term used so maybe it’s best to keep it that way :)
08:01 <cocreature> and use something like “monomorphic type” or other more specific terms
08:01 <jle`> some people use 'concrete type' mean 'fully saturated type', as in, non-*
08:02 <jle`> um, as in, *
08:02 <jle`> -kinded
08:02 <Cale> Well, a fully saturated type synonym might produce a type of kind other than *
08:02 bhiliyam joined
08:03 <quchen> type Foo = Monad
08:03 <quchen> Fully saturated, not kind *.
08:03 <jle`> so i guess, s/as in/or, alternatively
08:03 <Cale> Or less trivially perhaps, you can have stuff like type Foo a = State [a]
08:03 <monochrom> Oh hai quchen long time no see
08:03 <quchen> monochrom: Likewise!
08:03 biglama joined
08:04 <jle`> or even type Foo a = 5
08:04 <Cale> heh
08:04 Mysterious_Light joined
08:05 Yuras joined
08:06 jbiesnecker joined
08:06 SpaceGazebo3 joined
08:07 <jle`> someone should make a venn diagram of overlapping and mutually exclusive ways people use 'concrete type'
08:07 mattyw joined
08:08 <quchen> »inhabited type« should work fine in Haskell, but then people would start arguing about Void
08:09 <opqdonut> hmm
08:09 <opqdonut> [a] is also inhabited
08:09 <quchen> Clumsy as it sounds, »type of kind *« is probably as good as it gets
08:09 kosorith joined
08:09 <quchen> [a] has kind *
08:09 <opqdonut> right, in that sense
08:09 Beetny joined
08:09 <opqdonut> Cale had a definition that ruled out type variables, and that's the sense I've seen it used in
08:11 <quchen> Cale: Is (Int -> Int) a concrete type by your definition? I guess it depends on whether (->) is considered a constructor
08:12 augur joined
08:12 <opqdonut> why wouldn't it be a constructor?
08:12 <opqdonut> it just has funny syntax
08:12 <quchen> (->) is somewhat primitive
08:13 <monochrom> Then again, Int is somewhat primitive too.
08:13 <quchen> -> is primitiver ;-)
08:13 <opqdonut> if (Int -> Int) is not concrete, how about (Int,Int)?
08:13 <opqdonut> tuples are magic too
08:13 SimpleL joined
08:13 <quchen> Not really. They have their own syntax, but are not otherwise special.
08:14 augur joined
08:14 lep-delete joined
08:14 <quchen> monochrom: Can you define Int in terms of -> somehow?
08:14 Itkovian joined
08:14 <quchen> The other way round it’s not too hard (but fairly inefficient, using Boehm-Beraducci etc)
08:15 <monochrom> I don't know.
08:15 <monochrom> But you can define -> in terms of Int?!
08:15 <quchen> I don’t know
08:15 <quchen> Well, not Int, but maybe Nat?
08:16 mstruebing joined
08:16 bollu joined
08:16 <jle`> if you can define Nat then you can define Int
08:16 <quchen> If Gödel numbering is the simplest way I’ll count that as a »no« ;-)
08:16 <jle`> hehe
08:16 <monochrom> Then I think you have the order flipped. Boehm-Beraducci is when you define Nat in terms of ->
08:17 <lpaste> halogenandtoast pasted “Minesweeper.hs” at http://lpaste.net/354475
08:17 <halogenandtoast> jle`: I went with something like that
08:17 <halogenandtoast> I'm still not happy with it
08:17 <quchen> Oh yes, I flipped that sentence
08:17 <halogenandtoast> the instance bothers me
08:17 <halogenandtoast> But I don't get how to use MonadRandom here.
08:17 cchalmers joined
08:17 <halogenandtoast> since I'm not currently in a Monad
08:18 <jle`> you can use Rand to "build" your StdGen -> (a, StdGen)
08:18 <monochrom> -> in terms of Nat amounts to writing your own Haskell interpreter and you use Nat as your code format.
08:18 <monochrom> It can be done but I don't want to.
08:18 <halogenandtoast> jle`: my guess is that `a` is `Position` or `(Int, Int)`
08:19 <quchen> monochrom: Sorry, only constructive proofs allowed :-þ
08:19 Argue__ joined
08:19 <lpaste> jle` annotated “Minesweeper.hs” with “Minesweeper.hs (annotation)” at http://lpaste.net/354475#a354476
08:19 <jle`> but even better would be to make initGame a Rand
08:19 <monochrom> Because it reminds me of the nightmare of Dana Scott's "let's use the powerset of Nat to be the semantics of System F"
08:20 <halogenandtoast> jle`: but does that guarantee that the mines will be unique?
08:20 Mortomes|Work joined
08:20 <lpaste> jle` annotated “Minesweeper.hs” with “Minesweeper.hs (annotation) (annotation)” at http://lpaste.net/354475#a354477
08:20 <quchen> Speaking of constructive proofs: why are there infinitely many primes? Doesn’t this require showing how to construct a prime from a predecessor prime?
08:20 <jle`> halogenandtoast: it doesn't guaruntee it, but it makes it very very likely
08:21 <monochrom> Euclid's proof was not constructive, yes.
08:21 <quchen> Hm, I remember it’s easy to transform into a constructive one
08:21 <quchen> By showing that ab+c+d
08:21 <monochrom> (A dead horse beaten eternally by a crackpot in sci.math)
08:21 <quchen> Hah.
08:22 <lieven> it can be made constructive fairly easily. given n the largest prime so far, factorize n!+1 :)
08:22 ccomb joined
08:22 <monochrom> (He called himself Archimedes Plutonium.)
08:22 <jle`> halogenandtoast: that's how the Rand monad works
08:22 <quchen> Well, I guess the crux is realizing that the proof does not have to construct all primes in order, but to construct some ascending sequence
08:22 <jle`> halogenandtoast: replicateM 5 x will take 5 random samples from x
08:22 <lieven> or somewhat more practical, there's a primality test in P and a construtive proof of Bertrand's postulate
08:22 <halogenandtoast> jle`: So I would need to call evalRandT where I call initGame from?
08:22 <jle`> halogenandtoast: yes
08:23 <monochrom> shachaf may have written such a proof.
08:23 <halogenandtoast> I think that was what I was missing
08:23 <halogenandtoast> (probably among other things)
08:23 <jle`> halogenandtoast: you can also just "exit" immediately
08:23 <jle`> like what i wrote initially
08:23 <halogenandtoast> Right
08:23 <jle`> Rand & co. are just a way of building a StdGen -> (a, StdGen), but in nice ways
08:24 <halogenandtoast> Right, but wrapping the StdGen updates/returns
08:24 <halogenandtoast> I assume
08:24 <monochrom> I think lieven's idea works.
08:24 <halogenandtoast> s/but/by/
08:24 <jle`> halogenandtoast: yup, the key is in its Applicative instance
08:24 <jle`> at least for replicateM
08:24 <jle`> f <*> x will "run" f, then get the resulting generator, and then feed that to x
08:25 <jle`> and pop out that final generator at the end
08:25 <halogenandtoast> Yeah this is nice, and I think I better understand how to use it, but it doesn't seem like it would solve my problem, since I want to guarantee x unique mines.
08:25 <jle`> so it chains usages of the seed
08:25 <halogenandtoast> Still grateful for the explanation and example though!
08:25 <halogenandtoast> s/grateful/extremely grateful/
08:25 dhil joined
08:25 <jle`> halogenandtoast: it doesn't guaruntee x unique mines, it just generates 9 independently sampled mines
08:26 <halogenandtoast> Is there a way to generate infinite independently sampled mines?
08:27 <jle`> it depends on how you want to use it
08:27 marr joined
08:27 <halogenandtoast> take 9 $ nub $ <gen infinite list of random mines>
08:27 Speed09 joined
08:28 <jle`> i believe that evalRandT is lazy enough for that to work
08:29 biglama joined
08:29 <bollu> "let's use the powerset of Nat to be the semantics of System F" <- what?
08:29 cchalmers joined
08:29 <bollu> monochrom: enlighten me
08:29 <jle`> *evalRand
08:30 <jle`> halogenandtoast: yes, it works for me
08:30 <jle`> take 10 . nub $ evalRand (sequence getRandom) gen
08:31 <jle`> um, sequence (repeat getRandom)
08:31 <jle`> just don't try to get the resulting generator ;)
08:31 Salih_ joined
08:31 mkoenig joined
08:32 bjz joined
08:32 Ferdirand joined
08:33 oish joined
08:33 <halogenandtoast> jle`: I'll try it out, this problem was much harder than I imagined it to be.
08:33 bollu joined
08:33 ebzzry joined
08:33 Aruro joined
08:34 takle_ joined
08:34 MejGun joined
08:34 <jle`> halogenandtoast: alternatively, you might just want to shuffle the set of positions and take the first 9 items
08:35 <jle`> halogenandtoast: you can use uniform to shuffle
08:35 <jle`> and you can do it all inside Rand
08:35 bollu joined
08:36 kuribas joined
08:36 dhil joined
08:36 <lpaste> jle` annotated “Minesweeper.hs” with “Minesweeper.hs (annotation) (annotation) (annotation)” at http://lpaste.net/354475#a354478
08:37 zero_byte joined
08:38 bollu joined
08:38 <halogenandtoast> jle`: I'm assuming uniform doesn't ensure uniqueness either :p
08:38 <halogenandtoast> oh wait it will in this case.
08:38 <jle`> it shuffles a list
08:38 <halogenandtoast> right
08:39 <halogenandtoast> jle`: actually...
08:39 <halogenandtoast> uniform :: (MonadRandom m, Foldable t) => t a -> m a
08:39 <halogenandtoast> it returns a uniform element of the list, not a shuffled list
08:39 takle joined
08:40 <jle`> oh :o
08:40 beanbagula joined
08:40 <jle`> hm
08:40 <* monochrom> has a cunning plan to fix this! Build the list of all permutations. Uniformly pick one.
08:40 <halogenandtoast> I usually just write shuffle xs = map snd $ sortOn fst $ zip randomRs xs
08:40 <halogenandtoast> jle`: ^^
08:41 <halogenandtoast> well with a gen passed in
08:41 <jle`> yeah. it'd be neat if the module had a verison already
08:41 <halogenandtoast> jle`: There's https://hackage.haskell.org/package/random-shuffle-0.0.4/docs/System-Random-Shuffle.html
08:42 Fairy joined
08:42 rahulmutt joined
08:43 bollu joined
08:43 oish joined
08:44 <halogenandtoast> but I feel like my method is Good Enough™
08:44 LnL joined
08:44 acidjnk22 joined
08:44 Argue_ joined
08:45 a3Dman joined
08:45 mojjo joined
08:45 <jle`> it typechecks, so ship it
08:46 ali_bush joined
08:46 <Cale> quchen: It would be.
08:47 osa1 joined
08:47 osa1 joined
08:47 Iceland_jack joined
08:48 BartAdv joined
08:49 takle joined
08:50 Salih joined
08:52 CurryWurst joined
08:52 <halogenandtoast> jle`: thanks for all the help today, you're awesome!
08:53 <jle`> no problem!
08:53 <jle`> if you don't ever use any other randomness in the program, btw, then it's fine to just have initGame return not-in-Rand
08:53 mekeor joined
08:54 ali_bush joined
08:54 ali_bush joined
08:54 takle joined
08:55 cgfbee joined
08:55 <boxscape> I started using Lens.Simple today - can someone tell me why `zoom' only works with the strict version of StateT? Is this different in Control.Lens?
08:56 <boxscape> (I haven't used Control.Lens before either)
08:56 fotonzade joined
08:57 <Cale> It's not the case for Control.Lens
08:57 <Cale> But possibly that's one of the things which got simplified
08:57 <boxscape> ok, I see
08:58 lithie joined
08:58 <boxscape> most things in Lens.Simple regarding state just use MonadState
08:58 <Cale> Control.Lens has a Zoom type class which explains how the type of monad changes when you zoom
08:58 jhrcek joined
08:59 <boxscape> ok
08:59 yrdz` joined
09:00 Majiir joined
09:00 rahulmutt joined
09:01 path[l] joined
09:01 benl23 joined
09:03 bhiliyam joined
09:05 Ferdirand joined
09:06 oisdk joined
09:06 cpup joined
09:11 jeltsch joined
09:11 jgertm joined
09:12 mtesseract joined
09:14 Fairy joined
09:14 a3Dman joined
09:15 Itkovian joined
09:16 jaspervdj joined
09:16 bjz joined
09:17 <jennyrgb> Maybe is a type constructor. What does it return?
09:20 <Iceland_jack> (Maybe a) is a type for some type (a)
09:20 <Iceland_jack> The kind of Maybe: Maybe :: Type -> Type
09:20 Faucelme joined
09:21 locallycompact joined
09:21 <tdammers> if you will, Maybe takes a type and returns a type
09:22 Yuras joined
09:22 hdeshev joined
09:22 <tdammers> * -> *
09:24 <Iceland_jack> jennyrgb: It may help to look at the kind of Either as well (Either :: Type -> Type -> Type), I write 'Type' instead of '*' but they mean the same
09:24 <Iceland_jack> Partially applying the Either type constructor to Int gives us (Either Int) of kind (Either Int :: Type -> Type)
09:25 IndigoTiger_ joined
09:26 <jle`> jennyrgb: and applying 'Maybe' to 'Int' gives you 'Maybe Int'
09:27 <Iceland_jack> @kind Int
09:27 <lambdabot> *
09:27 <Iceland_jack> @kind Maybe
09:27 <lambdabot> * -> *
09:27 <Iceland_jack> @kind Maybe Int
09:27 <lambdabot> *
09:28 bennofs joined
09:29 oish joined
09:30 beknowly joined
09:30 <jennyrgb> god damn it.. I used baking soda instead of vanilla sugar powder, this taste like shit!
09:32 takle joined
09:33 <halogenandtoast> jennyrgb: I have that problem with Monads all the time.
09:33 <ongy> typesafe baking?
09:33 <geekosaur> one could only wish...
09:34 <halogenandtoast> That would definitely keep my wife from making non-sensical substitutions
09:34 <halogenandtoast> e.g. using coconut flour instead of flour when baking things that depend on chemical reactions.
09:34 <ongy> I wonder if indexed monads would be a good way to model this
09:35 <halogenandtoast> I actually work for a recipe sharing website, if we could make this a thing...
09:35 <* geekosaur> tries to use differently shaped containers, pattern matching seems to work well enough as a "type system"
09:35 feynhat joined
09:35 Ferdirand joined
09:35 <geekosaur> shape+size
09:35 merijn joined
09:35 bl0w3d_0ut joined
09:35 <geekosaur> but wht works for me doesn't always work for others...
09:35 <ongy> so your recipies are cut out boards with the right holes?
09:36 <geekosaur> just the ingredients. I substitute a lot, but deliberately (typeclasses?)
09:38 <halogenandtoast> geekosaur: yes typeclasses
09:38 <halogenandtoast> I am the highest authority for answering that question.
09:38 <jennyrgb> I am god, I have the ultimate authority
09:39 <geekosaur> well, not quite, unless you want to use a dependently-kinded system :) some things just should not be mixed, however well they might substitute individually
09:40 <halogenandtoast> geekosaur: the answer is more typeclasses
09:40 osa1 joined
09:40 <halogenandtoast> class CanBeMixedWithFlour where
09:41 <halogenandtoast> Just remember, with the correct encoding we can represent the current state of the universe in a single bit...
09:41 Swizec joined
09:42 Swizec joined
09:42 <Iceland_jack> jennyrgb: Protip, only make lemon cheesecakes
09:42 <Iceland_jack> they are delicious
09:42 alx741_ joined
09:42 <tdammers> If the first bit is 0, then the message represents the single test case; if it is 1, then the remaining bits encode some other case that is not the test case
09:43 Swizec joined
09:43 Swizec joined
09:44 Swizec joined
09:46 mzf joined
09:47 psychicist__ joined
09:47 <ongy> a testcase of the universe?
09:47 <tdammers> yes
09:47 <tdammers> of course
09:47 Miroboru joined
09:48 bollu joined
09:50 takle joined
09:52 bollu joined
09:53 mzf joined
09:54 kay joined
09:54 silver joined
09:56 MindlessDrone joined
09:58 bollu joined
09:58 rcschm joined
10:01 mzf joined
10:01 bollu joined
10:01 Itkovian joined
10:01 takuan joined
10:04 bhiliyam joined
10:07 mzf joined
10:08 Ferdirand joined
10:11 doomlord joined
10:12 suppi joined
10:13 Aruro joined
10:15 jhrcek_ joined
10:16 mmn80 joined
10:17 ragepanda joined
10:17 gabluc joined
10:17 CurryWurst joined
10:25 Aruro joined
10:26 wroathe joined
10:28 revprez_atlanta joined
10:28 eacameron joined
10:29 splanch joined
10:30 redpoppies joined
10:31 mzf joined
10:32 elvisren joined
10:32 unK_ joined
10:34 teggi_ joined
10:35 blocus joined
10:35 <elvisren> I have a question on the behaviour of "bracket" in Control.Exception. from the definition I think the "after a" will be called twice when "thing a" raises exception. But when I write test code it is called only once. Is there anything special I have overlooked? the function definition is here: http://hackage.haskell.org/package/base-
10:35 mzf joined
10:38 stphrolland joined
10:39 Ferdirand joined
10:40 <merijn> elvisren: After is not called twice, because onException doesn't stop the exception, it rethrows after running the handler
10:41 LnL joined
10:41 <merijn> elvisren: So either it throws, the handler from onException runs and the 2nd sequel is skipped. Or there's no exception and only the 2nd one runs
10:42 <elvisren> #
10:44 <jennyrgb> 1 + f a b, how's the precidence working here?
10:44 <merijn> jennyrgb: 1 + ((f a) b)
10:44 <jennyrgb> precedence*
10:44 <merijn> jennyrgb: Function application has higher precedence than ALL operators
10:44 cchalmers joined
10:45 bl0w3d_0ut joined
10:45 <Iceland_jack> (f x + g y) becomes : (f x) + (g y)
10:46 <jennyrgb> ok thanks :)
10:46 cschneid_ joined
10:46 <jennyrgb> what about f1 f2 a b, is f1 getting f2 as an argument, or is the return of (f2 a b) an argument of f1?
10:47 <merijn> Function application is left associative, so: "((f1 f2) a) b"
10:47 <Iceland_jack> It's left associative, so ((f1 f2) a) b
10:47 <Iceland_jack> so the first argument to f1 is f2
10:47 <Iceland_jack> > ((+) 10) 5000
10:47 <lambdabot> 5010
10:48 quinor joined
10:48 <jennyrgb> ok ty
10:48 Lord_of_Life joined
10:48 <quinor> hey, quick question: why isn't next_id :: MonadState (Sequence.Seq a) m => m Int valid type signature?
10:49 <quinor> (I import qualified Data.Sequence)
10:49 nighty-- joined
10:49 <Iceland_jack> Do you have FlexibleContexts on?
10:49 <Iceland_jack> Enabled in GHCi: (>>> :set -XFlexibleContexts)
10:50 <Iceland_jack> :t undefined :: MonadState [a] m => m Int
10:50 <lambdabot> MonadState [a] m => m Int
10:50 Aruro joined
10:50 MindlessDrone joined
10:50 <quinor> Iceland_jack: nope, should I? Can I enable it by source macroes? Or somehow in ghci?
10:51 <Iceland_jack> in GHCi you enable it with the command (:set -XFlexibleContexts)
10:51 <quinor> thanks!
10:51 <Iceland_jack> in a source file you enable it by adding {-# Language FlexibleContexts #-} to the TOP of your file
10:51 <elvisren> merijn: thanks for the explanation. I scan the doc again. It looks the document need to be improved. "bracket" use "onException", and "onException" is documented using "finally", which is documented using "bracket". for all these three functions, only "bracket" mentioned re-thrown exception, so it is a little confusing.
10:52 <Iceland_jack> The error message should tell you to enable the FlexibleContexts extension
10:52 <Iceland_jack> something else may be amiss
10:52 <Iceland_jack> who knows
10:52 <* Iceland_jack> starts drinking
10:52 <quinor> Iceland_jack: thank you VERY much!
10:53 <Iceland_jack> You're very welcome :)
10:54 <quinor> Iceland_jack: it did tell me to do that btw, but it did so on a couple of other ocasions when it was totally wrog so I thought it'll be better to ask
10:55 <merijn> elvisren: the bracket docs already say that it 1) frees the resource and 2) reraises exceptions, no? So the only reason people would get confused is if they look at the source, without looking at any other bit of the source, like onException
10:56 Kuros joined
10:56 <geekosaur> quinor, part of the reason it's an extension is because it can indicate a bug in your type. (and part is that the people who designed Haskell wanted to make it easier to implement. although ghc as the de facto reference implementation kinda clobbers that...)
10:57 <quinor> can I turn it on for a _single_ declaration?
10:57 kosorith joined
10:57 <merijn> geekosaur: I think it's mostly just "Haskell report forgot to specify"
10:57 <merijn> geekosaur: Because I remember Cale telling me that GHC allowed FlexibleContexts for years before someone pointed out the report didn't allow it
10:57 mzf joined
10:59 Aruro joined
11:01 <Cale> The Haskell report does specify that restriction, from what I recall. It's just that GHC didn't explicitly check it.
11:01 jeltsch joined
11:02 danza joined
11:02 <jennyrgb> data Triggered = Triggered {amount::Int, what::String} what is this?
11:02 JagaJaga joined
11:02 <Maxdamantus> jennyrgb: a record type.
11:04 <merijn> Cale: Yeah, I know the report specifies it, I meant that "no one working on GHC even realised the report was that restrictive"
11:05 bhiliyam joined
11:09 Croniamental joined
11:11 Ferdirand joined
11:11 <stphrolland> I'm starting with Pipes. A bit lost between tutorials available on the net and documentation. This is the code I have so far which cannot compile, lots of compilation errors I don't understand. The line that don't compile is line 19, runEffect $ ... http://lpaste.net/354479
11:11 <stphrolland> What I want to achieve: a handler that receives Command object and outputs Command object. There will be some IO side effect performed, but for the moment if it only returns the incomming command as is, it would be sufficient for my understanding better the Pipes / Pipes.Network / Pipes.Binary libs.
11:12 <stphrolland> How would you write the runEffect line I whave written wrongly.
11:12 aditsu left
11:14 wroathe joined
11:15 mtesseract joined
11:15 cpennington joined
11:16 nagyf joined
11:18 nick_h joined
11:18 Wuzzy joined
11:19 ragepanda joined
11:19 zcourts joined
11:21 <Cale> stphrolland: It might help if you add the error to your paste
11:21 edsko_ joined
11:23 <Cale> stphrolland: Are you sure you don't want fromSocket rather than recv?
11:24 <stphrolland> I have updated the paste with compilation errors: http://lpaste.net/354479
11:24 <Cale> Try using fromSocket instead of recv
11:26 hurkan joined
11:26 Aruro joined
11:26 <stphrolland> okay, I'm gonna search for it on hackage
11:26 Itkovian joined
11:26 <Cale> https://hackage.haskell.org/package/pipes-network-
11:26 <Cale> How did you write the code which you have? :)
11:27 takle_ joined
11:27 <stphrolland> From my partial understanding of the docs and the tutorial I found.
11:27 <Cale> ah, okay
11:27 hrehf joined
11:27 jgt2 joined
11:28 <Cale> Well, I think you probably want fromSocket and toSocket, which get you a Producer and Consumer respectively
11:28 wroathe joined
11:29 <Cale> You can send and recv inside the action given to runEffect, but they only do what they normally do in IO, get a single chunk of data
11:29 <Cale> (or send it)
11:30 <Cale> You could, for instance, write
11:30 xtreak joined
11:30 <Cale> do x <- PNT.recv connectionSocket pageSize; runEffect $ yield x >-> ...
11:30 <Cale> er
11:30 <Cale> that's not what I meant to write
11:31 <Cale> runEffect $ do x <- PNT.recv connectionSocket pageSize; yield x >-> ...
11:31 <Cale> yeah
11:31 <Cale> However, that would only get the one chunk and ship that along
11:31 <Cale> So you really probably want fromSocket, which will get many chunks
11:31 <Cale> https://hackage.haskell.org/package/pipes-network-
11:31 <Cale> It might be helpful to look at its implementation in terms of recv
11:32 fakenerd joined
11:32 <stphrolland> I have updated with fromSOcket in the code. Same kind of compilation errors. http://lpaste.net/354479
11:32 <Cale> It's just a loop which repeatedly runs recv, and yields the resulting chunk of bytes, until it doesn't get any more.
11:33 ziocroc joined
11:33 <Cale> ah I see
11:33 <Cale> Well, look at the type of decode from Pipes.Binary
11:33 <stphrolland> What seems to be blocking first here, is the encode/decode stage from ByteString to Command. noe ?
11:33 <Cale> decode :: (Monad m, Binary a) => Parser ByteString m (Either DecodingError a)
11:34 <Cale> It's apparently something called a Parser
11:34 <Cale> https://hackage.haskell.org/package/pipes-parse-3.0.4/docs/Pipes-Parse.html#t:Parser -- the Parser type is defined using StateT
11:35 <Cale> https://hackage.haskell.org/package/pipes-parse-3.0.8/docs/Pipes-Parse.html#v:parsed
11:35 cur8or joined
11:35 <Cale> is apparently how we run such a Parser
11:35 <Unhammer> Pied Parser
11:35 <stphrolland> okay, that makes sense
11:35 <Cale> parsed :: Monad m => Parser a m (Either e b) -> Producer a m r -> Producer b m (e, Producer a m r)
11:36 <Cale> So we give it decode, and the Producer we'd like to consume data from, and it gives us a Producer for the parsed values.
11:37 <Cale> So something like parsed PipesBinary.decode (PNT.fromSocket connectionSocket pageSize)
11:39 wroathe joined
11:40 <boxscape> "The function `zoom' is applied to three arguments, but its type has only four" good job ghc -.-
11:40 <Cale> hah
11:41 harfangk joined
11:41 <Cale> Yeah, sometimes it messes up that error message a bit.
11:41 <opqdonut> hey who ate my curry?
11:41 <opqdonut> :)
11:45 slacker joined
11:45 ebzzry joined
11:47 xtreak joined
11:49 Lord_of_Life joined
11:50 sdothum joined
11:50 <ertes> boxscape: it didn't say which order it was using
11:50 AndreasK joined
11:51 <boxscape> ertes: I'm not sure what you mean by that
11:52 <ertes> > Down 4 < Down 3
11:52 <lambdabot> True
11:52 <boxscape> ah, yeah...
11:53 <ertes> but my favourite GHC bug is still the one that deleted your source file when you had a type error
11:53 phaji joined
11:53 <boxscape> :D
11:53 fizbin joined
11:54 <boxscape> I'm almost surprised that can even happen, given that files can be opened in different modes
11:54 <boxscape> seems like the sort of thing that haskell would be good at preventing
11:55 <ertes> Blah.hs:50:4: error: You suck. Try again from the top, idiot!
11:56 asmyers joined
11:56 <ertes> i don't know how it happened… i'm guessing that it picked the wrong file for some reason
11:57 JagaJaga_ joined
11:58 theelous3 joined
11:58 Gurkenglas joined
11:58 <Iceland_jack> > sortOn Down "Hello!"
11:58 <lambdabot> "olleH!"
11:59 <jennyrgb> what exactly is one higher order function?
11:59 <ertes> @src sortOn
11:59 <lambdabot> Source not found. Maybe you made a typo?
11:59 <Iceland_jack> sortOn f = sortBy (comparing f)
11:59 <boxscape> jennyrgb: a function that either takes a function as an argument or returns a function
11:59 <ertes> lambdabot: you're surprisingly nice today
11:59 <boxscape> @src sortOn
11:59 <lambdabot> Source not found. Are you on drugs?
12:00 <boxscape> there we go
12:00 coot joined
12:00 <ertes> yeah, tsunderebot is back
12:00 <Iceland_jack> Behave lambdabot
12:00 stoopkid joined
12:01 geekosaur joined
12:01 jennyrgb joined
12:01 nh2 joined
12:02 biglama joined
12:02 <Cale> We can define the order of non-function types to be 0, and then the order of a -> b is max (1 + order of a) (order of b). A function is higher order when its order is at least 2.
12:02 HoierM joined
12:03 jennyrgb joined
12:03 <ertes> Cale: order of id?
12:03 <ertes> i can only see that working on monomorphic functions
12:03 <Cale> Doesn't work out on polytypes, right.
12:03 <Cale> huh, k-lined
12:03 <ertes> yeah, a few times
12:04 <ertes> not sure why
12:04 jennyrgb joined
12:04 teggi joined
12:04 <ertes> probably because of tor
12:04 <ertes> someone else might be abusive
12:04 <Cale> jennyrgb: We can define the order of non-function types to be 0, and then the order of a -> b is max (1 + order of a) (order of b). A function is higher order when its order is at least 2.
12:04 <jennyrgb> ertes: I said nigger in a channel
12:04 phaji joined
12:04 <ertes> ah
12:04 <jennyrgb> ertes: got klined
12:04 takle joined
12:04 <ertes> well, yeah, not surprising =)
12:05 <jennyrgb> ertes: yeah, lots of feminists on this network
12:05 mmhat joined
12:05 <ertes> let's return to the topic of haskell though
12:06 bhiliyam joined
12:06 <Cale> As ertes points out, this doesn't necessarily produce a definite result for polymorphic functions
12:07 eacameron joined
12:07 <boxscape> not necessarily? Is there an example where it does?
12:07 jennyrgb joined
12:07 <Cale> Int -> Maybe a
12:07 <ertes> boxscape: i can come up with examples using DataKinds
12:08 <ertes> or that =)
12:08 jennyrgb joined
12:08 <boxscape> ah, so even if you have Int -> Maybe (Int -> Int) it's still just order 1?
12:08 <Cale> Then again, I think just disregarding the forall would be sensible enough.
12:08 <Cale> yeah
12:08 <boxscape> ok
12:08 <Cale> So that id would be order 1
12:09 <Cale> and map would be order 2
12:09 <jennygbr> brb, think I need to ban evade
12:09 Mysterious_Light joined
12:09 <ertes> also i was wrong… i can't come up with examples using DataKinds, because:
12:09 <ertes> :k (->)
12:09 <lambdabot> * -> * -> *
12:10 shayan_ joined
12:10 <ertes> @let class Blah (a :: Bool); instance Blah False; instance Blah True -- that was the idea
12:10 lavalike joined
12:10 <lambdabot> Defined.
12:10 wroathe joined
12:10 <ertes> but * is too large
12:10 <boxscape> I haven't looked into DataKinds and related things.. I should do that
12:11 <ertes> boxscape: the more features GHC gets, the more desparate i get… we're so close to dependent types, yet so far away =)
12:12 <ertes> TypeInType is the latest and so far greatest depression extension
12:12 <boxscape> so is it likely that ghc will ever get fully dependent types?
12:12 <merijn> boxscape: Magic 8ball says: Maybe.
12:12 mkoenig_ joined
12:13 <boxscape> sounds... somewhat promising
12:13 <Philonous> You can already simulate dependently typed programs with singletons.
12:13 <ertes> i'm pretty sure the first revision of dependent types is going to be useless
12:14 xificurC joined
12:14 <ertes> "here you are: dependent types… BUT…"
12:15 <Cale> Making Haskell into a *good* language for dependently typed programming is going to be even harder than just technically supporting dependent types too. The fact that terms and types live and have lived in separate namespaces for so long is going to make it painful.
12:15 sz0 joined
12:15 <ertes> exactly
12:15 splanch joined
12:16 <ertes> it's the usual retrofitting problem… i'm very glad that GHC came with an interpreter early on
12:16 <ertes> otherwise we would have the same dilemma most language implementations have: making code work in both the interpreter and the compiler would be painful
12:18 shutdown_-h_now joined
12:18 <Cale> I'm surprised there doesn't appear to be at least someone interested in building a dependently typed language with lazy evaluation by default.
12:18 <ertes> for some reason most people think of lazy-by-default as a mistake
12:19 <ertes> (FWIW i disagree)
12:19 <fizbin> Is there a well-known, tuned datastructure that can serve as a (Map IntSet Int) replacement ? I've got profiling data telling me that 10% of my runtime and 17% of my alloc comes from a single M.lookup call that returns Nothing about 11% of the time. (And after returning Nothing, the map is then modified)
12:19 <Cale> Depending on who "people" includes, I'm not sure
12:19 <ertes> s/think/seem to think/
12:20 <ertes> fizbin: HashMap Integer Int
12:20 <ertes> fizbin: IntSet is basically a bit-field
12:20 <Cale> btw, HashMap doesn't seem to be safe in concurrent programs
12:20 Salih joined
12:20 wroathe joined
12:21 pavonia joined
12:21 <ertes> maybe IntSet has a Hashable instance itself
12:21 <ertes> Cale: hmm?
12:21 <fizbin> Cale: meaning that it's unsafe to access from multiple threads a single HashMap, or that even multiple threads each with their own HashMap run into issues?
12:21 <Cale> There was a guy in here the other day with a program which produced different results every time you ran it for no other reason than that it was using parallel sparks and HashMap
12:21 <ertes> weird
12:21 Lord_of_Life joined
12:22 takle joined
12:22 <mniip> was there a bug report
12:22 <ertes> HashMap doesn't have any unsafe hacks, as far as i can tell… sounds like a GHC bug
12:22 <Cale> HashMap has tons of unsafe hacks in it
12:23 <fizbin> ertes: I'll need to do some minor adjustment to make my IntSets use only numbers >= 0 in a contiguous block, but I should do those adjustments anyway.
12:23 <Cale> insert uses reallyUnsafePtrEquality# three times
12:23 obadz joined
12:23 bungoman joined
12:23 <fizbin> Then I have to worry about paying the IntSet -> Integer cost on each lookup.
12:24 <fizbin> But maybe I can work out the rest of this function to use Integers where it's currently using IntSets.
12:24 <ertes> oh, indeed
12:25 <ertes> fizbin: if your bit-field is sparse, you can probably use something more compact
12:25 <ertes> fizbin: like unboxed Vector Int
12:25 <ertes> but make sure it's sorted
12:25 <Cale> mniip: I'm not sure if there was or not
12:26 <Cale> https://github.com/tibbe/unordered-containers/issues/147
12:26 <Cale> ah here
12:26 initiumdoeslinux joined
12:26 xtreak joined
12:26 anuxivm joined
12:28 <fizbin> ertes: It sounds like I need to collect some more data on how large, on average, my IntSets are.
12:28 <ertes> fizbin: the size doesn't matter as much as the density
12:28 <fizbin> Because I don't actually have a good a priori reason to believe they'll be sparse, or one to believe that they won't.
12:28 <Cale> I went through and replaced the uses of HashMap with Map instead on a hunch, and the program ran about 2% slower, but no longer exhibited the weird random results.
12:29 <Cale> So we decided it had to be HashMap's fault, but it's very unclear exactly why
12:29 <ertes> also Integer is *far* more compact than IntSet
12:29 <ertes> in exchange for more expensive operations, of course
12:30 wroathe joined
12:31 <ertes> if your bit-fields are very sparse (only 1/64th of all bits set on 64-bit platforms), Vector Word is going to be even more compact
12:31 <ertes> uh
12:32 <ertes> Vector Int
12:32 <Athas> Cale: I think hashmap uses a random hash seed.
12:32 <boxscape> ugh, on one hand, "cpuReg r = cpu.registers.register r" looks like it should be super straightforward to eta-reduce, on the other hand, the pointfree style version looks horrible
12:32 <Athas> Things like HashMap.toList can certainly give different results depending on OS and compiler.
12:33 _sg joined
12:33 <ertes> fizbin: if you invest some engineering cost, you can even get the best of both: run-length encoding with the option to have dense bit-fields in the middle
12:33 <merijn> boxscape: Why's that? looks fine to me?
12:33 <boxscape> merijn: the pointfree version? because I want to keep the imperative-like cpu.registers.register
12:33 Kreest__ joined
12:33 <merijn> boxscape: That looks fine without the 'r' to me?
12:33 xall joined
12:34 <boxscape> @pl cpuReg r = cpu.registers.register r
12:34 <lambdabot> cpuReg = ((cpu . registers) .) . register
12:34 takle joined
12:34 <merijn> oh, wait
12:34 <merijn> I misparsed that :)
12:34 <Axman6> yeah that's gross
12:34 <ertes> looks like lens style
12:34 <boxscape> that's easy to misparse
12:34 <boxscape> yeah, it's lens style
12:34 <ertes> that's why i don't use lens style, even with lenses =)
12:35 <boxscape> I only started using lenses today, I can't stop using lens style yet
12:35 <ertes> look at it this way: you're not doing OO, so stop pretending you are ;)
12:35 <Cale> Athas: If that's observable within a single run of the program, that's terrible.
12:35 <boxscape> you do have a point
12:36 <Cale> Athas: But I don't think it's just that.
12:37 <Axman6> I think that characterising lens as just a way to get OO syntax in haskell does lens a huge disservice
12:38 <fizbin> @type (:.)
12:38 <lambdabot> error:
12:38 <lambdabot> • Data constructor not in scope: :.
12:38 <lambdabot> • Perhaps you meant one of these:
12:38 <Axman6> :t (.:)
12:38 <lambdabot> error:
12:38 <lambdabot> • Variable not in scope: .:
12:38 <lambdabot> • Perhaps you meant one of these:
12:38 <Axman6> :(
12:38 <Athas> Cale: I haven't seen it vary within a single run before.
12:40 RoyalNightGuard joined
12:40 <fizbin> ISTR seeing something like .: used to mean f .: g = (f .) . g
12:41 takle_ joined
12:41 wroathe joined
12:41 <fizbin> And if that definition were in place, then boxscape's function could be written cpu . registers .: register
12:42 RoyalNightGuard left
12:42 <boxscape> :t (f .) . g -- interesting that :t requires Show for some things
12:42 <lambdabot> error:
12:42 <lambdabot> • Could not deduce (Show b0) arising from a use of ‘f’
12:42 <lambdabot> from the context: (FromExpr c, Show a, Show a1)
12:42 <boxscape> at least, I think that's what's happening
12:42 <boxscape> fizbin: that does look alright
12:43 <fizbin> @type let f .: g = (f .) . g in (.:)
12:43 <lambdabot> (b -> c) -> (a1 -> a -> b) -> a1 -> a -> c
12:43 <merijn> boxscape: It's because you're using f and g :)
12:43 <merijn> :t f
12:43 <lambdabot> FromExpr a => a
12:43 nkhodyunya joined
12:43 <fizbin> :t \f g -> (f .) . g
12:43 <boxscape> right... but it's still not obvious to me how that leads to a Show constraint
12:43 <lambdabot> (b -> c) -> (a1 -> a -> b) -> a1 -> a -> c
12:43 goergen joined
12:43 RoyalNightGuard joined
12:43 <merijn> boxscape: Those are defined in lambdabot as a result simple-reflect
12:44 <merijn> boxscape: Because FromExpr expects functions to be applied to showable things
12:44 <merijn> It's how you can do neat things like:
12:44 <boxscape> ah, ok
12:44 <merijn> > foldr f z [a,b,c]
12:44 <fizbin> I just can't remember the name of the library that defined combinators like (.:), and Hoogle doesn't have it.
12:44 <lambdabot> f a (f b (f c z))
12:44 mda1 joined
12:45 <boxscape> yeah, simple-reflect is neat
12:45 ebzzry joined
12:46 gabluc joined
12:46 <boxscape> fizbin: there are a few results in hayoo
12:47 <boxscape> like custom-prelude and Sound.SC3
12:47 Ferdirand joined
12:47 acarrico joined
12:47 harfangk joined
12:48 <boxscape> at least I think that's the same function
12:48 <boxscape> :t (.) . (.)
12:48 <lambdabot> (b -> c) -> (a1 -> a -> b) -> a1 -> a -> c
12:48 <boxscape> looks good
12:48 <fizbin> Yeah, .: from custom-prelude is what I was remembering.
12:49 <fizbin> Lots of names for it: https://hayoo.fh-wedel.de/?query=%28c-%3Ed%29-%3E%28a-%3Eb-%3Ec%29-%3Ea-%3Eb-%3Ed
12:50 takle joined
12:51 wroathe joined
12:52 bennofs joined
12:54 oconnorct1 joined
12:56 juhp joined
12:57 gabluc joined
12:57 jeltsch joined
12:57 yellowj joined
12:57 dsh joined
12:57 gabluc joined
13:00 eklavya joined
13:00 HoierM joined
13:00 rcschm joined
13:02 ptek joined
13:03 <fizbin> How does one use an inorder operator from a module imported qualified again? I'm trying to say (mp `IM.!`) but that's a syntax error. Every combination of parens I can think of around that is also a syntax error.
13:03 dhil joined
13:04 cmn left
13:05 <lep-delete> a Mod.! b
13:06 <joe9> any one knows of a package to derive default values using GHC.Generics?
13:06 <fizbin> Oh. So my issue was too much syntax. Ok.
13:06 <lep-delete> :)
13:06 bhiliyam joined
13:06 <ertes> joe9: data-default supports that
13:07 takle_ joined
13:07 <joe9> ertes: Thanks.
13:07 <ertes> joe9: just derive Generic for your type and write an empty instance
13:07 <ertes> and i wish people would stop that horrible habit of completely hiding internals
13:08 <ertes> there is no reason to hide the GDefault class
13:08 <joe9> ok, will try that. yes, the docs are not that helpful https://hackage.haskell.org/package/data-default-
13:08 <ertes> joe9: for some reason it's only exported from the dependent pacakge data-default-class
13:08 Argue__ joined
13:08 <ertes> and only incompletely
13:10 mtesseract joined
13:10 Wizek_ joined
13:11 wroathe joined
13:12 dfeuer joined
13:12 <lyxia> joe9: if your type is an instance of Generic, just try an empty instance. if it typechecks you can use "def" as a default value of that type.
13:12 iAmerikan joined
13:13 dan_f joined
13:15 <joe9> lyxia: Thanks, got it.
13:15 splanch_ joined
13:15 <joe9> lyxia: btw, are you the author of generic-random?
13:16 Wizek_ joined
13:16 wei2912 joined
13:17 kthnnlg joined
13:18 ChristopherBurg joined
13:18 meba joined
13:18 netheranthem joined
13:18 revprez_atlanta joined
13:18 goergen joined
13:19 jeltsch joined
13:19 <lyxia> yeah
13:19 takle joined
13:21 <joe9> lyxia: Thanks for sharing the package . This is how I am using it. http://dpaste.com/12JHKV3 . If you do not mind me asking, Is there a way to just derive the instance? Instead of writing the instance manually?
13:22 hrehf joined
13:22 <joe9> lyxia: I have a bunch of types where the types are just simple non-recursive data types and I want to use a sane default that works both for recursive and non-recursive data types.
13:22 <lyxia> you can just use genericArbitrary for non-recursive types
13:22 <joe9> got your package after reading this https://byorgey.wordpress.com/2016/09/20/the-generic-random-library-part-1-simple-generic-arbitrary-instances/
13:23 <lyxia> and I don't think you can avoid writing the instance
13:24 <joe9> lyxia: I would rather use this arbitrary = genericArbitrary' (S Z) uniform and not worry about changing it for recursive and non-recursive data types. From the docs, I gather that it is a sane default.
13:25 jathan joined
13:25 <lyxia> As a matter of principle, there isn't a good universal instance to be derived, so I think it would be a bad idea to make Arbitrary derivable.
13:25 <lyxia> okay sure.
13:26 mizu_no_oto_work joined
13:26 <joe9> your logic makes sense, making the user think about it before using it. If not for that, I wish this genericArbitrary' (S Z) Uniform could be a default method for the class.
13:26 <lyxia> "make Arbitrary derivable" means adding a default implementation as part of its definition in QuickCheck.
13:27 ludat joined
13:27 <joe9> then, I could just say deriving (Eq, Show, Arbitrary) and be done with it.
13:27 <lyxia> that's precisely what I'm arguing against
13:27 stphrolland joined
13:28 <ertes> lyxia: interesting package… i think it's possible to derive uniform weights automatically though
13:28 <joe9> lyxia: You are the expert on this and if you have strong feelings about it, I will go with that.
13:28 mohsen_ joined
13:29 <ertes> lyxia: for sum types i mean
13:29 <joe9> lyxia: from a dumb user perspective, the alternative is easier/saner.
13:29 <ertes> let me try something
13:29 <lyxia> ertes: am I not doing that
13:29 <ertes> hmm? maybe i overlooked something
13:29 <lyxia> I have "uniform" defined!
13:30 <joe9> lyxia: but, that is not a sane choice across all datatypes.
13:30 <stphrolland> Hi, this morning I was asking about Pipes, and PIpes.Network. Things got better. But now I still cannot figure out what the type of my handler should be. I would like the handler to accept C.Command, and to output C.Command. I have tried without providing anytype signature, so as GHC tells me what it awaits... but no success: here's the code http://lpaste.net/354479 the usage of handler would be a line 19. Any what it shou
13:31 <ertes> lyxia: oh, you have
13:31 <lyxia> joe9: adding a default implementation to Arbitrary is not my call though :)
13:31 jship joined
13:31 chlong joined
13:32 wroathe joined
13:33 <joe9> lyxia: agreed. Thanks again for sharing the generic-random. made me avoid writing so many arbitrary instances.
13:33 eschnett joined
13:33 kosorith joined
13:33 warlock joined
13:35 <lyxia> Now that I think about it, for product type the default doesn't seem as controversial to me.
13:35 <lyxia> So maybe the default implementation could work with just that.
13:36 ziocroc joined
13:38 <joe9> lyxia: why not provide: genericArbitrary = genericArbitrary' (S Z) Uniform ?
13:38 <joe9> I could not find a genericArbitrary as described in the byorgey's article.
13:38 <joe9> lyxia: I presumed that it was removed as versions incremented.
13:39 <ertes> stphrolland: your 'handler' is not a function
13:39 <ertes> it's a Pipe that needs to use 'await' and 'yield' (or an abstraction of them like 'map' from Pipes.Prelude)
13:39 <stphrolland> understood, it should be a Pipe, but I don't know how to define it
13:39 <ertes> stphrolland: first write a type siganture
13:40 <stphrolland> map seems to be good, I want to transform incomming C.Command s
13:40 <ertes> stphrolland: handler :: (Monad m) => Pipe A B m r
13:40 <lyxia> joe9: yeah I did an update since Brent wrote that.
13:40 <ertes> replace A and B by the input type and B by the output type
13:40 <ertes> s/and B/
13:40 <ertes> /
13:41 <joe9> lyxia: sure, that is what I assumed. the name genericArbitrary is more intuitive. I wish you could provide it, please?
13:41 mada joined
13:41 ystael joined
13:41 earldouglas joined
13:41 <lyxia> joe9: I just didn't figure that it would be such a useful pattern, I can certainly add it!
13:42 <ertes> stphrolland: if you want to write a regular function, you can also use this pattern: … >-> P.map handler >-> …
13:42 <ertes> 'handler' is not a good name in either case
13:42 <stphrolland> how would you call it ?
13:42 <ertes> depends on what it is
13:42 jbiesnecker joined
13:42 yellowj joined
13:42 <stphrolland> it receives commands from a client, and returns another command
13:43 <ertes> that's not quite enough information to figure out a good name
13:43 <stphrolland> performs some IO action on the server side at the same time
13:43 <ertes> if it does that, you can't use 'map', but you need 'mapM'
13:43 <stphrolland> okay, I will try to firgure a better name :-)
13:43 <joe9> lyxia: Thanks a lot. if genericArbitrary' (S Z) Uniform is a sane choice, then exposing it as genericArbitrary would have saved some time while trying to use/understand the package. Also, using genericArbitrary' (S Z) Uniform makes it seem that I am doing something not usual or different from a sanely accepted function.
13:43 mazeinmaze_ joined
13:43 <ertes> and its type changes, too: handlerOrWhatever :: (MonadIO m) => Pipe Command Command m r
13:44 <phz_> hey folks
13:44 hrehf_ joined
13:44 xall joined
13:44 <ertes> then you can use liftIO from within it
13:44 <phz_> in tasty, there’s a function called defaultMain :: TestTree -> IO ()
13:44 `^_^v joined
13:44 <phz_> it seems it parses the command line arguments
13:44 <phz_> is there a way to run a specific test group from command line?
13:44 <stphrolland> ertes: many thanks, it's like I have all the bricks to play and experiment now
13:44 jbiesnecker joined
13:44 <ertes> phz_: yes, just give its name
13:44 <ertes> ./my-test-suite my-group
13:45 <phz_> even via stack?
13:45 IRCFrEAK joined
13:46 <ertes> if stack is any similar to cabal-install, you can probably use --my-test-suite-option=my-group
13:46 <ertes> but the cabal/stack interface is more for tests during installation/deployment… during development i would just call the test suite directly
13:47 <phz_> well, having a single entry point would be better
13:47 <cocreature> stack has a --test-argument option iirc that you need to use to pass arguments to your test suite
13:48 IRCFrEAK left
13:48 <phz_> Invalid option `--test-argument'
13:49 <cocreature> --test-arguments
13:49 <phz_> oh it’s
13:49 <phz_> yeah
13:49 <cocreature> stack test --help is your friend :)
13:49 <phz_> thanks!
13:49 <phz_> yeah I’m reading through
13:49 <ertes> you probably also need an option to stop stack from hiding your test suite's output… again if it's any similar to cabal-install =)
13:50 doomlord joined
13:50 <ertes> cabal-install only displays output if something goes wrong, and it also disables colour
13:50 <phz_> ertes: yeah I hate that
13:50 <ertes> that's why i would just use the test suite directly
13:50 <phz_> but it doesn’t hide it if you pass the testsuite
13:51 <cocreature> I don’t think cabal disables colour. it’s the test driver that disables colour if it’s not run via a tty
13:51 <Myrl-saki> Uwawawa~ Why is `evaluates to` and `you can derive` distinct in Evaluation inference rules?
13:51 <ertes> yeah, likely
13:51 fizbin joined
13:51 Ferdirand joined
13:52 xpkill23 joined
13:52 <Myrl-saki> Is there a reason why you can't have a rule with `pred (succ x) / x`
13:52 <phz_> we have colours here :)
13:52 <Myrl-saki> Why `x -> x / (succ x) -> (succ x)` or something similar?
13:54 <lyxia> joe9: are your types mostly single-constructor types
13:54 kadoban joined
13:54 fizbin joined
13:55 Snircle joined
13:55 <lyxia> I'm wondering whether a special function just for that case is actually what you're missing
13:56 oaao joined
13:56 bounb joined
13:56 bounb joined
13:56 xpkill23 joined
13:56 <lyxia> genericArbitrary' also messes with the size parameter, which might be annoying with simple types.
13:57 wroathe joined
13:57 xpkill24 joined
13:59 <joe9> lyxia: no, there are types like this: data Exchange = Globex | Eurex | Smart
13:59 <joe9> lyxia: I would not feel comfortable using a function just for simple types.
14:00 <joe9> lyxia: I want to use something that works whatever the type is.
14:00 suppi joined
14:00 <joe9> lyxia: does that make sense? it would be hard to debug if the genericArbitrary stops working just because the type is a little more complicated.
14:01 justin2 joined
14:03 mizu_no_oto joined
14:04 bounb joined
14:04 bounb joined
14:04 Mysterious_Light joined
14:04 cfricke joined
14:06 bodisiw joined
14:07 bhiliyam joined
14:08 <lyxia> I think things will break with recursive types though
14:08 Denthir_ joined
14:08 Mysterious_Ligh1 joined
14:09 fizruk joined
14:09 sphinxo joined
14:10 <joe9> I thought this would not: genericArbitrary (S Z) Uniform?
14:10 <phz_> https://gist.github.com/phaazon/eda92a5c5dc3c5676ad3a6c0d60c2047
14:10 <phz_> :(
14:10 <joe9> lyxia: genericArbitrary' (S Z) Uniform -- missed the quote
14:10 <lyxia> joe9: this is not universal either
14:10 <sphinxo> Could anyone provide any guidance/resources for stack typing? ( not talking about haskell stack )
14:10 <sphinxo> as in checking a stack based language
14:11 xall joined
14:11 <lyxia> and I don't quite like the fact that it messes with size by default
14:11 <lyxia> and detecting recursive types in a generic way is tricky
14:12 <joe9> lyxia: Is there a function that would work universally. Does not have to build infinite recursion depth. Something that just works for all types.
14:12 lithie joined
14:12 raycoll joined
14:12 deank joined
14:12 <joe9> lyxia: I understand infinite types can get tricky. Have a maximum depth for this case?
14:13 <joe9> lyxia: maybe hardcode the max depth to a certain default.
14:13 <joe9> lyxia: the "hardcode" just for this default function, I mean.
14:15 <phz_> no one knows about the ZonedTime parsed by aeson?
14:15 jgt2 joined
14:15 <phz_> that’s weird it doesn’t parse correctly
14:15 <lyxia> phz_: aeson parses JSON, your string doesn't contain JSON.
14:16 Lokathor joined
14:16 <phz_> ah
14:16 <phz_> I was missing a Z at the end
14:16 <phz_> hm, it’s gonna be boring…
14:17 wroathe joined
14:18 <lyxia> phz_: have you tried to encode one to see what the expected format is
14:18 <phz_> I just read the sources, because the documentation is bad
14:18 <phz_> https://github.com/bos/aeson/blob/master/attoparsec-iso8601/Data/Attoparsec/Time.hs#L136
14:18 <phz_> so yeah, I need to snoc a 'Z'
14:18 <phz_> I wonder how I can do that
14:18 <phz_> with the (.:) operator
14:19 <phz_> I guess I could… read a String / Text, then adds the 'Z', then readback to ZonedTime?
14:19 <phz_> ooooooooooooor
14:19 <phz_> I could just alter the source :)))
14:19 <phz_> and send the Z directly!
14:19 <phz_> yeah, I’ll do that
14:19 <phz_> I need to see how to do that in MSSQL
14:19 <phz_> hm, concatenate seems the right tool here
14:20 <phz_> oh SQL Server supports the + operator
14:20 <phz_> neat
14:20 mstruebing joined
14:20 <lyxia> there is a bit happening between zonedTime and eitherDecode
14:21 <lyxia> so the string you're passing eitherDecode isn't what gets passed to zonedTime
14:22 <mniip> haskell types are like constructive logic, right?
14:22 govg joined
14:25 exferenceBot joined
14:25 <merijn> mniip: An inconsistent form of constructive logic, yes
14:25 rcat joined
14:25 <mniip> and FOL is dependent types
14:25 zcourts joined
14:26 burtons joined
14:26 <Myrl-saki> mniip: o you still remember me. '-'
14:26 <Myrl-saki> Do*
14:26 <lyxia> joe9: I don't think there is a good solution. Trying to handle all kinds of cases would make this quite heavyweight, and then there is the issue that if you try to keep it too simple you have no knowledge about the resulting distribution.
14:27 Mysterious_Light joined
14:27 <mniip> no
14:27 <mniip> who are you
14:27 <Myrl-saki> mniip: rip.
14:27 <shapr> My gf needed some csv processing this past weekend, and I coudn't find any good example uses for cassava, so I used Python. Are there some good examples of cassava use?
14:27 wroathe joined
14:27 <mniip> merijn, I know of a cubic time solver for haskell types, is there a P time solver for dependent types?
14:27 <Myrl-saki> mniip: I feel kinda hurt.
14:27 <* shapr> hugs Myrl-saki
14:28 <merijn> mniip: I have no clue
14:29 <lyxia> joe9: testing-feat can cover a lot of types though
14:29 gcross_ joined
14:30 <joe9> lyxia: Thanks will check out testing-feat. did not know about it.
14:31 bennofs joined
14:31 cyborg-one joined
14:36 exferenceBot joined
14:37 cdg joined
14:38 wroathe joined
14:38 fizruk joined
14:38 carlomagno joined
14:39 zcourts joined
14:40 cdg joined
14:41 mazeinmaze_ joined
14:42 coltfred joined
14:42 blocus joined
14:43 <bennofs> Is gfoldl actually a fold? It looks more like a traverse to me
14:44 noteshui joined
14:45 xinming joined
14:46 nbro joined
14:46 Aruro joined
14:47 contiver joined
14:48 Guest67074 joined
14:49 <lyxia> I guess those who wrote this looked at folds and traversals from far enough to consider them the same.
14:50 ysahil joined
14:51 <Cale> It's also worth noting that Traversable didn't exist at the time
14:51 <ysahil> Hi Guys!! Can someone guide me on how to connect to a server in Haskell?
14:51 <Cale> I'm actually not even sure Applicative did...
14:51 <Cale> ysahil: What kind of server?
14:52 mtesseract joined
14:52 <ysahil> Actually, I am attempting to make a IRC bot using Haskell
14:52 <ysahil> So what is the server name we should connect to?
14:53 <Cale> uh, whatever IRC server it is you want your bot to connect to
14:53 <Rembane> ysahil: irc.freenode.net and see what happens. :D
14:53 fotonzade joined
14:54 <eschnett> bennofs: how is gfoldl a traverse? travers takes two functors, here i see only one (c)
14:54 cobreadmonster joined
14:54 mda1 joined
14:54 nagyf joined
14:55 <ysahil> I tried that and when I executed that program, two errors arose while connecting to that server, "Couldn't look up your hostname" and "No Indent response". I have no idea as to how this error arose
14:55 SimpleL joined
14:56 splanch joined
14:57 <ysahil> Rembane: Can you help me in this?
14:57 uglyfigurine joined
14:58 wroathe joined
14:58 mizu_no_oto_work joined
14:58 <geekosaur> what program are you using for this?
15:00 <Rembane> ysahil: Sure, answer geekosaur's question.
15:00 <ysahil> geekosaur: I made up my own program which, for now, just tries to connect to irc.freenode.net with port number 6667
15:00 <ph88^> what's the allocation strategy for Data.Vector ? 2x ?
15:02 <Cale> ysahil: That's normal. My IRC client gives those errors every time I connect.
15:02 sea_wulf joined
15:02 <Cale> ysahil: also, it's Ident response -- it's the IRC server looking to see if you're running identd
15:03 <peddie> ph88^: are you talking about mutable vectors? the immutable ones obviously don't resize . . . and I don't think there is automatic resizing on the mutable ones
15:03 <ph88^> peddie, ye what's the automatic resizing like? double up ?
15:04 <peddie> ph88^: I think you can call `grow` to manually resize; again, I don't think there is automatic resizing
15:04 <peddie> ph88^: you'd have to implement it yourself
15:05 <geekosaur> identd isn't often used any more, it's at beat meaningless and at worst itself a potential security hole
15:05 Saket joined
15:05 zuul joined
15:05 <zuul> Good day.
15:05 <peddie> ph88^: take a look at the docs in https://hackage.haskell.org/package/vector- -- I don't think there is anything analogous to push_back
15:05 <Guest67729> Opinions on Graham Hutton's "Programming in Haskell" for a first time programmer?
15:05 Saket left
15:05 <ph88^> peddie, oh ok i have to specify the grow size and thus strategy .. ok thx
15:06 rossberg joined
15:07 <ysahil> Cale:So what is the remedy to this problem?We can't just leave it as it is.
15:08 cschneid_ joined
15:08 bhiliyam joined
15:08 amargherio joined
15:08 mda1 joined
15:08 Gurkenglas_ joined
15:09 <Cale> ysahil: Ignore those messages?
15:10 jao joined
15:10 gregman_ joined
15:10 <Cale> ysahil: You'll see those messages even if your client is working just fine. In fact, depending on which IRC client you're using right now, you'll probably find that Freenode sent the same messages to you when you connected.
15:10 <Cale> ysahil: They're ignorable.
15:11 osa1 joined
15:12 mthek joined
15:13 al-damiri joined
15:13 HarveyPwca joined
15:14 <ysahil> Cale:Okay, now I get it.Thanks Guys. :D
15:15 raichoo joined
15:16 pheaver joined
15:16 eklavya joined
15:16 <lyxia> eschnett: traverse is only a special case of traversals as general concept where you go through a structure and modify its fields, sometimes with side effects.
15:17 blocus joined
15:17 snowalpaca joined
15:18 ryxai joined
15:18 wroathe joined
15:19 shutdown_-h_now joined
15:20 Swizec joined
15:21 fakenerd joined
15:22 revprez_atlanta joined
15:23 cdg_ joined
15:23 exferenceBot joined
15:25 trism joined
15:25 govg joined
15:25 steeze joined
15:26 Luke joined
15:26 psychicist__ joined
15:26 bab joined
15:26 des_ joined
15:26 pera joined
15:27 <Luke> Hey guys. Anyone know of a way to mock out the current time in IO for testing purposes?
15:27 mtesseract joined
15:27 <tdammers> Dependency injection
15:27 <tdammers> Don't get the current time from IO, pass it in explicitly
15:28 <Luke> tdammers: I can't pass it in explicitly because some of the libraries we're using are in IO and not MonadIO
15:28 stoopkid joined
15:28 <tdammers> ah
15:28 <tdammers> you mean, the third-party functions get current time from IO?
15:28 <Luke> yes
15:29 <tdammers> ah that sucks
15:29 sellout- joined
15:29 <Luke> tdammers: it's high performance networking code so it's hardcoded to IO on purpose
15:30 alx741 joined
15:33 skeet70 joined
15:33 eazar001 joined
15:35 simukis__ joined
15:35 animated joined
15:35 simukis__ joined
15:36 Mysterious_Light joined
15:37 <sphinxo> Luke: you can do it on the system level with https://github.com/wolfcw/libfaketime
15:37 <Luke> great thank you!
15:37 jmelesky joined
15:37 <sphinxo> this catches the actual calls using LD_PRELOAD
15:37 <Luke> perfect
15:37 <Luke> have you used this before? did you like it?
15:37 mbw joined
15:37 <sphinxo> Are you going to be changing the time, whilst the test cases are running?
15:38 wroathe joined
15:39 <ph88^> i have a file with lines like 2.152 3.760 -0.376
15:39 <ph88^> i was thinking of parsing with attoparsec and then make a Vector of Vectors of Double .. is that a good idea ?
15:39 <mbw> Is there a way to change how ghc cuts off identifier strings in the .hp file produced by ./bin +RTS -hc[...]? I currently have ids like "(3064)bubblesortM/bubblesor...", which are not very helpful.
15:41 <mbw> And what does 3064 stand for?
15:42 <Luke> sphinxo: I'd like to have the option to change the time during the tests for timeouts etc.
15:42 contiver joined
15:42 <nshepperd_> mbw: -L sets the cutoff iirc
15:43 <nshepperd_> Not really sure why the rts has a cutoff anyway.... That should be done in the ui tools really
15:43 simukis__ joined
15:44 boombanana joined
15:45 cmsmcq joined
15:45 <mbw> nshepperd_: You are correct! Thanks. And yes, heap profiling is probably not perfect, but way better than what I'm used to from c++&friends.
15:45 Yuras joined
15:46 <sphinxo> What's the best way to track position infomation through the type checking phase for better error reporting
15:46 simukis_ joined
15:48 RegEchse joined
15:48 preyalone joined
15:49 <sphinxo> Luke: you can change the enviroment variable FAKETIME=<datetime> and disable caching with FAKETIME_NO_CACHE=1
15:49 wroathe joined
15:49 <Luke> hmm ty
15:49 <sphinxo> no caching means it is forced to lookup the env var each time
15:50 amargherio joined
15:50 dhil joined
15:50 simukis_ joined
15:50 hamishmack joined
15:52 fizbin joined
15:56 urodna joined
15:57 <ertes> ph88^: depends on how precise you want those numbers to be
15:57 <ertes> ph88^: Double can only represent ratios of the form x * 2^e, where both x and e are integers, exactly, so for example there is no exact representation for 0.1
15:58 <ph88^> ertes, what are my options ?
15:58 <ertes> ph88^: Rational and Fixed (Data.Fixed)
15:58 <ph88^> how does Rational, Fixed and Double compare in speed ?
15:58 <byorgey> ph88^: probably Double is fine.
15:58 skeet70 joined
15:59 <ertes> ph88^: Rational is much slower, because it does Integer arithmetic, including calculating 'gcd'
15:59 <Myrl-saki> ph88^: What are the numbers supposed to represent?
15:59 <ertes> ph88^: Fixed is reasonably fast
15:59 <ertes> probably near Double speed
15:59 <Myrl-saki> ertes: lcd?
15:59 <ertes> ph88^: however, first check whether you need the precision
15:59 <byorgey> even without knowing what you want to do with those numbers, I am going to say with 95% confidence that you should just use Double.
15:59 <ph88^> Myrl-saki, http://users.rcn.com/wpacino/jitwtutr/jitwtutr.htm
15:59 <ertes> also Double is not *less* precise than Fixed, but it has a different trade-off
16:00 <ertes> for example Double can easily represent 0.000000000000000000000000000000000000000000000000000000000000005
16:00 <ph88^> ertes, i think speed is more important than the precision
16:00 <ertes> Myrl-saki: lcm involves gcd
16:00 <Myrl-saki> ertes: Talking about *d*
16:00 <Myrl-saki> ertes: Either gcf, lcd or lcm.
16:00 <ertes> what's lcd?
16:01 <Myrl-saki> least common denominator.
16:01 <ertes> that's the same as least common multiple =)
16:01 <byorgey> Myrl-saki: 'gcd' stands for 'greatest common divisor'
16:01 <ertes> > lcm 12 15
16:01 <lambdabot> 60
16:01 <Myrl-saki> byorgey: AOh.
16:01 <byorgey> > gcd 12 15
16:01 <Myrl-saki> byorgey: I know it more as gcf.
16:01 <lambdabot> 3
16:01 <ertes> > 12*15 `div` gcd 12 15
16:01 <lambdabot> 60
16:01 <Myrl-saki> factor <-> divisor
16:01 <Myrl-saki> Sorry. >.<
16:01 <byorgey> Myrl-saki: fair enough, but in Haskell it is called 'gcd' =)
16:02 <byorgey> no worries
16:02 <ertes> Myrl-saki: GCD is also pretty standard terminology =)
16:02 <ertes> and so is LCM
16:02 zcourts joined
16:02 <byorgey> well, I suspect 'standard' depends on where you went to school
16:02 <Myrl-saki> ertes: Yeah. d just auto-translated to denominator because fractions. Whoops. my fault.
16:02 <ertes> true
16:02 <Myrl-saki> byorgey: Yeah, we use factor rather than denominator here.
16:02 <byorgey> everyone thinks the way *they* learned it is 'standard'
16:03 <Myrl-saki> s/denominator/divisor/
16:03 <Myrl-saki> Can you do recursion with linear types?
16:03 <ertes> well, in my case it's my number theory/crypto background
16:04 <Myrl-saki> We can't define fix, but how about explicit(?) recursion.
16:05 <ph88^> should i use Data.Attoparsec.ByteString.Lazy or Data.Attoparsec.Text.Lazy ?
16:05 <ph88^> oh there is also a Data.Attoparsec.Lazy
16:05 <Myrl-saki> ph88^: That depends a whole lot.
16:05 <Myrl-saki> ph88^: Heck, why not even just use Parsec?
16:06 <ph88^> speed
16:06 <ph88^> our c programs takes 30 minutes
16:06 <Myrl-saki> ph88^: Ah. Migration.
16:06 <ph88^> the c program is not written well and the interface is not nice
16:06 <Myrl-saki> ph88^: I may be wrong here.
16:06 <ertes> ph88^: if you're going for raw speed, assume an encoding and use ByteString
16:06 <ph88^> ok
16:07 <ertes> ph88^: however, benchmark first
16:07 <ph88^> is Float faster than Double by the way ?
16:07 <ph88^> ok
16:07 <Myrl-saki> ph88^: Possible.
16:07 <Myrl-saki> Most likely, rather.
16:07 <ertes> ph88^: also see how attoparsec compares to the C program… it's fast, but far from the optimum
16:07 <ertes> especially since it does automatic backtracking
16:08 <ph88^> don't think much backtracking will be needed in that format
16:08 <ertes> so you should make sure that your choices ((<|>)) are as local as possible
16:08 <ph88^> 2.152 3.760 -0.376
16:08 featherlessbiped joined
16:08 Sonolin joined
16:08 <ph88^> that might vary in the amount of columns
16:09 bhiliyam joined
16:09 <geekosaur> actually I'd tend to assume Float is the same speed aside from non-strictly-floating-point operations like copying or loading/storing
16:09 <ertes> abstract over the floating point type, if you can, then you can easily benchmark both
16:09 moth joined
16:09 <Myrl-saki> `many numbers` or something.
16:09 <ertes> because i doubt that Double is slower on modern architectures
16:09 <Myrl-saki> geekosaur: Can't you do more float operations in parallel?
16:10 <ph88^> ertes, since i have a dynamic amount of columns, should my type be Vector Vector.Unboxed Double ?
16:10 jsgrant_ joined
16:10 <geekosaur> the floating point unit generally works at full precision (even more than Double) internally and truncates on store
16:10 <ertes> ph88^: are you parsing the whole thing into memory?
16:10 <ph88^> no, but i need a sliding window
16:11 <Myrl-saki> geekosaur: Eh.
16:11 <ertes> ph88^: Vector is not a good choice for a sliding window, unless you use a mutable vector
16:11 <ph88^> oh
16:11 <ertes> ph88^: Seq is a good choice, but a mutable vector will still be faster
16:11 <ertes> like a ring buffer
16:12 sellout- joined
16:12 SpaceGazebo3 joined
16:12 <ph88^> ertes, i need to fill up the ring buffer with for example 1000 values .. then i need to calculate the biggest value .. then i need move the window by 1 and calculate the next biggest value .. and so on ..
16:12 <Myrl-saki> http://x86.renejeschke.de/html/file_module_x86_id_6.html http://x86.renejeschke.de/html/file_module_x86_id_7.html
16:12 <ertes> ph88^: you don't need a sliding window for that, i think
16:12 <ph88^> i already figure that i don't have to compare the value with all the previous values but only the maximum previous value found
16:12 <ertes> ph88^: ah, nevermind, you do
16:12 <Myrl-saki> 4 singles vs 2 doubles.
16:12 <ertes> but you can limit the sliding window
16:13 <ph88^> what kind of limit ?
16:13 SpinTensor joined
16:13 <Myrl-saki> Of course, AVX exists.
16:13 <ertes> ph88^: well, once you have a greatest value, you can remove everything that came before it
16:13 <Myrl-saki> Where I might be very wrong.
16:14 emc2 joined
16:14 <ph88^> ertes, actually .. i don't think i need window at all ..
16:14 jmelesky joined
16:14 <emc2> is there some way to make a package require -threaded
16:14 <ph88^> i just need to calculate the window once and then check the next value with tha maximum one
16:14 <ertes> ph88^: you do, because if the greatest value falls off, you need to find the next greatest value
16:14 <emc2> seems I've never actually used -threaded before
16:15 aarvar joined
16:15 aarvar left
16:15 <ph88^> ertes, i think it will be enough to track the position of the greatest value
16:15 <emc2> but my test library needs -threaded for doing timeouts
16:15 <ertes> ph88^: let's say you're looking for the greatest value out of five and your window looks like this: [10, 4, 7, 1, 6]
16:16 <ertes> ph88^: now a new value comes in that is still smaller than 10
16:16 <cocreature> emc2: you can add -threaded to your ghc options
16:16 Swizec joined
16:16 <ph88^> ertes, oh yes you're right
16:16 <ph88^> ertes, would there be any benefit though to dropping the left half ?
16:16 <emc2> cocreature: that'll set it for anything that depends on it?
16:17 <cocreature> emc2: no sorry, that only works for executables (but a test-suite is an executable so it would work for that)
16:17 <ertes> ph88^: sure, whenever a new greatest value comes in, you can pretty much discard the whole window
16:17 <ertes> you only need the window, if the old greatest value falls off and you need to find the next one
16:17 Itkovian joined
16:17 Mysterious_Light joined
16:18 <ph88^> ertes, but discarding the window does that optimize for memory or for wall time ? because i care for wall time, not memoty
16:18 <ertes> ph88^: both
16:18 <ph88^> so i use Data.Vector.Unboxed.Mutable ?
16:18 <Myrl-saki> ertes: How does it help for both?
16:19 <ertes> ph88^: you should use Seq first, and only switch to a mutable vector when Seq is too slow, because the mutable vector variant requires some engineering effort and is easy to get wrong
16:19 jsgrant_ joined
16:19 wroathe joined
16:20 <ph88^> ertes, https://hackage.haskell.org/package/parallel- ?
16:20 ilyaigpetrov joined
16:20 <Myrl-saki> ertes: To be more exact, how does it help with wall time?
16:20 <ph88^> or this one https://hackage.haskell.org/package/containers- ?
16:20 cschneid_ joined
16:20 <emc2> in that case, is there a way to detect if I'm running with the threaded runtime
16:20 mattyw joined
16:21 <ertes> Myrl-saki: GC may have less work to do
16:21 <ertes> also using less memory is almost always a time benefit as well, because of caching
16:21 <ertes> ph88^: containers
16:21 <ph88^> ok
16:21 <ph88^> thank you
16:22 <shapr> mmm, vectors
16:22 <ertes> ph88^: in case you're going for the mutable variant, i strongly recommend that you write a ring buffer abstraction around it and test it well
16:23 augur joined
16:26 hamishmack joined
16:26 SpaceGazebo3 joined
16:26 ichor joined
16:29 cpennington joined
16:29 HarveyPwca joined
16:29 takle_ joined
16:29 wroathe joined
16:30 <cocreature> emc2: I think https://downloads.haskell.org/~ghc/8.0.1/docs/html/libraries/ghc-8.0.1/Config.html#v:cGhcThreaded tells you that
16:30 splanch joined
16:30 govg joined
16:31 skeet70 joined
16:32 a3Dman joined
16:32 acarrico joined
16:33 <lyxia> ph88^: Oh, I have a purely functional bounded buffer lying there https://github.com/Lysxia/breadcrumbs/blob/master/Data/Breadcrumbs/Caterpillar.hs
16:34 blocus joined
16:34 fakenerd_ joined
16:35 ntnvgu joined
16:35 coot joined
16:36 ryxai joined
16:36 robertkennedy joined
16:37 eklavya joined
16:39 UberLambda joined
16:39 zero_byte joined
16:40 SpaceGazebo3 joined
16:40 wroathe joined
16:41 mzf joined
16:41 Mysterious_Light joined
16:45 eschnett joined
16:46 tathougies joined
16:48 <Myrl-saki> I don't think it's possible to loop with linear types.
16:49 Guest81707 joined
16:49 cdg joined
16:50 wroathe joined
16:51 erisco joined
16:51 <erisco> an interesting thought... list the paths of an infinite tree
16:54 NeverDie_ joined
16:54 ChaiTRex joined
16:55 fizbin joined
16:56 infinity0 joined
16:56 iAmerikan joined
16:57 Icewing joined
16:59 crobbins joined
17:00 infinity0 joined
17:00 SolitaryCypher joined
17:01 <ski> Myrl-saki : you probably needs some kind of "of course" or "why not" modality, aye
17:01 <sphinxo> What's the best way to annotate an ast?
17:02 <sphinxo> to add position info/ errors
17:02 ner0x652 joined
17:03 tathougies joined
17:03 <Myrl-saki> ski: Mhm.
17:03 JuanMiguel joined
17:03 <ski> @where DecoratingStructures
17:03 <lambdabot> <http://web.archive.org/web/20051126143527/http://haskell.org/hawiki/DecoratingStructures>
17:04 <ski> @where IndirectComposite
17:04 <lambdabot> <http://web.archive.org/web/20051126141834/http://haskell.org/hawiki/IndirectComposite>
17:04 <ski> sphinxo : perhaps see ^
17:04 <Myrl-saki> ski: In Wadler's paper, `append` was only reimplemented when he reintroduced nonlinear types..
17:04 <sphinxo> Thanks!
17:04 Berra joined
17:05 <ski> Myrl-saki : possibly it'd be enough with a nonlinear zone
17:05 <Myrl-saki> ski: A bit of a segway. Why is evaluation done with `->` rather than going straight evaluation rules?
17:06 <ski> i'm not sure what you mean
17:06 <Myrl-saki> ski: Something along the lines of `pred (succ x) / x`
17:06 <Myrl-saki> Why go through the hoops of `x -> x / succ x -> succ x`
17:07 dhil joined
17:07 marfoldi joined
17:07 venkat24 joined
17:08 <Myrl-saki> Oh, that was an actual rule.
17:09 bhiliyam joined
17:10 wildlander joined
17:10 cyborg-one joined
17:10 <* ski> is still not following, fwiw ..
17:10 wroathe joined
17:11 mtesseract joined
17:11 feynhat joined
17:11 <Myrl-saki> ski: Do you have a copy of TAPL?
17:12 fosskers joined
17:12 <fosskers> Do attoparsec parsers perform better when written in Applicative style over Monadic style, or is the optimized code pretty much the same?
17:13 willprice94 joined
17:14 jgt2 joined
17:14 <joe9> fosskers: I would say user comprehension is more important than sysetm performance in that regard.
17:14 <ski> Myrl-saki : yes, but not here
17:14 dfeuer joined
17:14 <Myrl-saki> ski: Ah. Maybe some other time. x3
17:15 <lyxia> fosskers: attoparsec's <*> is implemented using >>=
17:15 <lyxia> http://hackage.haskell.org/package/attoparsec-
17:15 <ski> it seemed you were pondering something about operational semantics, rewriting systems. big-step vs. small-step. structural semantics. &c.
17:15 glamas joined
17:16 kosorith joined
17:16 <Myrl-saki> ski: I think it's because I'm misusing inference rules.
17:16 shutdown_-h_now joined
17:17 mizu_no_oto_work joined
17:17 sigmundv joined
17:18 latencyloser joined
17:18 ragepandemic joined
17:19 <fosskers> joe9, I'm going for speed
17:19 <fosskers> lyxia, thanks, so no difference.
17:19 <Myrl-saki> Welp. G'night. It's 1 over here.
17:19 splanch joined
17:20 splanch_ joined
17:21 boxscape joined
17:21 Noldorin joined
17:22 caente joined
17:23 <boxscape> hm, it seems strange that while lens has <.= to pass through the value of .=, it doesn't have <%= as the equivalent of %= ...
17:23 BlueRavenGT joined
17:23 splanch__ joined
17:23 Swizec joined
17:24 <cocreature> boxscape: hm? https://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-Lens.html#v:-60--37--61- exists
17:24 nagyf joined
17:24 ChaiTRex joined
17:24 <boxscape> huh
17:24 <boxscape> I looked in the wrong module apparently
17:24 <boxscape> thanks
17:25 <cocreature> boxscape: hoogle is great for that kind of stuff http://hoogle.haskell.org/?hoogle=(%3C%2B%3D)
17:25 <boxscape> yeah, I usually use hoogle.. I just naively assumed that it would be defined in the same place as <.= :)
17:27 ner0x652 joined
17:28 ner0x652 joined
17:31 wroathe joined
17:31 vimto joined
17:32 SimpleL joined
17:32 raichoo joined
17:34 splanch_ joined
17:34 <boxscape> (I had been looking in Control.Lens.Setter)
17:35 vimto joined
17:35 splanch joined
17:37 iAmerikan joined
17:37 jgt2 joined
17:38 Luke joined
17:41 contiver joined
17:42 zariuq joined
17:42 takle joined
17:42 jgertm joined
17:43 Zialus joined
17:44 MitchellSalad joined
17:46 jespada joined
17:47 significance joined
17:48 Gurkenglas joined
17:49 Orion3k joined
17:49 vydd joined
17:50 t0by joined
17:50 t0by joined
17:51 wroathe joined
17:51 theelous3 joined
17:52 takle joined
17:52 <significance> Hey all! If I have a do block that returns a list, how can I get the first element from it?
17:52 <significance> head do ... is of course a syntax error :P
17:54 <significance> nvm, got it -- head $ do.
17:54 bennofs joined
17:56 mattyw joined
17:56 ChaiTRex joined
17:58 bodisiw joined
17:58 ClaudiusMaximus joined
17:58 mizu_no_oto_work joined
18:00 will joined
18:00 eklavya joined
18:02 wroathe joined
18:02 bollu joined
18:04 sleffy joined
18:04 anuxivm left
18:07 chenshen joined
18:09 ysahil joined
18:10 bhiliyam joined
18:12 oaao joined
18:12 ertesx joined
18:16 twanvl joined
18:16 wroathe joined
18:16 caumeslasal joined
18:18 urodna_ joined
18:18 infandum joined
18:18 crobbins joined
18:18 <erisco> or head (do ...)
18:19 <infandum> What causes a NaN in Haskell? More specifically, why would (** (1 / 7)) . product $ [6703,6790,6440,6699,6933,6751,6707] cause a NaN in compiled but not in ghci?
18:19 <Tuplanolla> That sounds suspicious, infandum.
18:20 <geekosaur> platform?
18:20 <ChaiTRex> infandum: I can't get it to be NaN with either.
18:20 <infandum> (that is, when having a traceShow with that function, traceShow (x (that list), and that function result y) returns (that list, NaN))
18:21 Itkovian joined
18:21 <eschnett> your list has only integers. multiplying them might overflow. did you mean to convert to Double before taking its product?
18:21 <glguy> Incidentally you can deobfuscate that as: product [6703,6790,6440,6699,6933,6751,6707] ** (1/7)
18:21 <infandum> ChaiTRex: If I do it isolated in ghci it's fine, but for some reason with thousands of other values things start to become NaN even in that debug
18:21 IanKelling joined
18:21 augur joined
18:21 <infandum> so it has to be between those steps
18:21 <eschnett> with thousands of values, the product might end up being zero due to integer overflow
18:21 <infandum> glguy: I like point free :)
18:22 <eschnett> … or negative
18:22 <infandum> eschnett: Interesting. Because there are lots of examples of this.
18:22 contiver_ joined
18:22 <infandum> It's fmapping over a list of lists
18:22 madmax joined
18:22 <Tuplanolla> Do you get a different result with identical input and extensions, infandum?
18:22 <infandum> I've never had a problem like this before on big data though
18:23 richi235 joined
18:23 <eschnett> i would choose explicitly which type should be used for the product and the root
18:23 <Tuplanolla> Make sure you don't get anything with `-Wall`, infandum.
18:23 <infandum> Tuplanolla: The only extension I have is BangPatterns
18:23 epsilonhalbe joined
18:24 <Tuplanolla> This sounds like a common mistake due to type defaulting, infandum.
18:24 <Tuplanolla> However I would not be surprised if some optimization removed a store and accidentally kept extra precision in a floating-point register, infandum.
18:24 fizruk joined
18:24 <infandum> Tuplanolla: It's ok other than some name shadowing (in another function) and type inference of integer in some cases
18:25 sssilver joined
18:25 dcz__ joined
18:25 <eschnett> Tuplanolla: extra precision is only a problem with 32-bit intel architectures. 64-bit architectures don’t have that feature any more.
18:25 <infandum> I'm on 64 bit
18:25 <cocreature> infandum: are you sure you are really running the exact same code in your compiled program?
18:25 <Tuplanolla> Well, then.
18:26 orbifx joined
18:26 wroathe joined
18:26 <infandum> cocreature: It's actually: https://pastebin.com/10BYuVTm
18:26 jitu330 joined
18:27 <infandum> Where head xs is a list of 7 numbers (I verified it)
18:27 JuanDaugherty joined
18:27 <dcz__> hello guys, i am trying to find mp4 files in home directory. My purpose is that. For now, i listed files in $HOME but how can i convert IO [FilePath] -> [FilePath] or how can i get rid of IO ? :D, line 9 doesnt work for example. https://hastebin.com/befilogude.hs
18:27 <infandum> that trace results in stuff like: (NaN,[581,3498,461,4698,2675,395,2834],NaN,[6968,10050,10047,1323,9627,12393,10550])
18:28 ubsan_ joined
18:28 jitu330 left
18:28 <infandum> actually I removed one element in that tuple in the code I sent in order to recompile
18:28 <eschnett> infandum: you could replace “fromIntegral. product” by “product . fmap fromIntegral”
18:28 <cocreature> infandum: well that’s different from the code you used in GHCi
18:29 fXl joined
18:29 <cocreature> fromIntegral means that the product can be calculated using a different type
18:29 <infandum> ithat last one was the head of xs btw
18:29 <cocreature> the code you showed us before has to use something that is an instance of Floating
18:29 <infandum> cocreature: They are all integers until after the product
18:29 dylukes joined
18:29 <cocreature> infandum: they’re not in the code you showed at the beginning of this conversation
18:29 <cocreature> :t (**)
18:29 <lambdabot> Floating a => a -> a -> a
18:30 <cocreature> both sides need to be an instance of Floating
18:30 <infandum> hence the fromIntegral
18:30 <cocreature> :t product
18:30 <lambdabot> (Num a, Foldable t) => t a -> a
18:30 <infandum> I mean, otherwise it would not have compiled though
18:30 <cocreature> infandum: right but you didn’t use that in the example that didn’t cause problems in ghci
18:30 <infandum> I can try it again
18:30 <ysahil> How to change the timeout parameter in sockets?
18:30 cobalamin joined
18:30 ragepandemic joined
18:31 <ClaudiusMaximus> > product [6703,6790,6440,6699,6933,6751,6707] :: Int
18:31 <lambdabot> -759020139851360848
18:31 <ClaudiusMaximus> eschnett++
18:31 <geekosaur> dcz__, you use <>>=) or do notation. You cannot "convert" or "get rid of the IO".
18:31 <infandum> uh
18:31 Luke joined
18:32 <infandum> huh
18:32 <infandum> well that's starting to explain it
18:32 dylukes joined
18:32 <dcz__> geekosaur: whats the best way that thing i am trying to do ?
18:32 <infandum> yup, that solved it
18:32 <Tuplanolla> So it was a type defaulting problem after all, infandum.
18:32 <infandum> can someone explain why that happened?
18:33 <infandum> Why would product of a bunch of ints result in that number?
18:33 <Tuplanolla> > maxBound :: Int
18:33 <lambdabot> 9223372036854775807
18:33 <infandum> itsn't the accuracy the same?
18:33 <infandum> maxBound :: Double
18:33 mac10688 joined
18:33 <geekosaur> dcz__, you already used <- there, so x :: [FilePath]
18:33 chaosmasttter joined
18:33 <infandum> > maxBound :: Double
18:34 <lambdabot> error:
18:34 <lambdabot> • No instance for (Bounded Double) arising from a use of ‘maxBound’
18:34 <lambdabot> • In the expression: maxBound :: Double
18:34 <geekosaur> why do you think you need to "convert"?
18:34 wildlander joined
18:34 <infandum> > product [6703,6790,6440,6699,6933,6751,6707] :: Double
18:34 <lambdabot> 6.1638555625196704e26
18:34 <geekosaur> infandum, minBound/maxBound only work when the bounds are reachable by addition. Floating point doesn't work that way
18:34 <infandum> oh come on
18:35 <infandum> so I really should not be using Ints EVER
18:35 <Tuplanolla> There are no implicit conversions in Haskell land, infandum.
18:35 ragepanda joined
18:35 <dcz__> geekosaur: but line 9 doesnt work
18:35 <infandum> geekosaur: Characters work because of their integer conversion?
18:36 <geekosaur> "doesnt work" how?
18:36 <geekosaur> (I can already see one issue not related to types)
18:36 john__ joined
18:36 wroathe joined
18:37 <infandum> Tuplanolla: So is the lesson here never use Ints for large numbers, only Doubles and Integers?
18:37 slacker joined
18:37 <Tuplanolla> The lesson is that when you say `fromIntegral 42 :: Double`, your `42` may actually secretly be `Int`, infandum.
18:37 <infandum> because we can't always guarentee the bounds of a measure for something like product
18:37 <dcz__> geekosaur: the .viminfo file is in $HOME, f <- findFiles x $ y ++ ".viminfo", print f, however returns []
18:38 <geekosaur> yes, that has nothing to do with types
18:38 <cocreature> infandum: at least don’t use Int for large numbers and expect them to not overflow :)
18:38 <infandum> Tuplanolla: Sure, but speaking in terms of computational accuracy I don't see why It can't report 6.16 etc e26 as an integer, either, because it is one
18:38 <infandum> as an Int I mean. That's not a haskell issue though
18:39 <Tuplanolla> The other lesson is that, indeed, bounded types may wrap, infandum.
18:39 <Tuplanolla> At least in Haskell land that's defined behavior.
18:39 <geekosaur> dcz__, so I see you print y. what does that return? now think about what the concatenation does
18:40 <ClaudiusMaximus> > let d = 1 :: Double ; (f, _) = decodeFloat d ; g = f * floatRadix d - 1 ; (_, r) = floatRange d ; s = r - floatDigits d ; m = encodeFloat g s in m -- how to calculate the largest finite RealFloat value
18:40 <lambdabot> 1.7976931348623157e308
18:40 <infandum> Tuplanolla: I mean, I knew I was dealing with Ints the whole time until the end, the issue was that I didn't realize how large the numbers would get
18:40 <cocreature> > let x = -2^63 :: Int in (x, abs x) -- more fun with bounded types
18:40 <lambdabot> (-9223372036854775808,-9223372036854775808)
18:40 contiver joined
18:41 <infandum> oh jou
18:41 <infandum> joy
18:41 <infandum> How much slower is just using Integer? haha
18:41 <cocreature> at some point I was planning to try and convince people that this should throw an exception in haskell but then I got lazy
18:42 <Tuplanolla> You either take the performance hit or become a numerical analyst, infandum.
18:42 <dcz__> geekosaur: concatinates lists, right. how can i do that then ? :D doesnt <- converts them to String or whatever ?
18:42 jitu330 joined
18:42 jitu330 left
18:42 <Tuplanolla> The latter option takes longer in the end.
18:42 <geekosaur> dcz__, ok, you are not getting it
18:42 <ChaiTRex> > 1.7976931348623157e308 ^ 50
18:42 <lambdabot> Infinity
18:42 <geekosaur> "/home/foo.viminfo" is what you are getting
18:43 <geekosaur> or something similar to that. notice something missing??
18:43 <ChaiTRex> Why did they choose infinity for that, when it's much closer to 1.7976931348623157e308?
18:43 <geekosaur> because that's what ieee754 specifies?
18:44 <mauke> it's also much closer to 1
18:44 <ChaiTRex> Yeah, but why does it specify that?
18:44 SpaceGazebo3 joined
18:45 Zialus joined
18:45 <dcz__> geekosaur: ahh, i didnt realize that getHomeDirectory doesnt put "/" at the end
18:45 <infandum> ChaiTRex: I assume it's because x ^ 50 /= x for that case
18:46 <geekosaur> most stuff doesn't. shell expansion is an exception (and sometimes I woish it wouldn't just because people come to think the OS magically does that for them always)
18:46 yellowj joined
18:46 warlock joined
18:46 <infandum> ah, it shouldn't say Infinity, it should say PositivelyLarger
18:46 <infandum> or just Larger
18:46 <infandum> eh
18:46 <Tuplanolla> Read up on unums to feel less bad about floating-point numbers.
18:46 <AWizzArd> I want a data type which wraps a number: data Foo = Foo Num – how can this be achieved?
18:47 <geekosaur> that is more or less what Inf means in ieee754
18:47 wroathe joined
18:47 cpup joined
18:47 <geekosaur> AWizzArd, Num is not a type
18:47 <geekosaur> and while there is a way to write that "properly" I suspect it won;t do what you want it to do
18:47 <ChaiTRex> Tuplanolla: That looks interesting. Thanks :)
18:48 <geekosaur> remember that typeclasses indicate the maximum interface, not the minimum. Num a => a means all you can use on it are the methods of Num --- not those of e.g. Fractional, or Integral, or etc.
18:48 <AWizzArd> Okay, makes sense.
18:49 SpaceGazebo3 joined
18:50 cur8or joined
18:50 <dcz__> geekosaur: thanks for your help and patience
18:51 <lexi-lambda> jml: can I ask you a question about your graphql-api package?
18:52 <infandum> Thank you everyone!
18:54 <Guest39376> hashcat benchmark for nvidia gtx 1050 and gtx1050ti
18:55 locallycompact joined
18:58 Achylles joined
19:00 ysahil joined
19:01 cpup joined
19:01 crobbins joined
19:02 iomonad joined
19:05 snowalpaca joined
19:05 latencyloser joined
19:07 wroathe joined
19:08 fizruk joined
19:11 bhiliyam joined
19:11 mekeor joined
19:13 <dcz__> geekosaur: why map function doesnt work on x? x <- listDirectory y, f <- map (++ "f") x
19:14 <geekosaur> dcz__, you can;t use <- with that, you must use let
19:14 <geekosaur> you should also sit down with an IO tutorial so that you can recognize the difference
19:14 <dcz__> :D haha okey
19:14 <geekosaur> http://www.vex.net/~trebla/haskell/IO.xhtml
19:15 <dcz__> thank you very much
19:16 mda1 joined
19:16 iAmerikan joined
19:17 Destol joined
19:18 l_zzie joined
19:19 <jml> lexi-lambda: sure. my rates are very reasonable.
19:20 <lexi-lambda> jml: :)
19:20 zariuq joined
19:20 <jml> lexi-lambda: but probably best to ask it as a question on Github (or SO I guess, and then link me here). I'm just about to head offline
19:21 Mysterious_Light joined
19:21 <lexi-lambda> Alright, I'll try and do that. I actually just left for lunch, but I'll type it up when I get back.
19:22 anuxivm joined
19:24 Itkovian joined
19:24 holla joined
19:25 augur joined
19:26 phaji joined
19:26 dreco joined
19:26 ChaiTRex joined
19:26 Itkovian joined
19:27 wroathe joined
19:28 gcross_ joined
19:28 pavonia joined
19:28 zargoertzel joined
19:29 psychici1t__ joined
19:29 mbw joined
19:30 RoyalNightGuard joined
19:30 jespada joined
19:32 <mbw> The API for immutable Vectors exposes a lot of convenient functions for doing index-based work, for example ifoldr :: (Int -> a -> b -> b) -> b -> Vector a -> b. Is there any way to use these functions with mutable vectors? Do I have to unsafeFreeze them first?
19:32 nagyf joined
19:33 <ph88^> oh lyxia don't spoil me plz :P
19:33 <ph88^> oh it's not a unboxed mutable vector ..
19:33 shayan_ joined
19:33 bennofs joined
19:34 <lyxia> mbw: there aren't a lot of combinators for mutable vectors unfortunately
19:34 JuanMiguel joined
19:34 Itkovian joined
19:34 <lyxia> unsafeFreeze is dangerous because you have to make sure to force values you compute with it before mutating the vector further
19:35 phaji joined
19:36 <lyxia> ph88^: that wouldn't be purely functional!
19:36 <mbw> lyxia: Assuming that the restricted API is a design decision, and I really need to do destructive updates, am I "supposed" to write explicit go functions or use forM_ and the like?
19:37 cpup joined
19:37 <ph88^> lyxia, i care about speed mostly .. by the way i also found this https://hackage.haskell.org/package/combobuffer
19:38 <lyxia> oh interesting I hadn't seen it
19:38 wroathe joined
19:39 <ph88^> lyxia, also found this https://johnlato.blogspot.nl/2011/07/circular-buffers.html
19:39 <qmm> https://aphyr.com/posts/342-typing-the-technical-interview
19:40 <lyxia> mbw: using forM_ is better because it is more explicit about control flow
19:41 <ph88^> ertes, you should check out that article
19:41 <ph88^> "It looks like not only is the Seq-based implementation pure, it outperforms my mutable-vector implementation and scales better too. Completely unexpected.
19:41 <ph88^> "
19:41 SimpleL joined
19:41 taksuyu joined
19:42 oisdk joined
19:42 Lord_of_Life joined
19:43 Itkovian joined
19:43 boombanana joined
19:44 dsh joined
19:46 <lyxia> using Foreign seems like a bad idea
19:47 <ph88^> lyxia, ok so another reasion to go with the seq-based implementation then
19:47 <mbw> lyxia: Does the Generic interface change anything in this regard? I don't really understand the documentation. What does the generic interface allow me to do?
19:48 wroathe joined
19:48 SpaceGazebo3 joined
19:49 brandon-stiles joined
19:49 SpaceGazebo3 joined
19:49 <lyxia> mbw: all other vector interfaces are just specializations of the generic interface
19:49 <ertes> ph88^: i don't believe it before i test it myself… it just doesn't make sense
19:50 darjeeling_ joined
19:50 <lyxia> mbw: So you'd use Generic if you want to write algorithms working with multiple vector types (Boxed/Unboxed/Storable).
19:50 <ertes> ph88^: i'll write a short benchmark of my own later
19:51 <ertes> he's right about scalability though… a ring buffer has a fixed size
19:51 iAmerikan joined
19:51 <ertes> so you need to pick the maximum size beforehand
19:51 <ph88^> ertes, that's quite the challange you've set yourself :P
19:52 <ertes> ph88^: hmm? what?
19:52 fotonzade joined
19:52 <ph88^> write such a benchmark
19:52 <mbw> lyxia: Since I saw that Data.Vector.Generic exports ifoldl etc., would I be able to use this version on mutable vectors?
19:52 <ph88^> or you just gonna use the same code as the author ?
19:53 <ertes> no, i'll write my own
19:53 ziocroc joined
19:53 <mauke> qmm: hahaha
19:54 <lyxia> mbw: no mutable and immutable vectors are still strongly separated
19:54 <mbw> While it might be a personal choice to use explicit loops, I can write that kind of stuff more concisely in C++ or even Fortran...
19:55 <lyxia> I guess the API for mutable vectors could use some work
19:55 <lyxia> I hope there is an open issue about that.
19:56 <lyxia> https://github.com/haskell/vector/issues/159
19:57 SimpleL joined
19:57 fizruk joined
19:58 iAmerikan joined
19:58 wroathe joined
19:58 chaosmasttter joined
19:59 <mbw> At least the author is not MIA.
19:59 <AWizzArd> Out of curiosity: does anyone here have an extremly fast cpu and can report the compile times for a big Haskell project (maybe ghc or ghcjs)?
20:00 shainer joined
20:00 cdg joined
20:02 jeltsch joined
20:02 bungoman joined
20:03 blocus joined
20:04 locallycompact joined
20:04 meoblast001 joined
20:04 jeltsch joined
20:05 ysahil joined
20:06 phaji joined
20:07 ysahil joined
20:07 <koala_man> AWizzArd: You could rent a beefy EC2 box for an hour for ~$2. if it helps, I have a 24 core VM with what appears to be 2.5Ghz Haswell
20:07 <ph88^> does this parser also apply for Data.Attoparsec.Bytestring.Lazy ? https://hackage.haskell.org/package/attoparsec-
20:08 hexfive joined
20:08 wroathe joined
20:10 <ph88^> i guess one is suppose to combine lazy and strict parsers here
20:10 <ph88^> i see only examples with this
20:10 snowalpaca joined
20:10 <lyxia> ph88^: yes the only difference is the parse function, the Parser type is the same.
20:11 EvanR_ joined
20:12 hvr joined
20:12 hvr joined
20:12 bhiliyam joined
20:12 mbw joined
20:12 Itkovian joined
20:13 iAmerikan joined
20:13 nick_h joined
20:15 <mbw> One more thing. Since I saw some people discussing performance-related stuff, I presume people use criterion. I encountered the problem that when I have two benchmark groups with four benchmarks each, the .html output is basicall broken. That is, no diagrams are shown and the regressions just say "OLS: xxx". It's probably not related to the number of benchmarks, but to some subtleties in the benchmarks
20:15 <mbw> themselves (which are just simple summations with different folds). Has anyone encountered this problem, too?
20:16 Ferdirand joined
20:16 <mbw> I'll just paste them.
20:16 zcourts_ joined
20:16 Itkovian_ joined
20:17 EvanR_ joined
20:17 <mbw> http://lpaste.net/354495 . Can anybody reproduce this?
20:18 <mbw> Needs an additional main = benchSum.
20:18 <lyxia> I have encountered something like this before, but haven't investigated it.
20:20 <lyxia> I think criterion is hittin NaNs somewhere.
20:21 <lyxia> it correlated with the fact that R^2 was getting closer to 1.
20:21 <brandon-stiles> Hi. I'm trying to use GHCJS and JS FFIs to use a JS SVG library, but I'm having a hard time figuring out how to use callbacks, or what the proper (reflex-frp) way of doing this: https://gist.github.com/stilesb/9d26ebd4c18ba1c29c06e7566f7418af. Are there any people here with experience working with GHCJS and JS FFIs?
20:21 <* geekosaur> thinks the core for that might be nice... if somehow they get optimized away in that specific form, criterion would likely be doing a divide by 0 on the time :)
20:21 <lyxia> mbw: have you tried with smaller lists
20:21 sabalaba joined
20:22 <ph88^> ertes, just for me to get going i was thinking to try this one https://hackage.haskell.org/package/combobuffer-0.2/docs/Data-RingBuffer-SeqBuffer.html what do you think ?
20:22 path[l] joined
20:22 <mbw> lyxia: Indeed NaNs are shown in the console output. I haven't tried with smaller lists yet, I'll do that now. I just wanted to ask if this was a common problem.
20:23 <ertes> ph88^: no, i wrote my own… it does 1e7 steps in 400 ms on my machine
20:24 <ph88^> ertes, can i have yours ?
20:24 <ertes> i wrote a probabilistic benchmark (but with a fixed seed) that does 70% pushes and 30% pops
20:24 <ertes> gimme a second, i'm still optimising the Seq variant
20:24 <ph88^> combobuffer is too old and has dependency conflicts
20:24 mda1 joined
20:24 <ph88^> ok
20:24 <ertes> currently it uses memory proportional to the number of steps, so there is obviously something wrong
20:24 <ph88^> ok
20:25 fizruk joined
20:25 cur8or joined
20:26 Berra joined
20:26 iAmerikan joined
20:27 mtesseract joined
20:27 blocky joined
20:28 <mbw> Btw, from the help menu introduced by criterion's default main, should I be able to infer the possible verbosity levels? I actually looked inside the source on hackage, saw that a sum type with three values and an Enum instance is used and thought it's probably 0-2...
20:29 wroathe joined
20:29 <mbw> Ok, tests are finished. If I decrease the lists by a factor of 10, it works. Increasing them again now causes all but the first two tests to fail to produce the diagrams. So it's not really *that* reproducible.
20:31 tathougies joined
20:32 albertus1 joined
20:32 <mbw> I should check github more often (don't even have an account :/). Seems to be this issue: https://github.com/bos/criterion/issues/65
20:33 ali_bush joined
20:37 Achylles joined
20:37 orbifx joined
20:39 wroathe joined
20:39 simendsjo joined
20:39 Itkovian joined
20:40 <ertes> ph88^: the ring buffer version is about twice as fast as the Seq version… i didn't expect the difference to be as small as it is, but it does meet my expectation that the ring buffer version is faster
20:40 <ertes> with that in mind i think i would recommend the Seq version
20:40 <ertes> let me paste my code
20:40 <ph88^> ertes, you mean the one based on mutable unboxed vector ?
20:41 <ertes> yeah
20:41 tathougies joined
20:42 tathougies1 joined
20:42 <ph88^> ertes, for my curiousity .. do you have any idea about the differences between your benchmark and the one from that post ?
20:42 <ertes> ph88^: https://github.com/esoeylemez/snippets/blob/master/ring-buffer-bench.hs
20:42 <ertes> no, sorry
20:42 <ertes> but i did try to write a highly optimised ring buffer
20:43 <ertes> you can probably speed it up by using specialisation and/or inlining
20:44 slacker joined
20:44 <ph88^> ertes, shouldn't the rbBench and the seqBench be driven by the same data ?
20:44 <ertes> interesting… inlining made it *worse*
20:45 <ertes> they are driven by the same data
20:45 <ertes> the seed is fixed
20:45 <ertes> i'm using 'create' instead of 'createSystemRandom'
20:45 <ph88^> ertes, can i link your code from a github issue ?
20:45 <ertes> sure
20:45 <ertes> (even when using a random seed the results should be fairly similar)
20:46 <ertes> real 3.990 user 3.977 krnl 0.011 cpu% 99% mem 4m ./ring-buffer-bench 100000000 vu
20:46 <ertes> real 6.907 user 6.880 krnl 0.027 cpu% 99% mem 4m ./ring-buffer-bench 100000000 s
20:46 <ertes> these are my timings
20:47 <ertes> the unboxed ring buffer version finishes in about 4/7th of the time of the Seq version
20:48 electrostat joined
20:49 wroathe joined
20:49 <ph88^> ertes, why would you recommend the Seq version? I am quite confident that you wrote a nice vector implementation :P
20:49 <ertes> ph88^: i've just pushed a small change… you can now benchmark with different buffer sizes
20:49 <EvanR_> please tell me that ring buffer produces audio without drop outs
20:50 <ertes> if you change the ring buffer size from 1000 to 10000, there is no measurable time difference
20:50 <ertes> however, the Seq version now uses almost 10 secs
20:51 <ph88^> ertes, could compare it to https://github.com/bgamari/ring-buffer/blob/master/src/Data/RingBuffer.hs
20:52 <ertes> ph88^: that version is almost certainly worse… not necessarily by much, but worse nonetheless
20:53 <ertes> 'mod' is rather slow
20:53 <EvanR_> i heard quot is faster
20:53 <EvanR_> er, rem
20:53 <ertes> i've also not used 'min', because i can save one addition by doing it manually
20:53 <ertes> EvanR_: only for Integer
20:53 <ertes> for Int there should be no difference
20:54 <EvanR_> huh... Integer uses Int most of the time
20:54 <ph88^> well hhmm since those are all the implementations of ring buffers i round and yours should be the fastest might be worth packaging it
20:54 <ph88^> can i go back to the original problem statement for a moment ?
20:54 slacker joined
20:54 <ertes> let me benchmark with mod and rem
20:54 <ph88^> ok
20:55 <monochrom> Although Integer uses Int most of the time, there is still the overhead of asking "am I in the Int case?" every so often.
20:55 <ertes> ah, i can't even use rem =)
20:55 <ertes> i need mod, because i'm subtracting
20:56 <ertes> though pop can use rem, gimme a minute
20:56 <ertes> anyway, 'mod' made the run-time jump from 400 ms to 500 ms
20:56 <monochrom> Basically an Either type with a statistical fact "it is Left 99% of the time".
20:56 cpup joined
20:57 <ertes> 'min' made a much smaller difference: ~400 ms → ~420 ms
20:57 SpaceGazebo3 joined
20:57 hive-mind joined
20:57 ChaiTRex joined
20:58 <ertes> i can't use 'mod' in pop either, because i have a short circuit there
20:58 <monochrom> mod has quite a bit more conditional branching and fixup than rem.
20:59 <monochrom> Because rem maps to an x86 instruction but mod doesn't.
20:59 EvanR_ joined
20:59 wroathe joined
20:59 <ertes> i think 'rem' is still slower in this case, because the conditional branch should be almost free with prediction
21:00 <mbw> Is there a specific reason why Unboxed vectors aren't Functors/Foldable etc.?
21:00 Crescent joined
21:00 <Tuplanolla> The same reason `Set` is not either, mbw.
21:00 <ertes> mbw: unboxedMap :: (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
21:01 cmsmcq joined
21:02 <ertes> alright, i have tried to optimise RingBuffer, but i'm giving up… i don't think there is any room left for optimisation other than tweaking GHC flags
21:03 <ph88^> sweet
21:03 <mbw> ertes: Ok, that's neat. But there is probably a reason why Unboxed Vectors can't just be made Functors, right? Like the TypeFamilies thing?
21:03 <ertes> mbw: the reason is that there are constraints on the element type
21:04 Itkovian joined
21:04 <ph88^> ertes, why you choose to save the length in the RingBuffer ?
21:05 <ertes> ph88^: it's not the length of the ring buffer, but the current number of elements in the ring
21:05 <ph88^> ye i know
21:05 <ertes> ph88^: what would you do instead?
21:05 <ertes> oh… wait a minute
21:06 <ph88^> well in only designed ring buffers in hardware
21:06 <ertes> i haven't implemented a ring buffer, but a stack =)
21:06 <ertes> let me fix it
21:06 <ph88^> i would use a read and a write counter
21:07 <ph88^> ertes, this is the best implementation of ring buffers i've seen so far https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
21:07 <mbw> ertes: Ok thanks. It actually becomes clear once you try to implement it yourself.
21:08 dsfox1 joined
21:08 jgertm joined
21:09 t7 joined
21:10 wroathe joined
21:10 <ph88^> lol .. What kind of a monster would make a non-power of two ring? The kind that ran out of microcontroller SRAM for a large enough power of two ring, but could spare CPU cycles for an expensive modulo operation.
21:11 azahi joined
21:12 bhiliyam joined
21:13 gabluc joined
21:14 ryxai joined
21:16 darlan joined
21:17 bjz joined
21:18 Micamo joined
21:19 <mbw> Is there a way to pinpoint the exact cause of memory locations? Say I have located the function using time and heap profiles, where do I go from there? I know that I can make a more specific heap profile on a module basis or for specific constructors only. But what if in the end it's just something like PINNED or ARR_WORDS? Is there a way to approach this more systematically?
21:20 <mbw> I am of course still implicitly referring to my struggle with the vector library...
21:21 <ph88^> what you need the memory locations for
21:23 flatmap13 joined
21:23 <dcz__> geekosaur: thank you very much, i am like enlightened. really appreciated for the tutorial
21:24 <dcz__> i can't believe that for the first time i did something what i am doing :D
21:24 <dcz__> i know what i am doing first time :D
21:25 <mbw> I was implementing some example code from the book "Haskell High-Performance Programming". Specifically, a bubblesort implementation using mutable vectors. The authors claimed a runtime of 1.55 sec or something for a vector of 10000 random elements. For me it was something like 2 minutes initially. I was able to reduce it to 15 seconds or so, but there are still a surprisingly large number of allocations
21:25 <mbw> involved. I pinpointed it to a function that does a foldM on an immutable vector of indices (which I had to float out manually with a let binding, since it was regenerated every time). The iteration is mapped on swapping vector elements. I wouldn't expect many allocations for that.
21:25 SpaceGazebo3 joined
21:25 <mbw> The swap routine should be able to allocate temps on the stack if the values are unboxed, the way I understand it.
21:26 <mbw> To be honest, I didn't go for the full go function yet.
21:26 <kuribas> mbw: are you using an unboxed vector?
21:26 <mbw> Yes.
21:27 <kuribas> mbw: you aren't copying vectors?
21:27 <mbw> s/iteration/iteration\ space/.
21:27 <kuribas> mbw: you should use ST monad for mutating the vector.
21:27 phaji joined
21:28 <brandon-stiles> Ah! Here we go, this looks like it works: https://github.com/ghcjs/ghcjs/blob/master/doc/foreign-function-interface.md
21:28 ysahil joined
21:28 <kuribas> mbw: you could try to see if fusion works, but it may not kick in.
21:28 <kuribas> mbw: also for fusion you must enable optimizations.
21:28 <mbw> The bubblesort just invokes a bubblesortM function that works on mutable unboxed vectors (though with a polymorphic signature, like in the book). I replaced the runST $ do ... stuff with create and it didn't make a difference.
21:29 <kuribas> mbw: mutating an unboxed vector shouldn't do any allocations.
21:29 <mbw> Yeah I did compile it with -O2. Haven't figured out how to use -fllvm though, since I have multiple versions installed.
21:30 wroathe joined
21:30 <kuribas> that shouldn't be necessary
21:30 <kuribas> unless you want SIMD
21:30 <mbw> Then that is the reason I'd like to find out exactly what is causing those allocations. And I don't want to do this by trial-and-error, it should be clear that this is for pedagogical reasons :)
21:31 <ph88^> mbw, for llvm you need 3.5 and have the 2 binaries in path
21:31 <mbw> To be honest, I did it inside a stack project with a Lib.hs and a Main.hs.
21:32 <mbw> ph88^: I think it's 3.7 by now, and according to the ghc page 3.9 for HEAD.
21:32 <ertes> ph88^: fixed
21:32 <ertes> and still same speed
21:32 <mbw> I do have them installed, but have to figure out this update-alternatives thing.
21:32 <ph88^> mbw, i think a month ago or so it was still at 3.5 then
21:32 raynold joined
21:32 <ph88^> ertes, you ask me how would i done it, take a look at https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
21:33 <mbw> Are you using GHC 8.0?
21:33 <ph88^> ye
21:33 <ph88^> what's left and right now ?
21:33 chichou joined
21:33 <kuribas> mbw: could you plast some code?
21:33 <kuribas> mbw: paste
21:34 <ph88^> ertes, left - write counter, right - read counter ?
21:34 <mbw> https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/LLVM/Installing
21:34 <mbw> Sure thing.
21:35 <ertes> ph88^: i'm using that approach, except that i'm using -1 instead of i + 1
21:35 <ph88^> ok
21:36 <ertes> doesn't make a difference, because you need the branch on emptiness anyway
21:37 <ertes> in fact i believe my approach is even better, because i can check for emptiness without arithmetic
21:37 SimpleL joined
21:37 <ertes> as you see in rbPop, i'm not even asking for the second index, if the buffer is empty
21:38 Gurkenglas_ joined
21:38 darjeeling_ joined
21:38 xcin joined
21:38 <mbw> Here it is: http://lpaste.net/354496 .
21:39 <mbw> I think I had an inline pragma for f at some point, and removed it.
21:40 wroathe joined
21:41 Itkovian joined
21:41 cchalmers joined
21:43 dpren joined
21:43 <ph88^> ertes, *** Exception: user error (Pattern match failure in do expression at /home/ph88/haskell/ring/src/Main.hs:115:5-32)
21:44 <ph88^> oh some args suppose to go there
21:44 <ph88^> how can i call main with some arguments from ghci ?
21:45 <geekosaur> ph88^, use :main
21:45 <mbw> :set args should work
21:46 <geekosaur> or, import System.Environment and use withArgsDo
21:47 <ph88^> ertes, i want to test it, but i can't so quickly
21:47 <ph88^> i will test it tomorrow
21:47 <ph88^> can i ask a question about the original problem ?
21:48 locallycompact joined
21:49 <kuribas> mbw: your indices array may cause allocations...
21:49 deech joined
21:49 Jesin joined
21:49 <ertes> ph88^: try this: ./test 1000 10000000 vu
21:49 <adarqui> hi. how can i simplify my "forever alone" haskell line, so that it only has "forever" and "()", and perhaps one infix operator.. ie, forever $ pure () , would be nicer if it was: forever =<< ()
21:50 <deech> Hi, how do I file a bug against `syb`? The issues page is Google Code archive https://code.google.com/archive/p/scrapyourboilerplate/issues.
21:50 <ertes> ph88^: this selects the unboxed vector variant with a ring buffer of size 1000 and 10000000 iterations
21:50 <mbw> kuribas: To be fair, it's more or less the implementation from the book (probably a sales pitch for the clever fusion stuff).
21:50 <ph88^> ertes, yeah i mean go deeper into the algorithm and check the assumptions you made there .. but ye ok i can run the benchmark ..
21:50 <ertes> ph88^: options other than "vu" include "vb" (boxed vector) and "s" (Seq)
21:50 epsilonhalbe left
21:50 <kuribas> mbw: fusion isn't always predictable
21:51 <geekosaur> deech, I'd try https://github.com/dreixel/syb/issues
21:51 <geekosaur> since that's the clone url
21:51 <geekosaur> (with the issue tracker appended_
21:51 <deech> Nice, thanks!
21:51 daishi joined
21:52 <kuribas> mbw: also indices is used twice, so it may not be inlined...
21:53 <ph88^> ertes, vu is the fastest here
21:53 Jesin joined
21:53 pungi-man joined
21:53 hiratara joined
21:53 fizbin joined
21:53 <mbw> I would try to profile it again, but stack decided to rebuild the dependencies...
21:54 <mbw> Can I safely ^C it?
21:54 <mbw> I forgot I added criterion to the dependencies, with a different resolver.
21:54 <lexi-lambda> jml: I asked a question on stack overflow http://stackoverflow.com/q/43333486/465378
21:54 <kuribas> mbw: try inlining it yourself...
21:55 <kuribas> mbw: and compare with an explicit loop.
21:55 <pungi-man> Hey! I have just started with haskell today. I installed stack on my ubuntu laptop and I tried running the command `stack setup`. I am getting this error. http://paste.ubuntu.com/24357062/ . Now I am under a proxy and I can't always comment out the variable when developing haskell because my other functionality will not work. Is there a solution for my problem?
21:56 futuristic joined
21:56 sellout- joined
21:56 <ChaiTRex> pungi-man: If it's an environment variable, try VARIABLE_NAME="" stack setup
21:56 alx741_ joined
21:57 <ChaiTRex> pungi-man: So like: https_proxy="" stack setup
21:58 <pungi-man> ChaiTRex: Thanks! I think that error is solved. But now there is another error. "HostCannotConnect "s3.amazonaws.com" [connect: does not exist (Connection refused)]"
21:58 willprice joined
21:58 <mbw> kuribas: I'll try that in a minute, once stack is finished building.
21:58 <pungi-man> http://paste.ubuntu.com/24357086/
21:58 <ChaiTRex> pungi-man: That's a weird error message, since it has to exist to get a connection refusal.
21:58 e14 joined
21:58 <scav> Is there something I am not getting? If I replace the second last 'y' with an x, it works just fine. fn :: (x -> y) -> y -> y; fn xy x = xy x
21:58 <ChaiTRex> pungi-man: Not sure what to do about that.
21:58 <ertes> ph88^: yeah, as expected
21:59 <mbw> kuribas: But still, this is all very ad-hoc...
21:59 <ertes> ph88^: also it scales much better, because you can pretty much select arbitrary ring buffer sizes without changing the performance
21:59 epsilonhalbe1 joined
21:59 <kuribas> mbw: you could look at the core for more information :)
21:59 epsilonhalbe1 left
22:00 <ski> scav : the argument type of the function `xy' must be the same as the type of the actual argument you pass to it, namely `x'
22:00 chenshen joined
22:00 <pungi-man> ChaiTRex: Okay thanks! I just started out today so I don't know many things. Does stack try to download something while running `stack setup`? If that's so, can I download it using something else and pass it to `stack setup`?
22:00 <ertes> ph88^: if you find this useful, i can turn it into a library tomorrow
22:00 e14 joined
22:00 <scav> ski so if i were to pass in 'y', it should work?
22:00 darlan joined
22:01 <geekosaur> pungi-man, https://github.com/commercialhaskell/stack/issues/1165 suggests stack doesn't do what you need
22:01 <ChaiTRex> pungi-man: I'm not sure about that, sorry.
22:01 <ski> scav : there's no (value-level) variable named `y' in that snippet of code
22:01 <geekosaur> stack setup wants to download a package index. I don't know if you can do that manually
22:01 <scav> ski then I guess I should go back and read some more :)
22:01 <scav> thanks!
22:01 <ph88^> ertes, i'd love that
22:02 <ski> scav : it might perhaps help unconfuse things a bit (either for you, or for people trying to help, or both), if you didn't use the same name for a value variable as for a type variable ..
22:02 <pungi-man> geekosaur: Thanks a lot! That worked for me :)
22:02 <ph88^> ertes, i like to talk a bit how i'm gonna use the ring buffer with the program .. but i'm dead tired from kayak still and i have to work tomorrow. Nice effort on the ring buffer, talk later, byeee
22:03 <geekosaur> ah, so yours will let you http? then you're ok. it's specifically using an https: url for an https proxy that stack apparently does not support
22:03 <scav> ski thank you, noted :)
22:03 <ertes> ph88^: sure… good night =)
22:04 <pungi-man> geekosaur: Yes it is allowing http.
22:04 <ski> scav : .. when you're more familiar with the type system, it can sometimes help, though
22:04 <kuribas> mbw: you could try if specialization helps, but it probably gets specialized by ghc...
22:04 fizbin1 joined
22:04 darlan joined
22:05 <scav> ski sure, thank you for the feedback and tip
22:05 <ski> (people trying to help could be confused about whether you're confused about the value or the type variable, if you don't say explicitly)
22:06 <mbw> kuribas: Compiling with -Weverything will emit warnings like "Could not specialize[...]". Of course this is not a proof that everything not warned about was specialized...
22:06 <mbw> kuribas: Did you try running it?
22:07 ccomb1 joined
22:08 <kuribas> not yet...
22:10 wroathe joined
22:11 b4ff3r joined
22:12 cmsmcq_ joined
22:12 <kuribas> mbw: I get 36 sec without specialize, 32sec with
22:12 darjeeling_ joined
22:13 beanbagula joined
22:13 ebzzry joined
22:13 bhiliyam joined
22:14 <mbw> I should be done building anytime now... (Currently the machine is swapping :( )
22:14 fizbin joined
22:15 augur joined
22:15 zcourts joined
22:16 e14 joined
22:17 LnL joined
22:19 <mbw> kuribas: According to the book's author it took 1.55 sec for him. That is using the polymorphic signature and boxed vectors.
22:19 <kuribas> mbw: I am downto 30 with V.EnumFromN
22:19 <kuribas> mbw: maybe he has a supercomputer?
22:20 <mbw> He actually mentions GHC 8.0 extensions etc., so he probably used that as well...
22:20 SpaceGazebo3 joined
22:20 <kuribas> I have ghc 8.2 ...
22:20 <mbw> Oh, has it been released already?
22:20 <geekosaur> rc1
22:21 SpaceGazebo3 joined
22:22 <mbw> Oh boy am I looking forward to my vim plugins failing again.
22:23 <mbw> kuribas: Couldn't this be inside the tolerance?
22:24 hexfive joined
22:25 <kuribas> what tolerance?
22:25 dan_f joined
22:25 <mbw> The times you measured. 30 vs. 32 or even 36. Are they reproducible?
22:25 rotcpy joined
22:26 <mbw> I'm starting to get the impression bubblesort sucks D:
22:26 <EvanR_> lol
22:27 <EvanR_> n^2
22:27 l_zzie joined
22:27 dcz__ joined
22:29 <mbw> If my machine is just a _little_ slower, would that "propagate" quadratically as well?
22:30 l_zzie joined
22:30 <mbw> Sorry if that's a stupid question, it's been a long day...
22:30 anuxivm left
22:31 hiratara joined
22:31 <dcz__> how can we flip map arguments ? for example i do , map list (++ "F"), other then this "F"++EachListElement
22:31 l_zzie joined
22:32 <Tuplanolla> :t flip map -- Just ask, dcz__.
22:32 <jle`> dcz__: not sure i understand your question, but you can use flip?
22:32 <lambdabot> [a] -> (a -> b) -> [b]
22:32 <jle`> > flip map [1..10] succ
22:32 <lambdabot> [2,3,4,5,6,7,8,9,10,11]
22:32 <dcz__> i did it actually but doesnt work like i imagined, still adding to the end
22:33 <geekosaur> dcz__, do you want to flip the arguments to map itself, or those to the mapping function?
22:33 <jle`> what are you trying, and what result do you get, and what result do you want?
22:33 <geekosaur> the latter is ("F" ++)
22:33 <dcz__> i have files list and i want to add something to the end
22:33 <jle`> can you show an example
22:33 <dcz__> sorry to the beginng not the end
22:33 <jle`> > map (++ "F") ["abc","def","ghi"] -- ..?
22:33 <lambdabot> ["abcF","defF","ghiF"]
22:33 <jle`> > map ("F" ++) ["abc","def","ghi"] -- ..?
22:33 <dcz__> sorry to the beginng not the end
22:33 <lambdabot> ["Fabc","Fdef","Fghi"]
22:34 <dcz__> i did this too, ugh :D
22:34 <jle`> or you can write the explicit function
22:34 <dcz__> one moment
22:34 <jle`> > map (\x -> "F" ++ x) ["abc","def","ghi"]
22:34 <lambdabot> ["Fabc","Fdef","Fghi"]
22:34 <jle`> > map (\x -> x ++ "F") ["abc","def","ghi"]
22:34 <lambdabot> ["abcF","defF","ghiF"]
22:34 <jle`> your function can really be whatever you want
22:34 bjz joined
22:35 <dcz__> here is the function and the error ,
22:35 <dcz__> https://hastebin.com/zusizenafa.hs
22:35 l_zzie joined
22:37 <joe9> what is a good material to learn about kinds? I am clueless when the parameters in the function definition. such as in this line : instance (GIBFormat f, Constructor c) => GIBFormat (M1 C c f) where , I cannot figure out how to get more details on the C, c and f
22:37 <dcz__> omg , it was because of i did not put these around () that?
22:38 <dcz__> fIOtFs a b = map ((b++"/") ++) a , this worked
22:38 <geekosaur> yes, section syntax is a bit finiky
22:38 <geekosaur> *finicky
22:39 <jle`> if you are having problems, you can also just write the explicit lambda
22:39 fizbin joined
22:39 <jle`> map (\x -> b ++ "/" ++ x)
22:39 <geekosaur> it doesn't udnerstand associativity, so it doesn't know which operator is to be the one the section applies to
22:39 <jle`> also i'd suggest that you use something like </> instead of ++ "/"
22:40 <dcz__> okey cool
22:41 oisdk joined
22:41 wroathe joined
22:42 <jle`> just as a different issue :)
22:42 <jle`> unrelated.
22:43 kuribas joined
22:44 <kuribas> mbw: I had to restart my computer, because my modifications caused a space leak.
22:44 anderson joined
22:45 <mbw> That's one hell of a space leak.
22:45 contiver joined
22:45 <kuribas> yeah
22:46 <kuribas> I don't get why the kernel doesn't just refuse to give memory that isn't there...
22:47 <mbw> I only had to hard-reset when I didn't have designated scratch space. I made an 8G swap file since then.
22:48 sellout- joined
22:48 <EvanR_> kuribas: performance
22:48 <EvanR_> but you can change it to act that way
22:48 <Tuplanolla> I learned that lesson and always run with `+RTS -M1GM`, kuribas.
22:48 <kuribas> EvanR_: I should disable swap, it's useless anyway.
22:49 <kuribas> Tuplanolla: ok, thanks
22:49 <monochrom> I think you don't want the 2nd M, but yeah.
22:49 <Tuplanolla> Right you are, monochrom.
22:49 <mbw> Megagigs?
22:50 e14 joined
22:51 coltfred joined
22:52 <monochrom> ghc -j65536 +RTS -M1000000G :)
22:52 Achylles joined
22:52 <mbw> That's how the NSA does it.
22:53 <mbw> They probably use GHC 9.0, too
22:53 <bollu> is there a "pure" way of colorising ANSI text?
22:54 <int-e> monochrom: you seem to be exceeding the addressable space for current 64 bit systems
22:54 <bollu> every library seems to invoke IO, but I though that ANSI color escapes were well established?
22:54 <monochrom> Oh oops
22:54 <kuribas> mbw: I think that's a bug btw...
22:54 <mbw> What is?
22:55 <monochrom> Ah we could revive the EMS trick used during the 8088 days.
22:55 <monochrom> ghc -j65536 +RTS -M1000000G -fEMS :)
22:56 <glguy> bollu: for some control sequences it's not enough to emit a particular set of characters with a normal write
22:56 <bollu> glguy: I see :(
22:56 <mbw> monochrom: What does that do? Is it some segmented memory voodoo?
22:57 EvanR_ joined
22:57 <int-e> mbw: it's a hardware mechanism that allows swapping out the physical memory that underlies a fixed window in the physical address space.
22:58 <geekosaur> bollu, glguy, actually what I see is that most of them want to support Windows, and until Windows 10 you couldn't do it with escape sequences, you had to call device control functions
22:59 <bollu> geekosaur: hm, are you aware of any library that is pure?
22:59 <Tuplanolla> @hackage ansi-terminal
22:59 <lambdabot> http://hackage.haskell.org/package/ansi-terminal
23:00 <geekosaur> Tuplanolla, that's not pure, all the functions are in IO
23:00 <Tuplanolla> See "strawberry", bollu.
23:00 <bollu> Tuplanolla: yeah, but windows 10 has the fancy linux subsytem thing
23:00 <geekosaur> also, the ones that don;t go for Windows compat use terminfo
23:00 rotcpy joined
23:00 <geekosaur> so also can't be pure
23:00 <monochrom> mbw: https://en.wikipedia.org/wiki/Bank_switching
23:00 <bollu> oh, wait what, I can change to "Strawberry"?
23:00 a3Dman joined
23:01 <Tuplanolla> You can just ignore all the `IO` functions, bollu.
23:01 <bollu> Tuplanolla: cool, ty :)
23:01 <bollu> Tuplanolla: much appreciated
23:01 wroathe joined
23:01 <mbw> Thanks for the link.
23:01 <mbw> And the explanation.
23:02 zero_byte joined
23:02 EvanR_ joined
23:03 cables joined
23:03 chenshen joined
23:04 cables joined
23:04 <bollu> quick offtopic question if I may: how does one touch type "+", "-" and "?" I'm trying to unlearn fucked typing habits.
23:05 <Tuplanolla> How does one touch type Alt + F4?
23:05 dfeuer joined
23:05 <bollu> I have no idea
23:05 <ChaiTRex> bollu: For the outer ones, press shift with one hand and the key with the other hand.
23:06 <bollu> ChaiTRex: ah, thanks, that may help
23:06 <ChaiTRex> Tuplanolla: You can probably do that with your left hand, thumb on alt and middle finger on F4.
23:06 <Tuplanolla> I've developed some kind of semitouch typing where my hands wander and fingering patterns are correlated in time.
23:07 Majiir joined
23:07 <mbw> kuribas: What bug were you talking about?
23:07 <Tuplanolla> I can't imagine trying to teach it to anyone.
23:07 <kuribas> mbw: A bug that causes a space like with -O2
23:07 <kuribas> leak
23:08 <kuribas> mbw: and with a nested monad
23:09 oisdk_ joined
23:10 EvanR_ joined
23:11 <mbw> The version I got currently runs in constant space, with 15M maximum residency or so.
23:12 <mbw> Right now I am trying to make some sense out of the profiler output. Is there some way to visualize it as a call graph or make it more concise? Everything runs off to the right.
23:13 ali_bush joined
23:13 ali_bush joined
23:14 <mbw> kuribas: Did you use nested forMs? I think there is an open bug on the ghc page.
23:14 nakal_ joined
23:14 bhiliyam joined
23:14 markus1209 joined
23:14 markus1219 joined
23:14 <kuribas> mbw: no, just a handrolled loop.
23:16 doomlord joined
23:16 iqubic joined
23:16 <mbw> So what did you need nested monads for? As i understand it, a handrolled loop is a strict go function.
23:16 beanbagula joined
23:17 zcourts joined
23:17 <iqubic> What does Data.Complex gain from having Monad, Applicative, and Functor instance? As well as Foldable???
23:17 Koterpillar joined
23:17 jmcarthur joined
23:18 theDon_ joined
23:18 jbiesnecker joined
23:19 <iqubic> I guess it allows you to do things like this:
23:19 jbiesnecker joined
23:19 <iqubic> > (1 :+ 2) >>= (+1)
23:19 <lambdabot> 2.0 :+ 0.0
23:20 <iqubic> Err, what???
23:20 <iqubic> > (1 :+ 2) <$> (+1)
23:20 <lambdabot> error:
23:20 <lambdabot> • Couldn't match expected type ‘a -> b’
23:20 <lambdabot> with actual type ‘Complex Integer’
23:20 <iqubic> > (+1) <$> (1 :+ 2)
23:20 <lambdabot> 2 :+ 3
23:21 <iqubic> Alright, what is different between those?
23:21 <lyxia> > (1 :+ 2) >>= \x -> return (x + 1)
23:21 <lambdabot> 2 :+ 3
23:21 LnL joined
23:21 <Koterpillar> :t (+1)
23:21 <lambdabot> Num a => a -> a
23:21 <Koterpillar> :t (\x -> return (x + 1)
23:21 <Koterpillar> :t (\x -> return (x + 1))
23:21 <lambdabot> error:
23:21 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
23:21 <lambdabot> (Num a, Monad m) => a -> m a
23:21 <lyxia> ah
23:22 <lyxia> (1 :+ 2) >>= (+1) , the first argument has type Complex (Complex something)
23:22 <iqubic> > (1 :+ 2) >>= (+1)
23:22 <lambdabot> 2.0 :+ 0.0
23:22 <iqubic> No, I think the first argument has type complex int.
23:22 <iqubic> :t (1 :+ 2)
23:22 <lambdabot> Num a => Complex a
23:22 <iqubic> What???
23:23 <lyxia> > (1 :+ 2 :: Complex Int) >>= (+1)
23:23 <lambdabot> error:
23:23 <lambdabot> • Couldn't match type ‘Int’ with ‘Complex b’
23:23 <lambdabot> Expected type: Int -> Complex b
23:23 <lyxia> > (1 :+ 2 :: Complex (Complex Int)) >>= (+1)
23:23 <lambdabot> error:
23:23 <lambdabot> • No instance for (RealFloat Int) arising from the literal ‘1’
23:23 <lambdabot> • In the first argument of ‘(:+)’, namely ‘1’
23:23 <lyxia> > (1 :+ 2 :: Complex (Complex Double)) >>= (+1)
23:23 <lambdabot> 2.0 :+ 0.0
23:23 <iqubic> lyxia, why is the first argument of type Complex Complex Double?
23:23 <iqubic> And why does the imaginary part go to zero?
23:24 biglambda joined
23:24 <biglambda> Is there as version of the lens operator (.=) that allows the second operand to be monadic
23:24 <Koterpillar> > (1 :+ 1) :+ (1 :+ 1)
23:24 <lambdabot> (1 :+ 1) :+ (1 :+ 1)
23:25 <iqubic> I get that. But how does that help me Koterpillar ?
23:25 <iqubic> :t (1 :+ 1) :+ (1 :+ 1)
23:25 <lyxia> iqubic: look at the type of (>>=) :: m a -> (a -> m b) -> m b and the type of (+1) :: Num c => c -> c
23:25 <Koterpillar> I'm not sure
23:25 <lambdabot> Num a => Complex (Complex a)
23:25 <Gurkenglas_> biglambda, (<~)
23:25 <lyxia> iqubic: c -> c must unify with (a -> m b), therefore c ~ a ~ m b
23:25 <lyxia> iqubic: so the first argument of >>= must have type m a ~ m (m b)
23:26 <iqubic> I see.
23:26 <iqubic> So what does it do to make the first argument the right type?
23:26 <lyxia> then it sees (1 :+ 2) which must be some Complex d, so it unifies m ~ Complex, d ~ m b
23:27 <iqubic> > (1 :+ 1) >>= (:+ 3)
23:27 <biglambda> 7,1Gurkenglas_ 
23:27 <lambdabot> 1 :+ 3
23:27 <biglambda> Thanks
23:27 seawalk joined
23:27 <iqubic> What the heck is up with that example??
23:27 <iqubic> I don't understand the monad instance of Complex, what is good for?
23:28 <lyxia> thus we get Complex (Complex b) for some b which must be an instance of Num, but also RealFrac because you are using (+1) on c ~ Complex b and so b gets defaulted to Double
23:28 <iqubic> I see,
23:28 <lyxia> I'm pretty sure it's just there to confuse you
23:28 <iqubic> Really. I can't see anyway this monad instance could be helpful.
23:28 beanbagula joined
23:28 <iqubic> See this weirdness:
23:28 <iqubic> > (1 :+ 1) >>= (:+ 3)
23:28 <lambdabot> 1 :+ 3
23:29 <iqubic> That does weird stuff.
23:29 <Koterpillar> instance Monad Complex where a :+ b >>= f = realPart (f a) :+ imagPart (f b)
23:29 <iqubic> Oh, I see.
23:29 <iqubic> I also see how my example works.
23:30 <iqubic> That's helpful, I suppose.
23:30 wroathe joined
23:30 <codedmart> Trying to understand lenses. If I have `data SomeType = SomeType { someField :: Maybe Integer }` what does a `incSomeField` function look like that is `SomeType -> SomeType` and increments `someField` by `1` if it is `Just`? I know you can just write this as a function without lenses, but just trying to wrap my head around lenses a bit.
23:30 <lyxia> works just like ZipList
23:30 <iqubic> > return 2 :: Complex Double
23:30 <lambdabot> 2.0 :+ 2.0
23:30 <codedmart> I feel like I get it some, but then I feel confused.
23:30 <iqubic> That looks good.
23:31 <iqubic> I understand that.
23:31 <lyxia> well not quite since ZipList is not actually a Monad
23:31 <lyxia> "ZipVec"
23:32 louispan joined
23:32 <iqubic> Why is it that Data.Complex is foldable, and traversable?
23:33 hybrid joined
23:33 <lyxia> codedmart: so makeLenses will give you a lens from SomeType to Maybe Integer, then _Just gives you a prism from Maybe Integer to Integer, finally you can just use set or something
23:33 <lyxia> to operate on that Integer
23:33 <lyxia> iqubic: because we can
23:33 <iqubic> Really.
23:34 <iqubic> ??!!??!
23:34 <iqubic> What's an example of folding being used with complex numbers?
23:34 <Tuplanolla> > sum (42 :+ 13)
23:34 <lambdabot> 55
23:35 <iqubic> > fold (sum 5 :+ sum 10)
23:35 <lambdabot> error:
23:35 <lambdabot> • Could not deduce (Num (t0 m))
23:35 <lambdabot> from the context: (Num (t m),
23:35 <mbw> kuribas: Ok, I wrote it down in c++. Takes 0.2ms.
23:35 <iqubic> > fold (Sum 5 :+ Sum 10)
23:35 <lambdabot> Sum {getSum = 15}
23:35 <lyxia> An insane way of computing the complex modulus.
23:35 <iqubic> > fold (Product 5 :+ Product 10)
23:35 <lambdabot> Product {getProduct = 50}
23:36 <Sornaensis> :t fold
23:36 <lambdabot> (Monoid m, Foldable t) => t m -> m
23:36 <Gurkenglas> > sqrt . sum . fmap (^2) $ 3 :+ 4
23:36 <lambdabot> 5.0
23:36 <iqubic> Gurkenglas: What is that doing?
23:36 <Sornaensis> :t (:+)
23:36 <lambdabot> a -> a -> Complex a
23:36 <Sornaensis> > 2 :+ 1
23:36 <lambdabot> 2 :+ 1
23:37 <Gurkenglas> Computing the distance of (3 :+ 4) from (0 :+ 0)
23:37 <kuribas> mbw: lol
23:37 <Sornaensis> > fmap (^) $ 2 :+ 1
23:37 <lambdabot> <Integer -> Integer> :+ <Integer -> Integer>
23:37 <kuribas> mbw: same algorithm? 10000 doubles?
23:37 <lyxia> codedmart: someFieldLens . _Just %~ (+1) $ SomeType (Just 32) I guess
23:37 <iqubic> Gurkenglas: See this
23:37 <iqubic> > magnitude $ 3 :+ 4
23:37 <lambdabot> 5.0
23:37 <mbw> yeah
23:38 <iqubic> Simpler way of doing the same thing.
23:38 <mbw> The one from wikipedia.
23:38 <mbw> Currently doing a brute-force translation.
23:38 <iqubic> What does foldr do?
23:38 <codedmart> lyxia: So is the benefit more noticed when dealing with nested data?
23:38 <iqubic> foldl (+) 10 (1 :+ 1)
23:39 <iqubic> > foldl (+) 10 (1 :+ 1)
23:39 <lyxia> codedmart: yes
23:39 <lambdabot> 12
23:39 <iqubic> just as I expected.
23:39 <iqubic> > length (1 :+ 0)
23:39 <lambdabot> 2
23:39 <codedmart> lyxia: Thanks!
23:39 acro joined
23:39 <iqubic> won't the length of a complex number always be 2?
23:40 <Gurkenglas> Is it simpler just because it's been given its own name? (Hmm I assume that the scaling in http://hackage.haskell.org/package/base- has a purpose so that one's probably better to use.)
23:40 <iqubic> What scaling?
23:41 <Gurkenglas> I'm just refering to what it's doing with the scaleFloat k
23:41 <ClaudiusMaximus> the purpose is to avoid overflow or underflow for large or small results, afaik
23:41 <iqubic> Ah. Yeah. I said it was simpler because it was a single function.
23:42 <iqubic> > maximum (1 :+ 2)
23:42 <lambdabot> 2
23:42 <iqubic> > minimum (1 :+ 2)
23:42 <mbw> kuribas: Sorry, that is 0.2sec, not ms.
23:42 <lambdabot> 1
23:42 <mbw> My bad.
23:42 <kuribas> mbw: still...
23:42 <joe9> need some advice, please? I am reading a constructor name in while building a generic parser. Normally, when reading any other attributes, I do parse = fmap Constructor valueParsed . But, if I am reading a costructor name as the parsed value, I cannot figure out how to convert the valueParsed to the Constructor. I can have a matchName :: String -> Datatype (but that seems too much work)
23:43 <robertkennedy> Where can I find base-4.10.*?
23:43 <joe9> for example , matchName "Constructor" = Constructor
23:43 <joe9> but, I would be doing that for all data types and I wish there is a better way of going about it.
23:43 <iqubic> > 5 `elem` (20 :+ 30)
23:43 <lambdabot> False
23:44 <iqubic> cool. I know understand complex numbers a lot better.
23:44 chenshen joined
23:44 <iqubic> repls are amazing.
23:46 <iqubic> Why doesn't Java have a repl?
23:46 <iqubic> Would be so awesome.
23:46 <Koterpillar> Groovy does
23:47 <Gurkenglas> You can kinda evaluate expressions based on the variables in scope with the debugger
23:47 <monochrom> Complex is a Foldable?! This is surreal.
23:48 oisdk joined
23:48 <ClaudiusMaximus> robertkennedy: i'm guessing it comes with ghc-8.2 (rc1 of which just got released), seeing as ghc-8.0.2 comes with base- and new ghc major versions typically increment the second number
23:48 <Tuplanolla> Oh, but surreal numbers are different.
23:48 <monochrom> Heh
23:48 <iqubic> monochrom: Why is that surreal?
23:48 <EvanR_> what isn't foldable? (that has the right kind)
23:48 <mbw> This isn't easy at all...
23:48 <EvanR_> surreals library plz
23:48 <monochrom> The stage is set for Complex (IO Double) -> IO (Complex Double)
23:49 <johnw> EvanR_: since there are really no laws, and anything could define foldMap _ _ = mempty, I think anything is Foldable
23:49 <EvanR_> that is what i suspected
23:49 <johnw> in those cases, folding just means "ain't nothing to see here"
23:49 <kuribas> mbw: I got it down to 0.3sec by specializing bubblesortM as well.
23:50 <Gurkenglas> joe9, does matchName happen to be equal to read?
23:50 <kuribas> mbw: ghc only does specializing when it's in the same module
23:50 <Gurkenglas> (When you attach deriving (Read, Show) to Datatype's definition)
23:50 <kuribas> mbw: maybe that's why it worked in the book.
23:51 wroathe joined
23:51 <dcz__> guys, what should be the "undefined" part at line 21 ? https://hastebin.com/aboduwaxog.hs
23:51 Welkin joined
23:52 <robertkennedy> ClaudiusMaximus: yeah, that's where my interest comes from.
23:52 <joe9> Gurkenglas: very good point. When I think about it, it is a read. let me think about attaching the Read to the datatype's definition.
23:52 <iqubic> dcz__: What should that function do?
23:52 <mbw> kuribas: That sounds awesome! Could you paste your version?
23:53 oisdk_ joined
23:53 <kuribas> sure...
23:53 <dcz__> should find files with extension ".webm"
23:53 <mbw> Also it seems realistic :)
23:53 <Gurkenglas> dcz__, looks like homework. I'm guessing other files should be filtered out?
23:53 <iqubic> And what if a file doesn't have the extention ".webm"?
23:53 <dcz__> not homework, i just practice to understand how haskell works
23:53 <iqubic> I think ff stands for fileFilter
23:54 <Gurkenglas> dcz__, why isn't it 'b == ".webm"' in line 20?
23:54 <dcz__> iqubic: thats the point where i am struggling , what if it doesnt have .. :D
23:54 rcschm joined
23:54 <iqubic> dcz__: What would you like to have happen?
23:54 <dcz__> Gurkenglas, right :D
23:54 infinity0 joined
23:54 <dcz__> iqubic: it should skip it ofc
23:55 <monochrom> Then it is simply "ff xs"
23:55 <kuribas> mbw: http://lpaste.net/354496#a354500
23:55 <iqubic> Then Otherwise = ff xs
23:55 <monochrom> with lowercase o
23:55 <iqubic> Just don't append the current file onto the head of the list.
23:55 <dcz__> i did that but , *** Exception: Main.hs:(19,1)-(23,31): Non-exhaustive patterns in function ff
23:55 <kuribas> mbw: also vector recommends enumFromN
23:55 <dcz__> thats why i am asking
23:55 <iqubic> did what?
23:55 <monochrom> Yes, ff [] = ??? This is the base case.
23:55 filterfish joined
23:56 <Gurkenglas> dcz__, after you've fixed that, consider defining ff like "ff = filter ..."
23:56 <iqubic> That makes more sense.
23:56 filterfish joined
23:56 <dcz__> ff [] = ??? something real or ? :D
23:57 <monochrom> I mean that you need to fill in something for ???
23:57 <Gurkenglas> ??? is more ? than real
23:57 <dcz__> ff [] = []
23:57 <dcz__> cool
23:57 <iqubic> sure, that works.
23:58 <monochrom> You see the value in sharpening your thinking and your narrative, and not resort to "you know what I mean of course".
23:58 jbiesnecker joined
23:58 hamishmack joined
23:58 YongJoon joined
23:58 <dcz__> cool, now i think should this with filter :D
23:58 <monochrom> Yes, this is a classic application of filter.
23:59 <iqubic> Now, how would *you* write ff with a filter?
23:59 <monochrom> The code of filter is actually like what you already have, just a bit more general.
23:59 <dcz__> first i need to know how filter works :D