<    March 2017    >
Su Mo Tu We Th Fr Sa  
          1  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 30 31
00:01 marcopullo joined
00:03 xochozomatli joined
00:04 maarhart joined
00:06 louispan joined
00:06 patbecich joined
00:07 <boxscape> (I still don't understand why it has to check the whole pattern though, just t oget a)
00:07 <glguy> It matches the whole pattern because that's how pattern matching is designed to work
00:08 <boxscape> I suppose that makes sense
00:08 <boxscape> But it could be different?
00:09 <glguy> You could make a system where: case [1,2] of [x] -> x == 1 I suppose
00:09 <glguy> but that seems less useful than being able to force evaluation
00:09 <monochrom> Yes, one could design a language that does a different thing.
00:09 <boxscape> ok
00:09 <boxscape> I can see why that's more useful, yeah
00:09 <boxscape> i.e. why the haskell system is more useful
00:10 <monochrom> But Haskell chose this design point, it is a good balance over ease to explain, ease to implement, ease of use.
00:10 <boxscape> okay
00:10 <boxscape> thanks guys
00:11 aglorei joined
00:12 <boxscape> The problem was that I was just thinking about irrefutable patterns; when I think about patterns in general, it makes a lot of sense that you would want `f [a:_:rest] = a` to only match when the list really does have 2 elements
00:13 <boxscape> (at least)
00:14 splanch joined
00:15 <jle`> boxscape: i think maybe you can see it as ~ is not recursive; it just overrides default behavior for the top level pattern
00:15 <jle`> boxscape: you're thinking of ~(a,~[])
00:15 <jle`> but by default it's ~(a,[])
00:15 <boxscape> yeah, that's a good point
00:15 <jle`> if you want the inner layers to also be ~, you have to explicitly use ~
00:15 <boxscape> ok, but you can do that?
00:15 handyc joined
00:15 <boxscape> > case (1,~[[],[]]) of ~(a,[[],[1]]) -> a
00:15 <lambdabot> error:
00:15 <lambdabot> Pattern syntax in expression context: ~[[], []]
00:15 <jle`> ~(a,~(b,~(c,~[])))
00:15 <boxscape> oops
00:16 <boxscape> > case (1,[[],[]]) of ~(a,~[[],[1]]) -> a
00:16 <lambdabot> 1
00:16 <boxscape> ok, thanks
00:16 <jle`> same for bang patterns, too, for let statements
00:16 <jle`> !(x,y) only forces the evaluation of the top (,)
00:16 <jle`> !(x,y) isn't the same as !(!x,!y)
00:16 <boxscape> ok
00:16 <jle`> so ~(x,y) isn't the same as ~(~x,~y)
00:17 halogenandtoast joined
00:19 jsgrant-_ joined
00:19 <nshepperd_> How is ~[] different from _? Surely that value will never be "needed"?
00:19 systadmin joined
00:20 gugah joined
00:20 biotim joined
00:21 <c_wraith> it's not even named, so it can't be
00:22 linduxed joined
00:22 <c_wraith> jle`, I'm pretty sure ~(x, y) is the same as ~(~x, ~y)
00:23 <jle`> > case (1,[1,2,3]) of ~(x, []) -> x
00:23 <lambdabot> *Exception: <interactive>:(3,1)-(4,22): Irrefutable pattern failed for patte...
00:23 <c_wraith> jle`, i don't think irrefutable matches do anything unless applied to a constructor pattern.
00:23 <jle`> > case (1,[1,2,3]) of ~(x, ~[]) -> x
00:23 <lambdabot> 1
00:23 <c_wraith> yes, you're using a constructor pattern in that case.
00:23 <jle`> ah yeah, sorry, it was my abuse of notation
00:23 <jle`> i should have meant ~(Pat,Pat) vs. ~(~Pat, ~Pat)
00:24 <jle`> s/meant/wrote
00:24 <c_wraith> those are different. :)
00:24 eacamero_ joined
00:24 vicfred joined
00:25 eacameron joined
00:25 eacamero_ joined
00:26 JeanCarloMachado joined
00:26 lambda-11235 joined
00:28 plutoniix joined
00:29 Kundry_Wag joined
00:30 plutoniix joined
00:30 nomicflux joined
00:31 mr_sm1th joined
00:31 sypwex joined
00:34 andyhuzhill joined
00:34 plutoniix joined
00:35 plutoniix joined
00:36 augur joined
00:37 plutoniix joined
00:37 anemecek joined
00:38 ericsagnes joined
00:40 serendependy joined
00:40 leshow joined
00:41 <leshow> hello, im having some trouble with do notation i was hoping someone could give me a few pointers.
00:41 ClaudiusMaximus joined
00:41 sypwex joined
00:41 ubsan_ joined
00:41 <leshow> basically i want to return a string if any character doesnt match, and a map if everything is successful. adding each character to the map and incrementing its value
00:41 <leshow> http://lpaste.net/353994
00:42 <jle`> leshow: 'x <- xs'
00:42 <jle`> you can only do that if xs :: Either String something
00:43 <jle`> it looks like do notation doesn't really add that much here
00:44 <leshow> i thought you could take each element out of a list like that, ive written an fmap type of thing with do notation before
00:44 <jle`> ah yeah, that behavior depends on the monad you're using
00:44 <jle`> in this case, 'Either' doesn't have that behavior
00:44 <jle`> bind for Either binds the 'Right' result, if there is one
00:45 <boxscape> (and the <- notation uses bind)
00:45 <jle`> leshow: what behavior do you want? to fail if there are any failures?
00:45 <jle`> you can use forM or mapM for that
00:45 <jle`> mapM :: [a] -> (a -> Either e b) -> Either e [b]
00:45 <leshow> mapM... like traverse?
00:46 MarioBranco joined
00:46 <jle`> yupp
00:46 <jle`> it might be easier to write using forM/for
00:46 <jle`> forM xs $ \x -> do
00:46 <jle`> x' <- isValid x
00:46 <leshow> ok. so just to clarify
00:47 <lyxia> you still have to accumulate a map
00:47 <jle`> oh yes i see
00:47 <lyxia> just write a recursive function
00:47 <leshow> because im not in the list monad, we're returning Either, I cant do stuff like do { x <- xs; return (f x); }
00:47 <lyxia> or you can do it in two steps if you don't care about streaming
00:47 <jle`> you can use foldM
00:47 <jle`> leshow: you can if xs :: Either String something
00:48 <jle`> but not if it's [something]
00:48 <jle`> every line on a do block has to be of the same monad
00:48 <leshow> ok
00:48 <ski> @unmtl StateT (Map Char Int) (Either MyError) ()
00:48 <lambdabot> Map Char Int -> Either MyError ((), Map Char Int)
00:49 sanett joined
00:50 <jle`> :t foldM
00:50 <lambdabot> (Monad m, Foldable t) => (b -> a -> m b) -> b -> t a -> m b
00:50 gugah joined
00:51 <jle`> foldM :: (Map Char Int -> Char -> Either String (Map Char Int)) -> Map Char Int -> [Char] -> Either String (Map Char Int)
00:54 mson joined
00:55 <leshow> ok im trying with traverse/forM
00:55 sypwex joined
00:55 alx741 joined
00:55 eacameron joined
00:57 <jle`> leshow: forM won't quite work with either alone, sorry
00:57 <jle`> if you want to take advantage of Either, you can use foldM
00:57 StoneToad joined
00:57 <leshow> http://lpaste.net/353994
00:57 <leshow> yeah it doesnt the return type ends up being
00:57 mda1 joined
00:57 <leshow> Either String [Map Char Integer]
00:57 <jle`> foldM is like foldl, but instead of taking an (b -> a -> b), it takes a (b -> a -> Either String b)
00:57 <jle`> for foldr the result can be wahtever your accumulator is
00:58 <jle`> if your accumulator is 'Map Char Int', the result will be Either String (Map Char Int)
00:59 <jle`> (also for what it's worth i wouldn't use Strings to represent nucleotides)
00:59 <leshow> it's not my choice its part of the question
00:59 <jle`> ah, how fun :)
00:59 <leshow> im not doing anything serious with nucleotides haha
01:00 <leshow> out of curiousity what data structure would you choose
01:00 nighty- joined
01:01 <jle`> data Nucleotide = A | C | T | G, or something like that :)
01:01 robertkennedy joined
01:02 <leshow> Oh I thought you meant something fancy for storing a sequence, hey also one thing
01:02 <leshow> I was really hoping there was a way to do a multiple case on the left hand side
01:02 <leshow> 'A' | 'T' | ..
01:02 <leshow> of a case expression
01:02 <jle`> there isn't quite one
01:02 <leshow> is that not possible
01:02 <jle`> but you can use a function instead
01:03 <jle`> :t (`elem` "ACTG")
01:03 <lambdabot> Char -> Bool
01:03 <jle`> > 'A' `elem` "ACTG"
01:03 <lambdabot> True
01:03 <leshow> right yeah, but there's a cost with that
01:03 <jle`> what is the cost?
01:03 <leshow> it has to search the list
01:03 <jle`> > 'B' `elem` "ACTG"
01:03 <lambdabot> False
01:03 <jle`> leshow: do you think the case statement doesn't have to search the cases? :p
01:04 <jle`> pattern matching on case statements go from top to bottom
01:04 <leshow> i don't know how GHC puts it together
01:04 <jle`> so first it checks 'A'
01:04 <jle`> then it checks 'T'
01:04 <jle`> then 'G', then 'C'
01:04 <jle`> well, it's the semantics of pattern matching
01:04 <leshow> but if I was writing it in like Rust, I'd assume it'd be faster to match on arms of a case than search a list
01:05 sypwex joined
01:05 Stanley00 joined
01:06 <boxscape> was using guards in case statements, like `case 4 of a | even a -> ()` always possible?
01:06 <jle`> i believe so
01:06 <boxscape> ok
01:06 <ezyang> I believe that it was allowed in Haskell98
01:06 <jle`> oh, apparently not, then
01:06 <boxscape> does that mean, first allowed, or at least since then allowed?
01:06 <leshow> in any case, i got it to work with foldM
01:07 <ezyang> at least
01:07 <boxscape> ok
01:07 <leshow> http://lpaste.net/edit/353994
01:07 <jle`> if you want to be fancy and you're comfortable with monad transformers, you can use StateT (Map Char Int) (ExceptT String [])
01:07 <leshow> I've only just started with monad trans so I think ill put that off for now lol
01:07 <jle`> in which case it's just a single do block without loops
01:08 <leshow> if you want to show me what it looks like im open to that, I just dont think I can write it myself
01:08 <jle`> well you caught me in a nerd-snipable mood, so
01:08 <leshow> :D
01:09 Rodya_ joined
01:09 juhp___ joined
01:09 umib0zu joined
01:10 eacameron joined
01:11 <boxscape> > let a | even a = 4 in a -- this is a bit weird. I would expect this to work like the case statement above, but I'm probably misunderstanding the syntax here
01:11 <lambdabot> mueval-core: Time limit exceeded
01:12 <boxscape> > case 4 of a | even a -> a
01:12 <lambdabot> 4
01:12 <lpaste_> jle` annotated “nucleotide.hs” with “nucleotide.hs (annotation)” at http://lpaste.net/353994#a353998
01:12 <jle`> but actually you can use 'guard' in your original version, too
01:13 <Koterpillar> > let (a | even a = 4) in a
01:13 <lambdabot> <hint>:1:8: error: parse error on input ‘|’
01:13 Supersonic112_ joined
01:13 <leshow> how did you get lpaste_ to post that message to the chat?
01:13 <boxscape> that's what I thought my snippet would mean
01:13 sanett joined
01:13 <jle`> you just have to put the channel name in the channel box
01:13 <Koterpillar> leshow: select "channel"
01:14 <leshow> jle`, this is cool
01:14 <sanett> Hey folks, is \p.\a.\b.p b a \x.\y.x equal to \a.\b.(\x.\y.x) b a?
01:14 eacameron joined
01:14 <jle`> oh sorry i shouldn't use guard if you want a specific error message
01:14 <boxscape> > let a | even 3 = 3 in a -- works like I would expect, same with even 4
01:14 <jle`> leshow: using guard there would give you left "" in the case of an error
01:15 <lambdabot> *Exception: <interactive>:3:5-18: Non-exhaustive patterns in function a
01:15 <boxscape> and yet `let (a | even 3) = 3` produces a parse error
01:15 <boxscape> but I guess that makes sense actually
01:15 <lpaste_> jle` revised “nucleotide.hs (annotation)”: “nucleotide.hs (annotation)” at http://lpaste.net/353998
01:16 <boxscape> but `let a | even a = 3` in a producing an infinite loop doesn't make sense to me
01:16 <leshow> so throwE doesnt throw an exception, it returns a Left?
01:17 <leshow> and ExceptT is the monad trans for Either?
01:17 caconym joined
01:18 event_null joined
01:18 <Koterpillar> boxscape: you are using the return value (a) in the guard, what did you expect?
01:18 eacamero_ joined
01:18 <Koterpillar> boxscape: it's equivalent to: let a = if even a then 3 else error "partial" in a
01:19 <boxscape> Koterpillar: but am I not doing the same thing that I'm doing in `case 4 of a | even a -> a`?
01:19 sypwex joined
01:19 <Koterpillar> boxscape: no, because here you are doing: (\a -> if even a then a else error "partial") 4
01:20 augur joined
01:20 <Koterpillar> `a` on the left side of the guard gets matched with 4 right away
01:20 <rotaerk> leshow, Either is really similar to exceptions though; returning left is like throwing because in a sequence of Eithers, returning left short circuits the whole thing
01:20 <boxscape> ok
01:20 <rotaerk> so the analogy works
01:20 <boxscape> I think I get it
01:20 <leshow> rotaerk, so is it throwing an exception or returning a value
01:20 <ski> sanett : the usual way to parse `\p.\a.\b.p b a \x.\y.x' is `\p.(\a.(\b.(((p b) a) (\x.(\y.x)))))', but it seems you intended (?) `(\p.(\a.(\b.((p b) a)))) (\x.(\y.x))', which is indeed beta-reduces in one step to `\a.(\b.(((\x.(\y.x)) b) a))', which is your `\a.\b.(\x.\y.x) b a'
01:21 sz0 joined
01:21 <rotaerk> leshow, it's causing a Left to be returned, but it's *analogous* to throwing
01:21 Rodya__ joined
01:22 <leshow> rotaerk, ok
01:48 irclogger_com joined
01:48 Topic for
01:48 caconym joined
01:49 splanch joined
01:50 mkoenig joined
01:51 aglorei1 joined
01:51 marsam joined
01:51 ChaiTRex joined
01:53 certainty joined
01:55 taktoa joined
01:58 sanett joined
01:59 BlueRavenGT joined
02:00 FreeBirdLjj joined
02:00 hucksy_ joined
02:00 Koterpillar joined
02:01 <sanett> so now I have NOT TRUE = (λp.(λa.(λb.((p b) a) (λx.(λy.x)))))
02:02 <sanett> how do I deal with ((p b) a) (λx.(λy.x))?
02:02 norotartagen joined
02:02 augur joined
02:04 Rainb joined
02:04 meba joined
02:05 refold joined
02:05 <ski> sanett : i believe you're bracketting it wrong
02:06 <sanett> it should probably be (λb.((p b) a) (λx.(λy.x)))
02:09 sypwex joined
02:12 nomicflux joined
02:12 MarcelineVQ joined
02:14 caconym joined
02:15 fizbin joined
02:16 sandstorm joined
02:17 nomotif joined
02:18 sypwex joined
02:18 <ski> sanett : nah ..
02:18 <sanett> I died.
02:19 <sanett> I actually got NOT TRUE = TRUE which is pretty funny
02:19 jsgrant joined
02:20 whiteline joined
02:20 <boxscape> you heard it here first; lambda calculus is inconsistent
02:21 eklavya joined
02:22 systadmin joined
02:23 exferenceBot joined
02:23 robkennedy joined
02:23 ramzifu joined
02:24 <adelbertc> is it in general best practice to always us Text for string-y things? i'm programming against the Pandoc API and noticed it uses the prelude String, but i am doing a bit of string manipulation in it (e.g. calling unlines and lines and doing string matching) and am wondering if i should use Text
02:25 <ChaiTRex> adelbertc: If you're dealing with actual text where Unicode matters, I think that's best.
02:25 <adelbertc> mm i wouldn't expect much Unicode if at all, im doing something involving parsing code blocks from a markdown document
02:26 shayan_ joined
02:28 hexagoxel joined
02:30 fizbin1 joined
02:32 <Welkin> adelbertc: Text is an optimization
02:33 <Welkin> adelbertc: String can work just fine depending on what you are doing
02:33 sypwex joined
02:33 <adelbertc> Welkin: ChaiTRex sounds good, thanks!
02:34 fizbin joined
02:34 systadmin joined
02:35 mizu_no_oto joined
02:36 dfeuer joined
02:38 mkoenig joined
02:38 event_null left
02:39 pmade_ joined
02:40 Scip joined
02:41 eklavya_ joined
02:42 brownhami1 joined
02:42 marcopullo joined
02:42 sypwex joined
02:42 pmade_ joined
02:43 shoopaloop joined
02:44 sanett_ joined
02:44 shoopaloop joined
02:44 umib0zu joined
02:44 wagle joined
02:44 animated joined
02:45 augur joined
02:50 eklavya joined
02:51 chocopuff joined
02:51 pmade_ joined
02:52 Gurkenglas_ joined
02:53 tromp joined
02:56 CMCDragonkai joined
02:57 conal joined
02:57 sypwex joined
02:59 uglyfigurine joined
03:00 fizbin joined
03:05 raynold joined
03:07 umib0zu joined
03:07 fizbin joined
03:10 fizbin1 joined
03:12 xtreak joined
03:13 {emptyset} joined
03:16 Jeanne-Kamikaze joined
03:16 mkoenig joined
03:16 sanett joined
03:17 edvorg joined
03:18 JoshS joined
03:18 takle joined
03:19 deepfire` joined
03:20 koserge joined
03:20 Autolycus joined
03:21 sypwex joined
03:21 hololeap joined
03:22 fizbin joined
03:23 nomicflux joined
03:23 conal joined
03:25 fizbin1 joined
03:26 sypwex joined
03:26 moongazer joined
03:28 ljhms joined
03:29 augur joined
03:30 importantshock joined
03:30 sanett joined
03:30 watabou joined
03:30 hybrid joined
03:30 sypwex joined
03:32 caconym joined
03:33 fizbin joined
03:33 umib0zu joined
03:34 <OGLoli> Would anyone happen to know of any online CS lectures / courses that teach from the perspective of functional programming. Instead of the typical teaching CS from a language like C.
03:34 coltfred joined
03:35 <OGLoli> I know of courses that introduce functional programming design later on but that's only in the perspective of there's this and this is how it's different for one class or so.
03:35 fizbin1 joined
03:35 felixsch__ joined
03:36 <OGLoli> I'd like to know if there are any that teach from functional programming style from day 1 till the end of the course.
03:36 falafel joined
03:36 <dibblego> OGLoli: https://github.com/data61/fp-course/ and once you complete that, you can come and work there, https://www.itnews.com.au/news/data61-opens-new-labs-in-queensland-456275
03:37 brynedwardz joined
03:37 <boxscape> https://github.com/bitemyapp/learnhaskell/ this includes that course and one more
03:37 <Welkin> OGLoli: functional programming is very high level (perspective from mathematics)
03:38 <Welkin> you still need to understand the low-level perspective (from hardware)
03:38 <dibblego> adelbertc: it's not common practice. You can use libraries to abstract over it, to defer the decision to users e.g. lens
03:38 <Welkin> so you will still need to learn c and/or assembly
03:38 <adelbertc> dibblego: oh hello :-)
03:38 <dibblego> adelbertc: hey mate :)
03:38 Atrumx joined
03:39 petervaro joined
03:39 fizbin joined
03:40 cpup joined
03:41 <OGLoli> Thank you, dibblego and boxscape. I appreciate it. Also welkin I will also be doing that, I would just like to learn the same concepts from different paradigms. I'm currently watching a very informative course by Harvard. The CS50 video course series.
03:42 fizbin1 joined
03:45 sypwex joined
03:45 takle joined
03:46 sanett joined
03:46 IRCFrEAK joined
03:47 dreco joined
03:47 systemfault joined
03:47 splanch joined
03:47 caconym joined
03:48 esdzin joined
03:48 IRCFrEAK left
03:48 fiddlerwoaroof joined
03:50 sypwex joined
03:50 capisce_ joined
03:52 sypwex1 joined
03:52 Lazersmoke joined
03:53 <{emptyset}> is there anywhere good for asking about algorithms?
03:53 <{emptyset}> trying to understand a reduction from closure problem to maximum flow
03:54 certainty joined
03:54 otto_s_ joined
03:56 umib0zu joined
03:56 alanz joined
03:56 s3mi0 joined
03:56 killtheliterate joined
03:58 systadmin joined
03:59 augur joined
04:00 insitu joined
04:01 augur joined
04:01 haasn joined
04:02 raycoll joined
04:03 raibutera joined
04:03 caconym joined
04:04 conal joined
04:05 sgript joined
04:05 ebsen joined
04:05 splanch joined
04:06 Goplat joined
04:06 ackpacket joined
04:06 <ackpacket> Hmm.... using Aeson, how can i convert this: HashMap Text (HashMap Text Double) into an Object?
04:07 benl23 joined
04:07 <ackpacket> Can't find any other way other than transforming everything into Value at each step, but shouldn't it already be compatible?
04:07 takle joined
04:07 Lemmata joined
04:09 <thoughtpolice> ackpacket: Just use toJSON. There's an instance for (ToJSON k, ToJSON v) => ToJSON (Hashmap k v)
04:09 takuan joined
04:11 Rodya_ joined
04:12 <ackpacket> thoughtpolice, that gives me a Value, which, passing into a function expecting an Object returns an error of "Couldn't match 'Value' with 'HashMap Text Value', expected type Object actual type Value
04:13 connrs joined
04:13 xtreak joined
04:14 <thoughtpolice> ackpacket: You'll need to look at the 'Value' type to make sure it's an "Object" constructor. But there's an easier way, now that I look closer: use Data.HashMap.mapValues (or whatever it's called) with toJSON to turn every Double in the HashMap into a Value. You then have an 'Object', because 'type Object = HashMap Text Value'
04:15 <ackpacket> So that converts HashMap Text Double into Value, how do I convert that back later?
04:15 chrissl joined
04:16 <ackpacket> i.e. the reverse of what operation
04:16 sypwex joined
04:16 <thoughtpolice> You have to look at the Value and make sure it is the 'Double' constructor, there is no direct inverse. Technically, if you get a Hashmap Text Value, you don't know what's inside of it. You 'forgot' that you stored Double values in it.
04:17 madacol joined
04:18 <thoughtpolice> Oh, not 'Double'. It's the 'Number' constructor. And technically you won't get a Double back. You'll get a 'Scientific' which you have to convert to Double, using Data.Scientific.toRealFloat, I suppose.
04:18 caconym joined
04:21 esdzin joined
04:21 iCharlie joined
04:22 <hololeap> i'm trying to understand the 'forall' keyword. i am somewhat familiar with set theory and the universal quantifier. can someone help me out?
04:22 kritzcreek_ joined
04:23 <hololeap> i'm trying to understand the theory over the actual implementation
04:23 <hololeap> what is it signifying and how does that differ from what is usually there?
04:24 <hololeap> (in other words, from when there is no forall keyword)
04:24 ramzifu joined
04:25 <glguy> hololeap: a normal type signature like map :: (a -> b) -> [a] -> [b]
04:26 <glguy> has an implicit forall at the beginning for all the type variables mentioned
04:26 <glguy> so it's equivalent to: map :: forall a b. (a -> b) -> [a] -> [b]
04:26 <hololeap> ok
04:28 ackpacket joined
04:28 <hololeap> i would think that would be the case. so, it's obviously not the same as the universal quantifier, since that is implicitly there all the time. but some functions don't match up, like `!!`
04:29 <hololeap> because `!!` doesn't allow negatives. does that have something to do with my question?
04:29 <glguy> It's the universal quantifier
04:29 <glguy> no
04:29 <glguy> forall lives at the type level
04:29 <glguy> :t (!!)
04:29 <lambdabot> [a] -> Int -> a
04:29 <hololeap> i can't remember the term for it... complete function?
04:30 <glguy> explicitly: forall a. [a] -> Int -> a
04:30 <dmwit> Why doesn't (!!) match up, and what does "doesn't allow negatives" mean?
04:30 splanch joined
04:30 <glguy> It means that it doesn't allow negative integer values as arguments at the value level
04:30 halogenandtoast joined
04:31 mmachenry joined
04:31 <glguy> forall introduces new type variables, like 'a'. It doesn't have to do with type constructors like Int, or any of the values of these types
04:32 <glguy> It's saying that (!!) has that type forall choices of types 'a' (with kind * in this case)
04:32 esdzin left
04:32 takle joined
04:34 caconym joined
04:34 <hololeap> so what does explicitly writing it do
04:34 sypwex joined
04:35 pera joined
04:35 <dmwit> it makes it explicit
04:35 <dmwit> This sounds like a joke, but it's not.
04:35 <glguy> In general, it generates an error. If you turn on ExplicitForAll, in that case it does nothing. If you turn on ScopedTypeVariables it makes the named type variables available inside the definition's scope
04:35 systadmin joined
04:36 <dmwit> oh yeah, I forgot about STV
04:36 <glguy> It gets more interesting when you don't put the forall next to the ::
04:36 <hololeap> how do you turn these on?
04:36 <glguy> example :: (forall a. [a] -> [a]) -> Int
04:36 <glguy> That requires RankNTypes
04:36 splanch joined
04:37 <glguy> or you can use forall with ExistentialQuantification: data Example = forall a. Show a => MkExample a a
04:37 mmachenry joined
04:37 <hololeap> isn't putting a restriction in a data header frowned upon?
04:38 <glguy> Yeah, also it's not related to what I wrote
04:38 <hololeap> ok
04:38 <glguy> That would be something like: data Show a => Example a = MkExample a a
04:38 dreco joined
04:40 afnizarnur joined
04:40 <glguy> hololeap: You can add a language pragma to the top of your module: {-# Language ScopedTypeVariables #-}
04:42 <hololeap> i think that helps me understand a little better
04:42 FreeBirdLjj joined
04:43 boxscape joined
04:44 raycoll joined
04:46 <hololeap> i didn't understand that none of this was the "vanilla" language. i will go look up those pragmas (and now i know the term). ty
04:49 pavlicek joined
04:49 caconym joined
04:50 hvn0413 joined
04:51 gabe4k joined
04:51 hvn0413 left
04:52 sleffy joined
04:53 {emptyset} joined
04:56 <orion> Is the State Monad thread safe?
04:56 fizbin joined
04:57 <Koterpillar> what do you mean by that?
04:58 eklavya joined
04:58 <dmwit> It is pure, with all the consequences that come with that: thread-safety, but also thread-agnosticism.
04:58 <dmwit> If you're thinking you'll get a cheap way to share state between threads, State isn't it.
04:59 fizbin joined
05:00 mrowe joined
05:00 <dmwit> `State s a` is just a function `s -> (a, s)`.
05:01 <orion> My goal is to present a cryptographic API which prevents catastrophic nonce reuse.
05:01 animated joined
05:01 <dmwit> I will be impressed if you manage that in Haskell's type system.
05:01 <orion> If we had linear types it would suit my use case perfectly, but we don't so...
05:02 <dmwit> I'm not even sure if linear types help.
05:02 fizbin1 joined
05:03 <orion> I think it would: encryptMessage :: ByteString -> CryptoState -> (ByteString, CryptoState)
05:03 dec0n joined
05:03 conal joined
05:04 <orion> let msg = encryptMessage "foo" cs; msg' = encryptMessage "bar" cs <-- if I was using linear types, wouldn't this be unrepresentable?
05:05 <dmwit> That could work, if you could suitable restrict the construction of CryptoStates.
05:05 caconym joined
05:05 samgd joined
05:07 ichor joined
05:08 SpinTensor joined
05:09 ChaiTRex joined
05:11 Rodya_ joined
05:12 fiddlerwoaroof joined
05:14 fizbin joined
05:14 augur joined
05:15 tromp joined
05:18 yellowj joined
05:18 mmachenry1 joined
05:21 mada joined
05:22 animated joined
05:23 ramzifu joined
05:24 vlatkoB joined
05:27 fakenerd joined
05:27 meandi_2 joined
05:28 fakenerd joined
05:28 eacameron joined
05:29 unK_ joined
05:30 {emptyset} joined
05:31 jhrcek joined
05:33 osa1 joined
05:33 osa1 joined
05:33 danvet joined
05:34 systadmin joined
05:35 _sras_ joined
05:35 Hi-Angel joined
05:36 Axman6 joined
05:36 <_sras_> Why do funcions in the yaml config module require FromJson instances for the read data?
05:37 <jle`> the module from what package
05:38 <jle`> _sras_: if it's based on the 'yaml' library, it's because the yaml library is a thin wrapper over aeson
05:38 <jle`> it uses the FromJSON instance in order to parse yaml into data types
05:38 splanch joined
05:38 <_sras_> jle`: Yes. the 'yaml' library.
05:38 fiddlerwoaroof joined
05:38 <jle`> so if you have a FromJSON intsance for your type Foo, it uses it to parse yaml representing Foo into Foo
05:39 <jle`> and it uses ToJSON serialize data into yaml
05:40 <_sras_> jle`: So the yaml configuration files are supposed to contain json wrapped in yaml?
05:40 <jle`> they're supposed to contain yaml
05:41 <jle`> but it just uses the information from the 'FromJSON' instance to parse yaml into the type
05:41 <jle`> you can imagine type FromYAML = FromJSON
05:41 <_sras_> jle`: Oh. Alright.
05:41 eacameron joined
05:41 <jle`> if a type has a FromJSON instance, it means that it can be parsed from a yaml file
05:42 <jle`> if it helps, you can imagine that FromJSON is caled FromYaml
05:42 tsdh joined
05:43 <jle`> the yaml library is kind of "clever" in that it hijacks FromJSON to read yaml files
05:43 <jle`> so if you write a FromJSON instance for a type, you can use it to parse that type from json as well as yaml
05:44 eacameron joined
05:46 caconym joined
05:48 thunderrd_ joined
05:48 eacamero_ joined
05:48 Swizec joined
05:48 igniting joined
05:49 raycoll joined
05:50 <_sras_> jle`: Yes. Understood.
05:53 ThomasLocke joined
05:53 ThomasLocke joined
05:54 <_sras_> jle`: Do you know how I can make the config lib to read a key, like "dev", "production" from env and return the relavant section from the config file?
05:54 <jle`> _sras_: well, the normal way to do it would be to write a data file that represents the configuration
05:54 <jle`> and then write a FromJSON/ToJSON instance for it. this can be done automatically with generics
05:54 <jle`> so it's auto-derived
05:55 certainty joined
05:55 pavonia joined
05:55 <jle`> but you can also parse the yaml into an Object (nested Map's and Vector's) for ad-hoc usage as well
05:56 <jle`> aeson-lens provides a nice way of do nested lookups
05:56 eacameron joined
05:57 edsko joined
05:58 <_sras_> jle`: No. I think you got me wrong. I was not asking how to get a key from the config file. I was asking for a way to make the lib read a key, like "dev", "production" from the environment, and use the key to return the corresponding section from the yaml file (which will have the configurations nested under such keys as "dev" "production" etc")
05:58 systemfault joined
05:59 <jle`> sounds like it wouldn't be too complicated
05:59 eacamero_ joined
05:59 <jle`> you cna always parse a yaml file as a Map
05:59 <_sras_> jle`: Yes. It is not. But asking if there is a built in way in the lib for this.
06:00 ogrady joined
06:00 <jle`> i'm not sure exactly what you mean
06:01 <jle`> but if you write a quick implementation i might be able to see if it's possible
06:01 ali_bush joined
06:01 ali_bush joined
06:01 henriksod joined
06:02 caconym joined
06:03 splanch joined
06:04 certainty joined
06:04 raichoo joined
06:10 insitu joined
06:10 <cocreature> _sras_: afaik there is no builtin way to do that
06:10 t0by joined
06:11 morolin joined
06:11 <_sras_> cocreature: Yes.
06:13 Rodya_ joined
06:14 connrs joined
06:14 augur joined
06:15 insitu joined
06:15 inad922 joined
06:16 quchen joined
06:16 <morolin> Is there a preferred way to compare floats for approximate equality? I see the HUnit-approx package, Data.Eq.Approximate, and Data.AEq from ieee754, but it's not clear to me if I should prefer one over the other.
06:17 tromp joined
06:18 moongazer joined
06:19 fizbin1 joined
06:21 connrs joined
06:24 fizbin joined
06:24 nomotif joined
06:25 Mortomes|Work joined
06:25 gabe4k joined
06:27 fizbin1 joined
06:28 robertkennedy joined
06:28 ubsan_ joined
06:29 fizbin joined
06:30 ahri joined
06:31 takle joined
06:32 quchen joined
06:32 <ahri> hi, i'm trying to get https://github.com/JoeyEremondi/haskelm to build, but when compiling i get "Not in scope: data constructor ‘FamilyD’", yet PragmaD is there and seems to be defined in the same place judging by https://hackage.haskell.org/package/template-haskell-2.7.0.0/docs/Language-Haskell-TH.html - i'm new to Haskell and haven't touched Template Haskell at all. i'm just trying to get someone
06:33 <ahri> else's project building! do you have any tips for me to investigate?
06:33 caconym joined
06:33 zeroed joined
06:33 zeroed joined
06:33 fizbin1 joined
06:34 <ahri> i assumed that it was using a different version of template-haskell so i made the version explicit in the .cabal file: template-haskell >= 2.7.0.0, but that made no difference: the compilation still fails
06:34 saep joined
06:36 uglyfigurine joined
06:36 <glguy> ahri: that author didn't bother with version constraints, but the template-haskell package has changed since this was written
06:37 <glguy> so you'll have to figure out the versions yourself. you can't change template-Haskell versions without changing ghc versions
06:38 <ahri> ah, that's a great hint! i'll try to figure out what version he was using and go from there
06:38 <ahri> and set all the versions, once it's compiling
06:38 thc202 joined
06:38 systadmin joined
06:39 lok joined
06:39 refold joined
06:39 takle joined
06:40 mstruebing joined
06:41 systadmin joined
06:41 afnizarnur joined
06:42 caconym joined
06:43 MoALTz joined
06:47 Cxom_ joined
06:47 hurkan joined
06:51 Cxom2 joined
06:51 guiben joined
06:52 <ahri> glguy: is there some way i'm missing of correlating the template haskell version (2.10.0.0) back to a ghc version? the only hint i can see is that it depends on base==4.8.* but as i said, i'm new and this doesn't jump out as being tied to a particular GHC version
06:54 oish joined
06:56 laz joined
06:57 <cocreature> ahri: base 4.8 is GHC 7.10
06:59 Ch3ck_ joined
06:59 free_beard joined
07:00 <ahri> ok, cool. um... was that obvious in some way? it might be useful to me in future to be able to figure this out myself!
07:02 <jle`> it's kind of arbitrary, but there's a table associating ghc's with their corresponding base
07:03 <jle`> https://wiki.haskell.org/Base_package
07:03 <jle`> and here's a table i use for other libraries that come packaged with ghc as well https://ghc.haskell.org/trac/ghc/wiki/Commentary/Libraries/VersionHistory
07:03 Itkovian joined
07:05 <jle`> so all of those ghc's are tied to the corresponding versions of those libraries i believe
07:06 rossberg joined
07:06 <ahri> thanks, that's really helpful!
07:06 raichoo joined
07:07 Grisha joined
07:07 <jle`> no problem! this is what i use myself when i have to trudge through versioning problems
07:07 suls joined
07:09 govg joined
07:09 vlatkoB_ joined
07:10 cyborg-one joined
07:13 Rodya_ joined
07:15 athan joined
07:16 albertid joined
07:16 tromp joined
07:17 vlnts joined
07:17 insitu joined
07:18 hamishmack joined
07:18 _sg joined
07:21 takle joined
07:23 _sras_ joined
07:25 mattyw joined
07:26 jsgrant joined
07:27 jsgrant-_ joined
07:27 cyborg-one joined
07:28 albertid joined
07:29 kamog joined
07:29 ragepandemic joined
07:31 roundhouse joined
07:31 sypwex joined
07:32 CurryWurst joined
07:34 razi1 joined
07:34 <roundhouse> hi guys, I have a function that produces elements of type `a`. Depending on `a` I need one or more inputs. I tried modelling this via "data A a b = A { prod :: b -> a }" and my hope was that putting b to () this would erase the input of prod. However this seems to not work. Do you have a hint what would be a better way to do this?
07:35 vydd joined
07:37 sword865 joined
07:38 <mpickering> roundhouse: Can you describe what you are actually trying to do?
07:39 mfukar joined
07:39 <jle`> roundhouse: what do you mean by 'erase' ?
07:40 <jle`> it is true that 'A a ()' is isomorphic to ()
07:40 fizbin joined
07:40 <jle`> er sorry, A () b is isomorphic to ()
07:40 <roundhouse> mpickering: I want to abstract over asset loading. An assetloader gets a filename and loads the asset "a". But some assets need extra information, e.g. a font needs to know the size which to load
07:40 <jle`> A a () is isomorphic to 'a'
07:41 <roundhouse> jle`: erase in the sense: if b == () then prod :: a, otherwise prod :: b -> a
07:42 <jle`> oh, er, that seems kind of magical
07:42 <roundhouse> I was hoping prod :: () -> a would be treated as prod :: a
07:42 louispan joined
07:42 <roundhouse> there being only one value for that type
07:42 <jle`> haskell doesn't automatically coerce types like that, heh
07:42 <roundhouse> (if I understand () correctly)
07:42 <jle`> `() -> a` is a different type than 'a', even though they are isomorphic (up to bottom)
07:43 <phz_> <3
07:43 bennofs joined
07:43 <phz_> jle`: and () is isomorphic to a -> ()
07:43 fizbin joined
07:43 <jle`> roundhouse: but yeah, haskell doesn't automatically coerce values like that
07:43 <jle`> () isn't magical, either, it's just a normal type
07:43 <roundhouse> damn
07:43 <jle`> you can get the 'a' out of an '() -> a' by applying it to ()
07:43 tomboy64 joined
07:44 <roundhouse> any idea how I can modell my original problem?
07:44 <roundhouse> yeah
07:44 <jle`> @let stuff :: () -> Int; stuff () = 10
07:44 <lambdabot> Defined.
07:44 <roundhouse> but that clutters all function calls that don't need the extra argument
07:44 <jle`> > stuff ()
07:44 <lambdabot> 10
07:44 <phz_> roundhouse: I’ve done that
07:44 <phz_> your problem
07:44 <phz_> see:
07:44 <phz_> https://github.com/phaazon/spectra/blob/master/src/resource.rs#L17
07:44 marfoldi joined
07:44 <jle`> well, you can write a function that converts any `() -> a` into an `a`
07:44 <phz_> in Haskell, it’d be a simple typeclass
07:45 <phz_> and associated types as well
07:45 <jle`> as a higher-order function
07:45 <phz_> if you don’t need arguments at loading, you just set type Args = ();
07:46 <roundhouse> ok, but then I have to call load with "()" all the time, correct?
07:46 <mpickering> what is the purpose of this abstraction because it seems like you could define "data AssetLoader a b = AssetLoader (a -> b)"
07:46 <phz_> roundhouse: yeah
07:46 <phz_> but you can add a special method for that case :)
07:46 Rainb joined
07:46 <phz_> like load_ ;)
07:46 <mpickering> and you have function "loadAsset :: AssetLoader a b -> a -> b"
07:46 <roundhouse> jle`: I guess that works
07:46 fizbin1 joined
07:46 <jle`> you can also abstract over the application as well; loadFoo :: A a b -> (b -> a), loadFoo_ :: A a () -> a
07:46 connrs joined
07:47 <jle`> loadFoo_ (A f) = f ()
07:47 jud^ joined
07:47 eklavya joined
07:47 <roundhouse> mpickering: assetloader has more stuff, this is just the issue I ran into. It e.g. also saves the assets
07:47 <mpickering> I don't advise doing anything complicated with type classes
07:48 <jle`> you can also write bIsUnit :: (() -> a) -> a
07:48 <phz_> I’d say use type classes
07:48 raichoo joined
07:48 <roundhouse> I actually have atype class right now
07:48 <roundhouse> but it is way to complicated
07:48 <phz_> it’s typically the right ad-hoc situation type classes will help you solve in a great and flexible way
07:48 <jle`> but, writing a spcial case for b ~ () is definitely a route that a lot of people and libraries take
07:48 jgertm joined
07:48 LuckyRawApe joined
07:48 <jle`> it's roughtly equivalent to runStateT vs. runState
07:49 <jle`> runState being a special case of runStateT when m ~ Identity
07:49 <phz_> jle`: for Identity
07:49 <roundhouse> https://github.com/r-raymond/purple-muon/blob/master/src/Client/Assets/Generic.hs
07:49 <phz_> yep.
07:49 <roundhouse> is the current type class
07:49 BartAdv joined
07:49 <roundhouse> but I'd like to remove it for a simple data type
07:49 fizbin joined
07:49 <roundhouse> thanks, I'll just implement some helpers for the special case ()
07:50 gregman_ joined
07:51 <jle`> it's not the cleanest method but it's simple enough
07:51 <jle`> and used pretty widely
07:51 <roundhouse> cool
07:52 <roundhouse> I'll have to read more source code of other people
07:52 geekosaur joined
07:52 fizbin1 joined
07:53 <jle`> to be clear, i don't mean necessarily that special-casing () is common, just that special-casing the situation where specific types are used in type parameters is common
07:53 <jle`> like how you have `runStateT :: StateT s m a -> s -> m (a, s)`
07:54 jbuurlage joined
07:54 <jle`> but in the case where m is Identity, transformers offers a special-case convenience function, runState :: StateT s Identity a -> s -> (a, s)
07:54 <roundhouse> I see
07:55 <roundhouse> thanks again!
07:55 <jle`> no problem!
07:55 bjz joined
07:55 freusque joined
07:55 fizbin joined
07:56 locallycompact joined
07:56 augur joined
07:58 ramzifu joined
07:59 Yuras joined
07:59 ccomb joined
07:59 Claudius1aximus joined
08:01 xywbtu joined
08:01 ventonegro joined
08:01 binaryplease joined
08:02 afnizarnur joined
08:03 Glooomy joined
08:03 data_hope joined
08:04 jchia joined
08:05 lep-delete joined
08:07 jchia joined
08:09 CurryWurst_ joined
08:12 peterbecich joined
08:13 mceier joined
08:13 mszczygiel joined
08:14 freusque joined
08:15 zar joined
08:15 bennofs joined
08:15 bjz joined
08:15 Guest42979 joined
08:16 Rodya_ joined
08:16 vlnts left
08:17 Guest42979 left
08:17 tromp joined
08:18 puregreen joined
08:18 tomphp joined
08:19 ClaudiusMaximus joined
08:19 fakenerd joined
08:20 kylefang joined
08:30 <ertes> helo
08:30 binaryplease joined
08:31 takuan joined
08:32 dolio joined
08:32 MarioBranco joined
08:32 mansa joined
08:33 azahi joined
08:34 vydd joined
08:35 badlands joined
08:35 eacameron joined
08:39 free_beard joined
08:44 ub joined
08:46 data_hope joined
08:47 baldrick joined
08:47 mkeyhani joined
08:48 louispan joined
08:49 dawehner joined
08:50 sypwex joined
08:51 biglama joined
08:52 binaryplease1 joined
08:52 sanett joined
08:53 kyle joined
08:54 mekeor joined
08:56 louispan joined
08:58 patbecich joined
08:58 freusque joined
08:58 detrumi joined
09:00 fizbin1 joined
09:01 Rodenbach joined
09:01 certainty joined
09:02 zero_byte joined
09:03 fizbin joined
09:06 mansa joined
09:07 fizbin1 joined
09:07 juhp joined
09:08 patbecich joined
09:09 marr joined
09:10 fizbin joined
09:10 sanett_ joined
09:11 mmn80 joined
09:12 oish joined
09:13 jaspervdj joined
09:14 peterbecich joined
09:14 fizbin joined
09:16 Rodya_ joined
09:17 tsmish joined
09:17 kritzcreek_ joined
09:17 fizbin1 joined
09:18 inad922 joined
09:19 bbcue joined
09:22 jgertm joined
09:23 sypwex joined
09:24 Glooomy joined
09:24 ebzzry joined
09:24 bbcue joined
09:26 Kundry_Wag joined
09:27 roundhouse left
09:29 bbcue joined
09:31 juhp joined
09:31 rcat joined
09:32 nilof joined
09:33 louispan joined
09:37 danza joined
09:38 soupy joined
09:38 <soupy> are parentheses in lambda calc primitive?
09:39 <soupy> When I want to say \xyz.xy(xz) ; can I somehow define it without using parentheses anywhere?
09:39 <soupy> I mean, it seems like a let..in construct, but shouldn't that be stated as a primitive?
09:40 carlosdagos joined
09:41 takle joined
09:41 sanett joined
09:42 oisdk joined
09:42 <Saizan> the way i think of it is that a lambda calculus term is a tree, and the parentheses are just a way to write that tree as a flat string
09:42 freusque joined
09:43 Xanather joined
09:43 Sampuka joined
09:43 <soupy> Saizan: saying "it's a tree" sounds equivalent to "you can use parentheses" - can you perhaps unpack that further?
09:44 alfredo joined
09:45 <soupy> also, would that mean that parentheses are exactly what allow branching then?
09:45 <soupy> Is lambda calc without parentheses completely trivial and boring?
09:46 <Saizan> i'd say grouping rather than branching
09:46 <Saizan> and yeah, you're pretty limited without parentheses
09:47 <soupy> is there a precise way to say what I'm limited to, perhaps context sensitive grammars or something like that?
09:47 louispan joined
09:48 takle joined
09:48 <Saizan> a simple way would be to always require parentheses, around each lambda and each application
09:48 <Saizan> soupy: are you familiar with haskell?
09:49 <Saizan> btw, i hate that most books don't put spaces, it's much more readable if you write \x y z. x y (x z)
09:49 <* ski> . o O ( polish notation )
09:49 <soupy> yes, sure
09:50 <* Saizan> blames latex's math mode
09:50 <* ski> . o O ( ` x y z @ @ x y @ x z' )
09:50 <Saizan> soupy: parentheses in LC are used just like in haskell
09:50 <soupy> uh, that's like putting the cart before the horse
09:51 <soupy> don't you think?
09:51 lukaramu joined
09:51 <Saizan> nope, because there are haskell implementations which you can use to test your terms
09:52 salva0 joined
09:53 <soupy> I mean, it doesn't help to denote the expressive power of 'LC w/o parentheses' concisely, which is all I'm asking, really.
09:54 <* ski> . o O ( `data Expr = Var Ident | Abs Ident Expr | App Expr Expr; display :: Expr -> String; display (Var i) = displayIdent i; display (Abs i0 e1) = "\" ++ displayIdent i0 ++ display e1; display (App e e0) = "@" ++ display e ++ display e1' -- no brackets. parser is an exercise )
09:55 <Saizan> soupy: oh, i didn't get you were asking that
09:55 <Saizan> soupy: i don't know
09:55 <soupy> haha, ok thanks, it's more of a cstheory question than a Haskell question anyway
09:56 dawehner joined
09:59 mansa joined
10:00 Kundry_Wag joined
10:03 mekeor joined
10:06 govg joined
10:07 splanch joined
10:07 KorriX joined
10:08 locallycompact joined
10:08 CurryWurst joined
10:09 locallycompact joined
10:09 patbecich joined
10:09 doomlord joined
10:10 Aidan[m] joined
10:10 doomlord joined
10:10 dawehner joined
10:11 sanett joined
10:11 doomlord joined
10:12 doomlord joined
10:13 doomlord joined
10:13 uglyfigurine joined
10:13 <augur> whats the current best way to get a haskell app running on a server?
10:14 doomlord joined
10:14 FreeBirdLjj joined
10:14 <lep-delete> i for one just statically compile
10:14 geekosaur joined
10:15 peterbecich joined
10:16 Gurkenglas_ joined
10:17 Rodya_ joined
10:17 <mekeor> i guess, you don't want to compile it on the server, huh?
10:17 mansa joined
10:18 tromp joined
10:18 binaryplease joined
10:18 Itkovian joined
10:20 tomboy64 joined
10:21 <orion> augur: I compile my Haskell programs and link them statically against musl.
10:21 baldrick joined
10:21 <augur> orion: oh?
10:21 data_hope joined
10:21 <augur> lep-delete: hows that?
10:22 <augur> mekeor: i'm investigating how to do that, but i'm not very familiar with the tools for that stuff
10:22 sdothum joined
10:22 <Rembane> orion: Do you have a writeup for how to do that?
10:23 insitu joined
10:24 sphinxo joined
10:27 locallycompact joined
10:27 <ertes> augur: i mostly use nix to build docker containers these days
10:28 <ertes> augur: if that's not possible, i use nix to extract the closure and just send a tar.gz of it to the target host
10:28 <ertes> closures are self-contained
10:28 <augur> i wish i understood what this means :(
10:28 mrjake left
10:29 certainty joined
10:29 castlelore joined
10:29 castlelore joined
10:29 <orion> Rembane: I don't have a formal writeup, no. I use docker for everything: https://github.com/centromere/ghc-musl-bootstrap
10:29 vektorweg1 joined
10:30 <ertes> augur: after you have built a haskell package using nix, you get a "derivation", a directory in the nix store that holds your package… the "closure" of that derivation is the set of nix store paths that your package needs… everything from glibc and all haskell libraries to the derivation itself
10:30 <ertes> augur: you can just feed that list into 'tar' to get a package that you can extract on the target host, and it will just work (assuming same architecture)
10:31 sanett joined
10:31 <Rembane> orion: Informal works, git repo works even better. Thank you! :)
10:32 ddere joined
10:32 Itkovian joined
10:35 raynold joined
10:36 Beetny joined
10:36 closures999[m] joined
10:36 wictory[m] joined
10:36 bb010g joined
10:36 alaradia[m] joined
10:36 Naughtmare[m] joined
10:36 davidar_ joined
10:36 TylerCecil[m] joined
10:36 cbHXBY1D[m] joined
10:36 M-krsiehl joined
10:36 bobjason[m] joined
10:36 riaqn joined
10:36 hakan[m] joined
10:36 iffsid[m] joined
10:36 davidar joined
10:36 roadrunner168[m] joined
10:36 jyp[m] joined
10:36 herzmeister[m] joined
10:36 karroffel joined
10:36 FederalRick[m] joined
10:36 travisr joined
10:36 M-BostonEnginerd joined
10:36 curry[m] joined
10:36 Soif[m] joined
10:36 elwan7[m] joined
10:36 unknownln joined
10:36 unclechu joined
10:36 seequ_ joined
10:36 jacqueline[m] joined
10:36 goodboy[m] joined
10:36 monomon[m] joined
10:36 miviotros[m] joined
10:36 moonarch joined
10:36 jmnoz[m] joined
10:36 sudoreboot[m] joined
10:36 zaphar_ps[m] joined
10:36 mmmrrr[m] joined
10:36 MatrixTraveler[m joined
10:36 m4lvin[m] joined
10:36 M-Illandan joined
10:36 Magnap joined
10:36 M-berdario joined
10:36 tester668[m] joined
10:36 M-schmittlauch joined
10:36 colton[m] joined
10:36 jascot[m] joined
10:36 hendrik[m] joined
10:36 TheWizardTower joined
10:36 hiq[m] joined
10:36 corintho[m] joined
10:36 rakete joined
10:36 noraesae joined
10:36 M-Quora joined
10:36 srenatus[m] joined
10:36 chef_excellence[ joined
10:36 gentam[m] joined
10:36 rdesfo[m] joined
10:36 ProofTechnique[m joined
10:36 Guest91110[m] joined
10:36 drasich[m] joined
10:36 aspiwack[m] joined
10:36 M92854[m] joined
10:36 NopeMarker[m] joined
10:36 tfc[m] joined
10:36 Yves[m] joined
10:36 gkaplan[m] joined
10:38 sanett joined
10:40 uglyfigurine joined
10:42 henriksod joined
10:45 govg joined
10:46 mansa joined
10:47 phaji joined
10:47 bjz joined
10:49 sanett_ joined
10:50 sanett joined
10:52 Booba joined
10:52 piyush-kurur joined
10:55 piyush-kurur joined
10:56 yellowj joined
10:56 splanch joined
10:57 <Booba> Hello dear haskellers. I am a not-so-beginner haskeller now. I am somewhat comfortable in monads and monad transformers and wanted to find out how do I design my own monads to encapsulate the effects I am interested in. For example, I've been looking at haskell chat example https://wiki.haskell.org/Implement_a_chat_server and was able to figure it out. I understand how and why it waorks. But I don't see how could I refactor this?
10:57 <Booba> I mean, how do I extract Chat into a separate module, how do I posiibly make it use conduit, elerea or pipes, for intance? Could anyone point me to a guide on how to desgin my own API's?
10:58 mariano joined
10:59 Glooomy joined
11:00 wrengr joined
11:00 silver joined
11:00 deepfire` joined
11:00 deepfire joined
11:00 fizbin joined
11:03 mekeor joined
11:03 <ertes> Booba: most people probably shouldn't create their own monads
11:03 fizbin1 joined
11:04 <ertes> if all you need is a bunch of effects you can interpret in a certain way, free monads are often a good way to go
11:04 tsmish joined
11:04 <ertes> but if all you do in the end is to translate those effects into ones already captured by other monads, you should have just used the other monads to begin with
11:06 <Booba> ertes: thanks for your reply. I hear what you say and I agree, I guess. Maybe I am looking for a way to unambiguate some effects. Or how do I figure out a correct data type for my needs.
11:06 fizbin joined
11:07 binaryplease joined
11:07 <Booba> ertes: Going back to chat example. I see it as a a type that is able to handle Socket type in a specific way: send and receive messages in a certain way. How do I design that?
11:07 <ertes> Booba: by writing code and then improving it
11:07 <ertes> by talking to other haskell programmers
11:07 <ertes> etc.
11:08 <ertes> i don't think there is such a design guide anywhere, and also there is often not one true solution, but many different approaches with unique characteristics
11:09 <Booba> ertes: right. I've written a chat exactly as in the example. How do I improve it to be a reusable module itself? The original example does not introduce any data types. I have a feeling that I could introduce couple of useful ones.
11:10 <ertes> Booba: the chat example is not that interesting to be honest… there aren't too many ways to improve it
11:10 fizbin1 joined
11:10 nulldata joined
11:10 <Booba> ertes: so you're saying that I, most probably, should be looking for making any monads/transformers. Maybe I'd better be designins some sort of State and functions on modifying/reading it?
11:10 <ertes> one improvement i would do is to switch to stream processing (e.g. pipes)
11:10 <nulldata> Hey
11:10 patbecich joined
11:10 <Booba> ertes: should not*
11:10 arpl joined
11:11 <ertes> Booba: you should first make the application more interesting… more complex that is
11:11 ortmage joined
11:11 <nulldata> Is there any way to reference an associated type of a type class in a function signature outside the type class definition?
11:11 <ertes> Booba: the current one doesn't even have any state worth mentioning… all its state is already captured by concurrency
11:12 <ertes> Booba: perhaps turn it into a stateful networked game first
11:12 hiptobecubic joined
11:12 <Booba> ertes: I can see that. For instance, I want to add rooms to a chat. So that any user can create/remove/enter/leave rooms
11:12 <Booba> ertes: oh, a game is a good one.
11:13 <ertes> Booba: you could switch to stream processing along the way
11:13 fizbin joined
11:13 <ertes> nulldata: what do you mean? once defined you can use the AT anywhere
11:14 <Booba> ertes: I imagine that the game would have its own state, right? So it is a data type that hides this state and exposes functions that represent participants turns and actions. Every function might modify state in a certain way.
11:14 <nulldata> ertes: Kinda like this: https://ctxt.io/2/AAAA0LlFEg
11:15 <Booba> ertes: Doesn't it looks like some sort of state transformer monad? Or I am misreading the purpose of transformers?
11:15 <geekosaur> nulldata, it needs the type parameter
11:15 <geekosaur> you want (Var a)
11:15 ziocroc joined
11:15 <ertes> Booba: you won't be able to use state monads a lot, because the state is shared between client threads
11:15 ramzifu joined
11:15 <ertes> Booba: but here is your first abstraction: STM
11:15 ebzzry joined
11:15 <nulldata> So: `liveness :: Liveable a => Block a -> [LivenessBlock (Var a)]`?
11:16 <geekosaur> yes
11:16 <nulldata> Ah, thanks!
11:16 fizbin1 joined
11:16 peterbecich joined
11:17 <Booba> ertes: Ok. Do I get it right that the need for STM comes from the fact that I have green threads processing my connections?
11:18 Rodya_ joined
11:18 <ertes> Booba: no, STM is an abstraction for transactional mutable variables
11:18 <ertes> there is no *need* to use it
11:19 <ertes> Booba: you should probably read The Book
11:19 <ertes> http://chimera.labs.oreilly.com/books/1230000000929/
11:19 petermw joined
11:19 <Booba> ertes: Ok, thanks. I'll dive into that, then.
11:19 <Booba> ertes++
11:20 <ertes> particularly the concurrency part
11:20 eatman joined
11:20 <ertes> so from chapter 7 onward
11:22 mansa joined
11:23 mizu_no_oto joined
11:24 JoaoPortela joined
11:24 <Booba> ertes: I imagine my game API looking like this http://lpaste.net/354006. So there is a Game data type that is a Monad, am I right? Or this is a not a good way do design a module?
11:24 <ertes> Booba: i suggest that you don't try to model an "application monad"
11:24 Lord_of_Life joined
11:25 <ertes> just use IO
11:25 a3Dman joined
11:25 russellw joined
11:25 <ertes> and where applicable Consumer/Producer/Pipe over IO
11:26 JoaoPortela joined
11:26 <ertes> (or whatever your favourite streaming abstraction calls them)
11:26 tsmish joined
11:27 sypwex joined
11:27 <Booba> ertes: I can do that, or at least, I'll try. But I wonder what the next step might be? How do I generalize that? How do I hide the fact that I use IO underneath?
11:27 <ertes> Booba: first try to come up with a valid reason why you would want to hide it
11:27 eacameron joined
11:28 <ertes> "IO is evil" is not a valid reason =)
11:28 <Booba> ertes: what I am trying to say is, how do I expose only those effects that I want to a potential module consumer?
11:28 eatman joined
11:29 <ertes> Booba: you will find ways to design a domain-specific language that simply only allows correct APIs
11:29 Yuras joined
11:29 <ertes> until then you can just not export certain parts of your module
11:29 Einwq joined
11:29 <ertes> Booba: if you want, i can give you an exercise
11:29 <Booba> ertes: I'd love to!
11:30 <ertes> Booba: write the classic game of hangman, just a simple command line program that communicates via stdin and stdout
11:30 <ertes> don't even limit the number of guesses the player has, just let them guess until they have all the letters
11:31 <ertes> once you have it, i will show you many ways to improve it (none of which involve monads) =)
11:31 <Booba> ertes: like this one https://en.wikipedia.org/wiki/Hangman_(game) ?
11:31 <ertes> yeah, exactly
11:31 tangled_z joined
11:32 <ertes> display "_____ _____", ask for a letter, fill in the blanks: "__ll_ ___l_"
11:32 <ertes> ask again, until the phrase is complete
11:32 <Booba> ertes: Ok, I'm on it, then. I thank you for your effort so much!
11:33 CurryWurst joined
11:34 coot joined
11:34 ragepandemic joined
11:35 systadmin joined
11:36 sphinxo joined
11:37 Yuras joined
11:37 <ski> @where PCPH
11:37 <lambdabot> http://community.haskell.org/~simonmar/pcph/
11:38 <ski> @where+ PCPH "Parallel and Concurrent Programming in Haskell" by Simon Marlow in 2013 at <http://community.haskell.org/~simonmar/pcph/>,<http://chimera.labs.oreilly.com/books/1230000000929/>
11:38 <lambdabot> I will never forget.
11:40 petermw joined
11:40 carlosdagos joined
11:41 zar joined
11:41 <ertes> where+ TheBook …
11:41 <ertes> =)
11:42 gleblobanov joined
11:43 sypwex joined
11:46 z3r01 joined
11:47 osfameron joined
11:47 z3r01 joined
11:48 KarboniteKream joined
11:49 deepfire joined
11:49 deepfire` joined
11:49 a3Dman joined
11:52 afnizarnur joined
11:55 sepp2k joined
11:56 ph88 joined
11:57 CurryWurst joined
11:57 <ph88> can someone recommend a package for handling server side for single-page-app ?
11:57 <ph88> maybe a REST package
11:57 Amadiro joined
11:57 <brynedwards> ph88: servant, Spock, scotty
11:57 certainty joined
11:58 <ph88> what are the differences between those 3 ?
11:59 contiver joined
11:59 KarboniteKream joined
11:59 <brynedwards> servant is more focused on API features, the other two are more generic lightweight web frameworks
11:59 <ph88> what do you mean API features ?
12:00 <brynedwards> Spock is based on scotty, it has some more features like a DB helper
12:00 mohsen_ joined
12:00 <cocreature> servant also uses significantly more typelevel magic
12:00 CurryWurst joined
12:00 <ph88> is that a good thing? :P
12:01 <cocreature> that depends on your point of view :)
12:01 <ph88> i don't have one yet :/
12:01 <cocreature> then try it out and decide for yourself :)
12:01 <ph88> servant seems a bit more mainstream
12:01 russellw left
12:01 <ph88> maybe i should go with that
12:01 <brynedwards> Check out servant's tutorial http://haskell-servant.readthedocs.io/en/stable/tutorial/index.html
12:01 <ph88> i saw it mentioned more often and it has more commits
12:01 <quchen> ph88: There are multiple talks by Alex Thiemann about Spock, e.g. from last year’s ZuriHac
12:02 <quchen> ph88: (he’s the author)
12:02 <ertes> ph88: they are all fairly popular
12:02 <ph88> ok i try spock
12:02 <ertes> ph88: scotty and spock are just much simpler, but servant has some type-driven features they lack
12:03 <ertes> particularly for people who would like to derive clients and servers from the same piece of code
12:03 Lord_of_Life joined
12:03 <ertes> so if you plan to use GHCJS for your frontend, servant is probably the best option
12:04 tromp joined
12:04 selthas joined
12:04 niteria joined
12:04 <ph88> probably elm or otherwise purescript
12:05 djellemah_ joined
12:05 Grisha_ joined
12:06 <cocreature> I just wish servant stopped using ExceptT :/
12:08 FjordPrefect joined
12:09 selthas joined
12:09 HoierM joined
12:09 <ph88> so i compile the spock app and run it and it's a webserve r?
12:09 <cocreature> ph88: yep
12:09 insitu joined
12:09 <cocreature> ph88: it’s the same for pretty much all Haskell web frameworks
12:10 <ph88> how can i let it do work on the CLI ? for the user i need the webinterface but i want to do some tasks with CLI
12:10 <ph88> import files should happen from CLI, view files from webinterface
12:11 <ph88> or should i let the compiler make 2 binaries for that ?
12:12 refold joined
12:12 niteria joined
12:12 patbecich joined
12:12 gguy joined
12:13 eatman joined
12:14 <cocreature> unless you have a good reason for embedding a cli and a webserver in in the same executable, I would use separate executables
12:14 <ph88> ok
12:14 skeuomorf joined
12:15 <ertes> ph88: you can either have a (web?) API used by a separate CLI program, or you can fire up a CLI thread
12:15 <ph88> would it be a good idea to put the two executables in the same project or is it better to create separate stack projects ?
12:16 <ph88> a CLI thread ?
12:16 <gguy> Is there a fundamental reason why type literals are kinds? Currently I can embed string information into datatype like this: 'type CRLF = Proxy "\r\n"' but I'd rather do this: 'type CRLF = "\r\n"'
12:16 <ertes> ph88: if you want the executables to be in separate cabal packages, you probably need three packages: a common API package, a server package and a client package
12:16 ramzifu joined
12:16 <ph88> ertes, i like to keep it as simple as possible, quick n dirty
12:16 niteria joined
12:17 <cocreature> gguy: type CRLF = "\r\n" should work just fine
12:17 <ertes> gguy: there is no value of type "\r\n", so you need the proxy (or explicit type signatures) to pass the type information around
12:17 chlong joined
12:17 <cocreature> gguy: they are not also not kinds. their kind is Symbol
12:17 <ertes> gguy: otherwise you would have to type: f (Proxy :: Proxy CRLF)
12:17 peterbecich joined
12:17 <ertes> with the first verison you can type: f (Proxy :: CRLF)
12:18 selthas joined
12:18 niteria joined
12:18 <ertes> ph88: it's up to you… you can write a package that includes a library and two executables that use that library
12:18 sanett joined
12:18 Itkovian joined
12:19 <ph88> ertes, a library ? you mean a haskell module file ?
12:19 niteria joined
12:19 <ertes> ph88: a 'library' section
12:19 <ph88> in the cabal file ?
12:19 <ertes> yes
12:19 <gguy> cocreature: Symbol, yes... I'm still getting my head around that :)
12:20 <ph88> how do i find out how i can make the cabal file so that it has a library and two executables that use that library ?
12:20 <ertes> ph88: here is my project skeleton: https://github.com/esoeylemez/skeleton/blob/skeleton/skeleton.cabal
12:20 <cocreature> ph88: https://cabal.readthedocs.io/en/latest/developing-packages.html#developing-packages read the cabal docs :)
12:21 <cocreature> ph88: https://cabal.readthedocs.io/en/latest/developing-packages.html#example-a-package-containing-a-library-and-executable-programs is an example of exactly that
12:21 msl09 joined
12:21 <ph88> ertes, how does this compare with the CLI thread option on difficulty of coding ?
12:21 <gguy> ertes: sure yes I'm using Proxy at the moment, I was just hoping I'd missed some work around to allow Strings as types
12:21 <ph88> cocreature, ok thx i read the docs
12:21 <ertes> ph88: the separate executable option definitely needs more engineering
12:22 <ertes> because you can't just access the state of the running thread, but you need to design an actual run-time API for communication
12:22 <ph88> ertes, ok let's not go with the separate executable option then :/
12:22 <cocreature> gguy: I’m repeating myself but they _are_ types. 'type Foo = "foo"' works just fine
12:22 <msl09> hello I have a question about type class instances
12:22 <cocreature> gguy: if it doesn’t you might need to enable DataKinds or upgrade GHC
12:22 <ph88> how do i find out how the option works with the separate CLI thread ?
12:22 <msl09> in learn you a haskell http://learnyouahaskell.com/making-our-own-types-and-typeclasses#typeclasses-102
12:22 <gguy> sure cocreature it works
12:23 <ph88> msl09, go ahead
12:23 <gguy> I probably shouldn't use that example
12:23 <ertes> ph88: well, have the web server in a separate thread, and let your main thread be the CLI
12:23 <gguy> data CRLF = CRLF "\r\n"
12:23 <msl09> it is said that this eq instance declaration is invalid:
12:23 <msl09> instance Eq (Maybe m) where Just x == Just y = x == y Nothing == Nothing = True _ == _ = False
12:23 mmhat joined
12:23 asthasr joined
12:24 <ertes> msl09: you say x == y, where x and y are of type 'm'
12:24 <ertes> but there is no Eq constraint on 'm'
12:24 <cocreature> gguy: that fails because the _kind_ of "\r\n" is Symbol but a data declaration expects things of kind *
12:24 <msl09> yeah
12:24 <ertes> msl09: instance (Eq a) => Eq (Maybe a) where …
12:24 <ertes> msl09: values of type (Maybe a) can only be compared, if values of type 'a' can be compared
12:25 <cocreature> that error message is really confusing.
12:25 <msl09> but doesn't a Just x == Just y = x == y implies that x and y must be instances of Eq?
12:25 <gguy> cocreature: yes which is a feature of datakinds, was hoping there was a seperate extension that was of kind *
12:25 <ertes> msl09: no, they *need* the type of x and y to be Eq
12:25 <cocreature> gguy: what do you expect data CRLF = CRLF "\r\n" to do? what should the constructor store?
12:25 <gguy> but I guess that would be confusing
12:25 <gguy> nothing
12:25 <ertes> msl09: but your instance is claiming that no Eq on 'm' is necessary
12:26 kosorith joined
12:26 <ertes> msl09: example:
12:26 <ertes> blah :: a
12:26 <ertes> blah = 5
12:26 <ph88> msl09, you should let haskell know that logically when you want to compare some stuff inside Maybe that the stuff inside can be compare in the first place. So Eq m says that m is everything that has a compare function (implemented by the Eq type class) and then in Eq (Maybe m) m can not by EVERYTHING anymore, it can only be everything THAT CAN BE COMPARED
12:26 e14 joined
12:26 migimunz joined
12:26 nighty- joined
12:26 <ertes> msl09: the type signature claims that 'blah' can be *anything*, but then it requires 'a' to be a Num instance
12:27 <geekosaur> msl09, when you specify a type for something, it overrides type inference and is considered the final authority. so if it does not specify Eq m =>, it is saying that m does not need an Eq instance.
12:27 <asthasr> Are there any good articles about how practical servant is versus more traditional (i.e. not type-level) frameworks? Or perhaps in other contexts where TL programming is used vs. a more traditional alternative
12:27 <asthasr> I don't feel that I have a really good grasp of the benefits of type level programming, so I'm interested.
12:27 <ph88> msl09, yes you are right that == implies that x and y must be able to be compared, but for some reasons you must be explicit about this. This is a design choice of GHC that this is not automatically accepted
12:28 importantshock joined
12:28 <msl09> I think I undestand geekosaur definition
12:28 <ertes> msl09: type sigantures aren't automatically augmented by extra information from the actual definition
12:28 <ertes> so if you say (blah :: a), then you mean it
12:28 <msl09> ic
12:28 <ertes> blah can be anything
12:28 importantshock joined
12:28 <gguy> cocreature: I'm deriving parsers using GHC generics from data types where "instance (KnownSymbol a) => Parser (Proxy a) where parser = parseString $ symbolVal (Proxy :: Proxy a) "
12:29 <ertes> and the compiler disagrees, because it actually checks the definition against your type signature
12:29 teppic joined
12:29 nulldata joined
12:29 Gloomy joined
12:29 <ph88> ertes, when i start that program (with cli and web thread) i guess i want it to go run the webserver .. but then how do i enter CLI commands? in a REPL like fashion? normally CLI are just one-off commands and the program terminates after each command
12:30 henriksod joined
12:30 <geekosaur> you can have it listen for commands from some other channel, or you can have the CLI connect to the web server and send commands that way
12:30 <nulldata> Hey, how would I go about constraining an associated type (For example making sure it's Eq)?
12:30 <geekosaur> usually for a web server the latter is easier
12:30 <gguy> cocreature: then using ghc generics I can parser the "or" case e.g. 'data LineEnd = CRLF (Proxy "\r\n") | LF (Proxy "\n")'
12:31 <gguy> anyways, just an idea i want to play out to completion... using proxy makes things abit messy
12:31 <cocreature> gguy: I think what you really want is singletons for Symbols instead of the weird KnownSymbol stuff & proxies. I’ve wanted this myself several times so I can definitely empathize with that feeling :)
12:31 <ph88> geekosaur, just asking where the commands from the other channel should come from .. i know i want to type them in my terminal .. other than that not sure
12:32 <gguy> yeah, I went the singletons route but the instances bloated the code out to be more bloated then I'd hoped
12:32 djellemah_ joined
12:32 <ph88> msl09, type classes can be used for what is known as generic programming in other languages, it took me a while before i figured that out .. just saying cuz that info is not in LYAH
12:32 <ertes> ph88: if you want the program to be batch-style, you *need* an API
12:33 <ertes> ph88: note that you can have both the web server functionality and the command-line API in the same executable
12:33 <cocreature> gguy: it’s kind of annoying how we have all those fancy features but using them can become painful quite quickly
12:33 <migimunz> Hi everyone. I'm writing a parsec parser for a toy haskell-like language for fun, and I'm having a bit of trouble with indentation. I can't get a parser to stop parsing when the next line is "dedented", it attempts to continue parsing greedily. Here's a short example if someone can take a look: https://gist.github.com/migimunz/3fc30b6b6a4005626edfe745844b65fb
12:33 <ph88> ertes, but if the web server is running should i launch another process of the same executable ?
12:34 <ph88> not sure what you mean with batch-style
12:34 <msl09> ph88, geekosaur, ertes does that mean that there is no type inference for type declarations?
12:34 <ertes> ph88: let's say your executable is named 'blah'
12:34 <ertes> ph88: then you can have a "blah daemon" command that runs the actual web server
12:34 <gguy> cocreature: the real goal is I want to rewrite an application that parses binary, can reproduce the binary, and also produce that in HTML form
12:34 <ph88> msl09, the types are infered but the constraints are not infered as far as i know
12:34 <ertes> and then you can have "blah quit" that perhaps connects to some unix socket created by the daemon and tells it to quit through a JSON API
12:35 afnizarnur joined
12:35 <ertes> msl09: as geekosaur said, inference does not apply if you write a type signature, and for instance you *always* write a full instance head
12:35 <ertes> msl09: so for instances you *must* be explicit about the constraints
12:35 <ph88> msl09, another thing i found out later is that the => notation is very closely related to logic programming, it wouldn't hurt to read this page for example http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse1 and then realise that => is VERY closely related
12:36 <ertes> msl09: it's not that inference doesn't infer it (it could), but that inference isn't used at all
12:36 <geekosaur> msl09, there's an extension in ghc8 that allows partial type signatures with missing parts inferred. I would recommend against using it unless you fully understand the type system
12:36 <lyxia> migimunz: can you give us more context.
12:36 justanotheruser joined
12:36 <migimunz> lyxia, I can paste the whole thing sure, I just hoped that gave a minimal example. Sec
12:36 edwtjo joined
12:36 edwtjo joined
12:37 <msl09> geekosaur: actually I just wanted to know what to watch out for :]
12:37 <ph88> ertes, ah so communicate through unix pipes ? but then it's still 2 processes and not CLI thread right ?
12:37 <geekosaur> ph88, unless your system can deal with changes made from outside such that the CLI can do things by itseldf (this is uncommon and highly error-prone), your CLI *must* send commands to the server
12:37 <migimunz> lyxia, here it is: https://gist.github.com/migimunz/dcfa6a2f85ce46003bda75d52bfec04d
12:37 <ertes> ph88: yes
12:37 <gguy> cocreature: I already have the application in a working state but it's a pain to maintain both parsers, printers, and html generators. Not to mention the filtering etc I want to do. GHC generics gets me closer since I can generate a generic HTML version of the data (then just style with css). But the parser is abit trickier to define using instances in some generic way since every singleton is a separate instance
12:37 <ertes> ph88: and more likely sockets, not pipes
12:37 <migimunz> I'd also appreciate any other advice you can give, I've read in places that Parsec is no longer actively developed and that there are other alternatives like megaparsec or attoparsec, but I don't really have much experience
12:38 <ph88> ertes, ok it seems simple .. but i'm still curious .. how would the CLI thread option work ?
12:38 <ertes> ph88: keep in mind that by using unix sockets you give up portability to some systems (e.g. windows)
12:38 <gguy> cocreature: anyways thanks for the help... that's my rant for the night
12:38 <ertes> ph88: well, with the CLI thread the idea is that your program starts the server and the provides a REPL during its run-time
12:39 ramzifu joined
12:39 <lyxia> migimunz: that's better
12:39 vaibhavsagar joined
12:40 <geekosaur> ph88, note that that means your program does not run as a daemon, it starts up the web server component and then issues a prompt on the terminal you started it from. if you don;t start it from a terminal, you can't use its prompt
12:40 <migimunz> lyxia, thing is, I get why it's doing it - I have a many1 that attempts to parse type or var names greedily, and that just consumes whatever it can until it says "oh wait, this isn't a type/var, and isn't properly indented"
12:40 <ertes> ph88: something like this: main = withDB … $ \db -> withAsync server $ \s -> repl `finally` (cancel s >> wait s)
12:40 <migimunz> wish I could express "until dedent" somehow
12:40 <ph88> migimunz, i investigated a bit on megaparsec and attoparsec, attoparsec is better for things that are generated by a machine (such as export scripts or APIs) and megaparsec better for human written things (like source code) .. because attoparsec is much faster but it can not track the position in the source very well
12:40 boxscape joined
12:41 nomicflux joined
12:41 djellemah_ joined
12:41 <migimunz> ph88 I'll check out megaparsec as well. I don't mind scarce docs that much, but with these it's sometimes impossible to tell what functions do just by looking at the types
12:41 Amadiro joined
12:42 <ph88> ertes, ah yes ok so i have 3 options, 2 executables, 1 executable run multiple times, 1 executables with threading ... i think the second option might be the most simple one
12:42 sanett joined
12:42 <ertes> migimunz: if you don't mind scarce docs, have a look at trifecta as well =)
12:42 <geekosaur> ph88, it's not necessarily easier, it can be much harder
12:42 oish_ joined
12:42 <ertes> ph88: in terms of engineering simplicity the third option is definitely the easiest one
12:43 <geekosaur> do the two instances running each have to know about any changes the other has made? if so, that second solution will be much harder
12:43 <geekosaur> and much easier to get wrong
12:43 <cocreature> ph88: do you have some database or some other external data store?
12:43 <ph88> yes elasticsearch and maybe sqlite if i need it
12:43 <cocreature> then it’s pretty easy to have multiple executables because you don’t need to reinvent ipc
12:43 <ph88> ok
12:43 <migimunz> ertes, checking it out, thanks :D
12:43 <cocreature> just have both applications write/read to a database and everything should be fine
12:44 <ph88> so i read the section in the cabal manual to make 2 executables and then do the stuff on elasticsearch
12:44 <ph88> ok
12:44 <ertes> ph88: BTW, if your commands only need to do data changes, then having a separate executable is not only easy, but in fact preferred
12:44 <ph88> ok
12:44 <ertes> ph88: because it doesn't actually need to know anything about the running web server
12:44 <ph88> yeah
12:44 <ertes> of course you can still get this wrong, if the web server and the CLI disagree on data consistency
12:45 sanett joined
12:45 <nulldata> How would I go about constraining an associated type (For example making sure it's Eq)?
12:45 <ertes> nulldata: instance (Eq (F a)) => C a where type F a = …
12:46 fakenerd joined
12:47 xaph joined
12:48 Shatnerz joined
12:48 <ph88> migimunz, shouldn't parseTypeDeclaration fail when sameOrIndented fails ? why do you think it tries another time with many1 ?
12:48 <nulldata> ertres: Uhn, how about for a associated type in a type class (https://ctxt.io/2/AAAA0EUhEg) or am I misunderstanding your snippet?
12:48 sanett joined
12:48 handyc joined
12:49 <geekosaur> what part of that snippet is confusing you?
12:49 <geekosaur> instance Eq (Var a) => Liveable a where type Var a; ...
12:50 <nulldata> Oh I see
12:50 <geekosaur> (you no longer need the (:: *) because the Eq instance forces that)
12:51 <lyxia> migimunz: you don't ever set the level of reference
12:51 <lyxia> do you?
12:52 sanett joined
12:52 <migimunz> lyxia, I thought withPos does that
12:53 <nulldata> So like this? (https://ctxt.io/2/AAAAAK4MFA)
12:53 <migimunz> ph88: it does fail, but also says unexpected '=' on line 7, column 3
12:53 <migimunz> that's what had me confused
12:53 <lyxia> oh I'm blind.
12:53 <gguy> oh, anyone know of any haskell that defines all (or most) singletons for all the chars?
12:54 <geekosaur> hm, actually I wonder if that's true still
12:54 <geekosaur> :k Eq
12:54 <lambdabot> * -> Constraint
12:54 <geekosaur> ok
12:54 <migimunz> lyxia, to be honest I don't really know how indentation based languages are supposed to be parsed - when I used to do it manually a long time ago, I made my tokenizer emit separate INDENT and DEDENT tokens, which is probably not an ideal approach
12:54 <migimunz> then I just treated them like regular tokens in the parser, but that was a lot less complicated language as well
12:55 <codedmart> Is there an extension or a way to do somethin like this? https://gist.github.com/codedmart/b768414e5025de7625819066ff58f4ec
12:55 <ph88> migimunz, when it fails you need it to backtrack on the parts that it had already consumed. So when you expect ABC and you have ABDD then it eats AB and leaves you with DD then the next parser is confused why it starts with DD and not ABDD so look for "try" function
12:55 <nulldata> Well what I posted is not right, I get a syntax error..
12:55 <lyxia> migimunz: you're setting the reference at the start of the line though
12:55 <migimunz> ph88: hm, I did leave off try for the last alternative
12:55 <ph88> migimunz, i think identation is tracked within the state of the parser, but i'm not sure
12:56 <migimunz> ph88: it is, yeah
12:56 <ph88> migimunz, many1 $ try myParser maybe this
12:56 <migimunz> lyxia, yeah, I don't necessarily want it to be indented past the data keyword, just mode than the start of the line
12:56 <geekosaur> codedmart, you would not normally use case for that, case is about structure not values
12:56 <migimunz> ph88 thanks, trying it now!
12:56 insitu joined
12:56 _ashbreeze_ joined
12:56 mada joined
12:57 <geekosaur> codedmart, if you want to do that, use guards
12:57 <geekosaur> don't try to twist case expressions to do values instead of structure
12:57 <migimunz> ph88: nope, same thing :/
12:57 <codedmart> geekosaur: Good point I guess I was overlooking that.
12:57 <codedmart> Thanks!
12:58 plutoniix joined
12:58 <migimunz> reading megaparsec docs too, there's a blog post claiming that it has support for indentation based languages, should probably investigate
12:58 <migimunz> or should stop being lazy and read the actual source of the parser to understand what's going on under the hood
12:58 <lyxia> migimunz: change line 110 to fields <- (sameOrIndented *> (simpleTypeExpr <|> nestedTypeExpr)) `sepBy` spaces
12:59 <lyxia> this checks in every field whether you're still in the same block
12:59 augur joined
12:59 <migimunz> lyxia, thank you! That worked, now I just have to figure out why
12:59 <migimunz> aah
12:59 xgley joined
13:00 Boomerang joined
13:01 <migimunz> lyxia, oh I see what you mean, it basically does the sameOrIndented check for every separated element and discards the ()
13:01 <migimunz> thanks a lot lyxia, ph88
13:01 xgley left
13:01 netheranthem joined
13:02 mojjo joined
13:03 sypwex joined
13:04 splanch joined
13:07 cdg joined
13:09 <lpaste_> gguy pasted “StateT Int Parser Trace” at http://lpaste.net/354012
13:09 xtreak joined
13:09 <gguy> migimunz: if you give up on using something existing you could always just store the indent info in StateT (code above)
13:10 <gguy> migimunz: that's some code I have using attoparsec
13:10 theelous3 joined
13:10 <gguy> not for indent ofcourse, but could mold to your need
13:11 ramzifu joined
13:12 teqwve joined
13:12 teqwve left
13:14 patbecich joined
13:14 kuribas joined
13:18 peterbecich joined
13:19 splanch joined
13:19 Rodya_ joined
13:20 cic joined
13:21 xaph joined
13:22 <migimunz> gguy: I was hoping to avoid having to do that by picking up a library that does exactly that sort of thing for me - unfortunately, using it proved a bit trickier
13:22 <migimunz> well, coupled with the fact that I'm not all that familiar with Parsec
13:24 fakenerd joined
13:24 KarboniteKream joined
13:24 Phillemann joined
13:25 eacameron joined
13:25 <Phillemann> Is there a haskell type for HTML data? I'd like to create HTML programmatically and convert it to a bytestring (or something) later.
13:25 locallycompact joined
13:25 <Phillemann> I mean, not in the Prelude, of course.
13:26 dfeuer joined
13:26 <ezyang> There's xhtml
13:27 <ezyang> that's an old library. There are newer ones too, I think
13:27 revprez joined
13:27 <ahihi> @hackage lucid
13:27 <lambdabot> http://hackage.haskell.org/package/lucid
13:28 <Phillemann> Ah, thanks.
13:29 ekinmur joined
13:30 lush_ joined
13:32 kosorith joined
13:32 <lush_> hey everyone, is there a nixos user here?
13:33 <gguy> lush_: I'm a nixos noob :)
13:33 <lush_> gguy: me too I installed it yesterday ^^
13:34 <gguy> haha, good luck
13:34 <rom1504> you only had one question, it has been answered
13:34 revprez joined
13:34 <lush_> gguy: I don't really get how I should start haskell projects using cabal + nix-shell.. have you got some advice? :-D
13:34 <rom1504> :d
13:34 <lush_> gguy: to be more precisely I thought about playing around with hakyll and start a little website where I can toy with its features
13:35 ystael joined
13:35 <gguy> lush_: yes, there are a few different ways people do it, but for the most part nix replaces vast amounts of what you might use cabal for
13:36 lukaramu_ joined
13:37 <gguy> basically when I want to bring up an environment to compile I do a "cabal2nix --shell > shell.nix; nix-shell" if i typeds that correctly
13:37 <gguy> hakyll... 2 secs let me look
13:38 <lush_> gguy: so you start a project and add a cabal file etc first and then use cabal2nix to get it running with nix-shell?
13:39 umib0zu joined
13:39 <gguy> yes, nix-shell paths all the required dependencies listed in the shell.nix file (which were derived from the cabal file)
13:39 xanadu_ joined
13:40 <gguy> the trickiest part will be getting your favorite ide working... if you use emacs you might find it easier
13:40 ozgura joined
13:41 <lush_> so I start "a usual cabal" project with cabal files etc and then let that get translated through cabal2nix?
13:41 <lush_> how about atom? :-D
13:41 meba joined
13:42 <gguy> lush_: did you work out how to install hakyll in nixos?
13:43 plutoniix joined
13:43 eschnett joined
13:43 ij left
13:44 crobbins joined
13:44 takle joined
13:46 <gguy> lush_: don't know about atom
13:46 <gguy> lush_: yes create a cabal file as normal and run cabal2nix
13:47 <gguy> lush_: eventually you will get to the stage where u think it's wise to not use cabal at all, which is true, but editor will like it better when there is a cabal file
13:48 mson joined
13:48 <gguy> lush_: if you want to install directly to your envionment you can run: nix-env -f "<nixpkgs>" -iA haskellPackages.hakyll
13:48 jwsuiw joined
13:48 sanett joined
13:49 Cale joined
13:50 saysjonathan joined
13:51 simukis__ joined
13:51 <lush_> gguy: I thought that I could set up nix-shell to download ghc, hakyll etc just within that sandbox?
13:52 <gguy> yep absolutely
13:53 mmn80 joined
13:53 Big_G joined
13:53 <lush_> gguy: so I start that like: nix-shell -p haskellPackages.hakyll ?
13:54 SpinTensor joined
13:55 <gguy> lush_: yep
13:55 <gguy> lush_: can add atom in there too etc
13:55 locallycompact joined
13:56 <lush_> gguy: and then I've got ghc etc in there as well. Can I start like this and when I realize that I need another packages as well just "reenter" that environment through the same command with the package added?
13:56 marvin2 joined
13:56 <gguy> lush_: sure
13:56 <lush_> alright cool thanks man
13:56 <msl09> I have another newbie question
13:57 <gguy> lush_: good luck :)
13:57 revprez joined
13:57 Booba joined
13:57 <msl09> when learning about Functors I mistyped a statement
13:57 <msl09> Prelude> fmap (*2) Just(1)
13:57 <Booba> ertes: Hi, here's what I came up with http://lpaste.net/354013
13:57 <KorriX> Hello! - Is there a way to get a type-level list of all function argument types? For example if f :: Int -> Char -> Bool I'd like to get '[Int, Char] on the type level
13:57 <msl09> and ghci yelled at me "Non type-variable argument in the constraint: Num (Maybe t)"
13:57 <Cale> msl09: right.
13:58 <msl09> what does ghc believes I trying to do?
13:58 <Cale> Because that'd be ((*2) . Just) 1
13:58 <Cale> You're using the Functor instance for (->) e
13:58 <Cale> fmap :: (a -> b) -> (e -> a) -> (e -> b)
13:58 <Cale> in that instance
13:58 eacameron joined
13:58 <vaibhavsagar> hey, I have a question about a free monad thing: http://lpaste.net/9158315209444556800
13:58 revprez joined
13:58 <msl09> I was actually trying to do "fmap (*2) (Just 3)"
13:58 <Cale> and that's just function composition
13:58 <Cale> yeah
13:59 <Cale> So, it complained at you because what you wrote is equivalent to (Just 3) * 2
13:59 <msl09> hmm
13:59 eacameron joined
13:59 [k- joined
13:59 sanett joined
14:00 <msl09> huh
14:00 <Cale> > fmap (*10) (+5) 1
14:00 <lambdabot> 60
14:00 <Cale> > fmap reverse (map toUpper) "hello"
14:00 <lambdabot> "OLLEH"
14:01 importantshock joined
14:01 <Cale> fmap can specialise to function composition
14:01 sanett joined
14:01 <Akii> vaibhavsagar: change `value` to `Maybe value` in line 7?
14:01 <ertes> Booba: does it work?
14:01 <Booba> ertes: it does
14:01 <Booba> ertes: running on Haskell2010
14:01 <ertes> Booba: great =)
14:02 nycs joined
14:02 <Akii> vaibhavsagar: or `set "ref2" (Just v)`
14:02 revprez joined
14:02 <ertes> Booba: right now i'm too busy, but i can offer you to help you improve it interactively later, or i can just show you my variant and explain it later
14:03 sanett joined
14:03 <lush_> gguy: I'm still a little bit confused. in #nixos they told me that I don't need to install cabal at all (I think) and only use it within a nix-shell
14:03 insitu joined
14:03 <lush_> gguy: so I really write down a .cabal manually to start and then give that to cabal2nix
14:03 <Booba> ertes: I'd like to see yours and try to figure out your thought process while you are busy
14:03 <vaibhavsagar> Akii: I didn't realise it was that simple :)
14:04 uglyfigurine joined
14:04 <ertes> lush_: if you pass --shell to cabal2nix, it will generate an expression that is compatible with nix-shell and nix-build
14:04 carlosdagos joined
14:04 pavonia joined
14:04 <ertes> Booba: https://github.com/esoeylemez/snippets/blob/master/Hangman.hs
14:04 <Akii> vaibhavsagar: pretty neat and compact example, thanks for that
14:04 <Booba> ertes: Thanks a lot!
14:05 <ertes> Booba: high-level explanation: a hangman game is either a game that is already won (Won), or something that presents a challenge and expects a guess (Guess)… hangman games turn out to be a monoid, so they can be composed from single-character games (singleton)
14:05 burtons joined
14:05 <lush_> ertes: ok ty
14:06 <ertes> Booba: and then there is an interpreter that actually runs the game and interacts with the user
14:06 <ertes> hangmanStdio
14:07 Amadiro joined
14:07 Rodya_ joined
14:08 howdoi joined
14:08 babu` joined
14:10 mmachenry joined
14:11 <ertes> Booba: this approach is: 1. compositional (hangman games are constructed by composition), 2. composable (games are first-class), 3. extensible (games form a monoid and there are monoid morphisms to and from it), 4. separation of concerns (game logic vs. user interface)
14:12 sanett joined
14:14 sanett joined
14:14 e14 joined
14:15 patbecich joined
14:15 doomlord joined
14:16 sypwex joined
14:17 coltfred joined
14:19 peterbecich joined
14:19 robertkennedy joined
14:20 Itkovian joined
14:21 <Booba> ertes: to start a game I have to run hangmanStdio parametrized with functions to parse/serialize from user input and a constructed single ton that knows how to figure out wether a games is won?
14:21 mmachenry joined
14:22 wraithm joined
14:23 dsh joined
14:23 jmiven joined
14:23 <ertes> Booba: hangmanStdio abstracts over a parser, a printer and a game
14:24 <ertes> hangmanStdio_ (fromString "Hello World")
14:24 Claudius1aximus joined
14:25 Kundry_Wag_ joined
14:25 n1 joined
14:26 sanett_ joined
14:26 <ertes> and that's just short-hand for: hangmanStdio_ (char 'H' <> char 'e' <> char 'l' <> …)
14:27 xanadu_ joined
14:27 ekinmur_ joined
14:32 jmiven joined
14:32 jathan joined
14:32 sanett joined
14:34 igniting joined
14:36 caadr joined
14:36 halogenandtoast joined
14:37 sphinxo joined
14:37 Luke joined
14:38 maarhart joined
14:39 sanett joined
14:39 carlomagno1 joined
14:40 thunderrd_ joined
14:41 guampa joined
14:42 obadz joined
14:43 sphinxo joined
14:43 wraithm joined
14:44 ChristopherBurg joined
14:44 data_hope joined
14:45 MarioBranco joined
14:48 hackebeilchen joined
14:49 pera joined
14:50 Faucelme joined
14:51 <Booba> ertes: I can't [ut my finger on what Guess contructor second parameter stand for?
14:53 kamog left
14:54 dbmikus joined
14:54 thallada joined
14:56 codesoup joined
14:57 yezariaely joined
14:58 ramzifu joined
14:58 <[k-> from what I can make out of it, it's a lambda that checks if a given input is correct
14:58 raycoll joined
14:58 fosskers joined
14:58 <[k-> and return a new game state?
14:59 infandum joined
14:59 jship joined
14:59 wraithm joined
14:59 psychicist__ joined
15:00 <infandum> Let's say I have a function with "do" syntax. After each binding, I want to print "step 2" then "step 3" etc. How can I have it print when the binding actually finishes? I assume I would have to lose laziness then.
15:00 yezariaely joined
15:01 hackebeilchen1 joined
15:01 hybrid joined
15:01 Kreest__ joined
15:02 Gurkenglas_ joined
15:02 sea_wulf joined
15:02 arante joined
15:02 migimunz joined
15:03 ekinmur joined
15:03 <phz_> hey, imagine I have several packages which I’d like to generate the doc and put all of them in a centralized place (haddock)
15:03 <phz_> how can I do that with stack?
15:03 <phz_> I invoke stack haddock on all projects
15:03 <phz_> then…? :)
15:04 arante left
15:04 <Geekingfrog> phz_: create a stack project with all those projects as dependency and run stack haddock on this project ?
15:04 sanett joined
15:04 carlosdagos joined
15:05 data_hope joined
15:05 ebzzry joined
15:06 mizu_no_oto_work joined
15:06 <brynedwards> To view the docs: cd $(stack path --snapshot-doc-root)
15:06 marsam joined
15:12 thimoteus joined
15:12 jmelesky joined
15:12 sphinxo joined
15:13 JagaJaga joined
15:14 vlatkoB joined
15:15 <cocreature> infandum: just insert a print statement on the next line?
15:15 anemecek joined
15:16 fendor joined
15:16 patbecich joined
15:16 XMunkki joined
15:16 tjt joined
15:17 <bjs> infandum: do you have code that isn't working that you tried?
15:17 fendor joined
15:20 peterbecich joined
15:22 <phz_> Geekingfrog: brillant :D
15:22 mak` joined
15:25 raichoo joined
15:26 <robertkennedy> Why is the state Monad `a -> (b,a)` vice `a -> (a,b)`?
15:26 <glguy> robertkennedy: It's arbitrary, it works to implement it either way.
15:27 <glguy> and the difference isn't distinguishable to the user of the State type
15:27 alfredo_ joined
15:27 cpennington joined
15:29 Luke joined
15:29 Glooomy joined
15:29 <robertkennedy> Sure, but with the other version you have `fmap = fmap . fmap`, which seems like enough reason to prefer it if there is no other convenience from the actual rep
15:30 <msl09> ghc complains about this type declaration "func :: (b->c) Either a b -> Either a c"
15:30 sanett joined
15:30 <glguy> Yeah, that's handy, but it doesn't really matter since you don't have to implement fmap manually for it
15:31 <rotaerk> msl09, yes, that's a bad type signature
15:31 gnull joined
15:31 <glguy> msl09: You can't apply the type (b->c) to Either
15:31 doomlord joined
15:31 <msl09> aw frigg
15:31 augur joined
15:31 <msl09> I forgot an arrow
15:31 <msl09> sorry guys
15:31 OnkelTem joined
15:32 xtreak joined
15:33 MarioBranco joined
15:33 Rainb joined
15:35 <NickHu> Just wondering, do many people here use halcyon for deployment? I went to look at the tutorial but it's dated two years ago...
15:35 fotonzade joined
15:36 modal joined
15:36 ExpHP joined
15:36 sanett_ joined
15:38 simukis__ joined
15:38 <ExpHP> I require somebody well-versed in magical runes
15:38 <ExpHP> I had a script which looks like this:
15:38 simukis__ joined
15:38 <ExpHP> stack runghc --package=hex Shakefile.hs "$@"
15:38 <ExpHP> ...and now I want it to have stack traces
15:39 marsam joined
15:39 maarhart joined
15:39 <ExpHP> I think my furthest attempt so far involves two scripts;
15:40 <ExpHP> stack exec --package=hex -- runghc -f the-other-script Shakefile.hs -- "$@"
15:40 <ExpHP> where "the-other-script" is: ghc -prof -with-rtsopts=-xc "$@"
15:41 <ExpHP> but this complains about hex being a hidden package, as if I weren't using stack exec
15:41 kosorith joined
15:41 <ExpHP> _/o\_
15:41 Lord_of_Life joined
15:42 <ExpHP> (pretty much any layer I remove from that script sandwhich results in the rts opts going to the wrong thing)
15:42 dsub joined
15:44 <Reisen> I'm trying to derive JSON on an associated data family, but I get template haskell errors: deriveJSON ''(Foo X)
15:44 <Reisen> Is there a trick to work around this?
15:44 <Reisen> Seems it expects a name but the space in the data family screws with this
15:45 yezariaely joined
15:45 <glguy> Reisen: Try using deriveJSON on the data constructor for your data family instance
15:46 trism joined
15:46 MitchellSalad joined
15:46 boombanana joined
15:46 serendependy joined
15:46 <Reisen> glguy there's several, will it get me something equivelent just doing deriveJSON ''XA; deriveJSON ''XB?
15:47 <glguy> I don't know. The documentation says "Generates a ToJSON instance declaration for the given data type or data family instance constructor."
15:47 <infandum> cocreature: That works? I get things at wrong times though. For instance, it might print "step 2" and "step 3" even though the process inbetween did not finish. I would need to create an example though.
15:47 <Reisen> glguy, I see, let me try it out
15:47 ragepandemic joined
15:48 <cocreature> infandum: it depends on what you mean by “finished”. you’re probably right that an example would help at this point
15:49 phaji joined
15:50 <Reisen> glguy that worked, that is insanely unintuitive though, but nice to have a solution
15:51 jao joined
15:51 <glguy> The data constructors are the only names that uniquely identify the particular data family instance, so I'd say it makes a lot of sense to use them for that. I'm glad the docs were right
15:52 mmachenry joined
15:52 <Reisen> It makes sense why it needs to work that way, It's just a bit unclear looking at a piece of source code that says "deriveJson 'User" and expect it to derive JSON for the entire data family for a set of user types
15:53 <Reisen> data X = X {..} deriveJSON 'X is OK, data X = Fst | Snd | Third deriveJSON 'Fst, less obvious
15:57 eschnett joined
15:58 splanch joined
15:58 Boomerang joined
15:59 funkshun joined
16:00 <infandum> cocreature: Okay nevermind, I just didn't time the functions correctly.
16:01 dylukes joined
16:01 conal joined
16:02 mmachenry joined
16:03 zar joined
16:03 MindlessDrone joined
16:03 takle joined
16:05 Yuras joined
16:06 laserpants joined
16:08 robotroll joined
16:08 insitu joined
16:11 dpren joined
16:11 Yuras joined
16:12 Sonolin joined
16:12 mariano joined
16:13 ChaiTRex joined
16:13 lhcrkd joined
16:13 Wizek_ joined
16:14 mattyw joined
16:16 dfeuer joined
16:16 <Geekingfrog> Is there a lifted version of Data.Conduit.BracketP the same way there is a lifted version of bracket?
16:17 patbecich joined
16:17 <Faucelme> A DSL-related doubt. Are "tagless interpreters" the same thing as "intrinsic encodings", described here: http://okmij.org/ftp/formalizations/#intrinsic
16:18 t7 joined
16:19 <Faucelme> also here: https://people.mpi-sws.org/~gil/publications/typedsyntaxfull.pdf
16:19 wraithm joined
16:19 Dmas joined
16:21 peterbecich joined
16:23 raycoll joined
16:24 <ExpHP> So after a 30 minute reinstall of aeson with profiling enabled, here's my beautiful stack trace:
16:24 <ExpHP> ^C^CShakefile: out of memory
16:24 cpup joined
16:25 <cocreature> ExpHP: beautiful! you should print and frame this!
16:26 ragepandemic joined
16:27 haskellearner joined
16:28 Rodya_ joined
16:28 <kadoban> ExpHP: hah
16:28 mda1 joined
16:28 splanch joined
16:28 Rodya__ joined
16:29 dj1 joined
16:30 dj1 left
16:30 <NickHu> How do you pass environment variables to stack exec?
16:30 sypwex joined
16:31 <ExpHP> cocreature: http://imgur.com/a/Eavlg
16:31 phyrex1an joined
16:31 JagaJaga joined
16:32 agjacome joined
16:36 pera joined
16:36 Denthir joined
16:36 simendsjo joined
16:36 mizu_no_oto_work joined
16:37 <robertkennedy> > mapM (\n -> [n..n+2]) [1..3]
16:37 <lambdabot> [[1,2,3],[1,2,4],[1,2,5],[1,3,3],[1,3,4],[1,3,5],[1,4,3],[1,4,4],[1,4,5],[2,...
16:37 <robertkennedy> What do those represent?
16:37 iomonad joined
16:38 <robertkennedy> Oh, it's like each value for 1 with each value for 2 with each for 3. Got it
16:42 ramzifu joined
16:44 Jacoby6000__ joined
16:47 umib0zu joined
16:49 ted898_ joined
16:49 tomboy64 joined
16:49 chlong joined
16:49 dmwit_ joined
16:50 ortmage joined
16:51 dylukes joined
16:52 ted898_ left
16:52 sypwex joined
16:54 Micamo joined
16:54 KarboniteKream joined
16:55 splanch joined
16:56 Itkovian joined
16:58 sleffy joined
16:59 Denthir joined
16:59 MarioBranco joined
16:59 connrs joined
17:00 Salih joined
17:01 t0by joined
17:03 ClaudiusMaximus joined
17:04 fendor joined
17:05 carlosdagos joined
17:06 burtons joined
17:07 Berra joined
17:09 peterbecich joined
17:09 wraithm joined
17:09 castlelore joined
17:10 KarboniteKream joined
17:11 Tre joined
17:12 Luke joined
17:12 mmachenry joined
17:12 <Tre> Hey all
17:13 <mmachenry> Hi
17:13 <Tre> how are you?
17:13 <mmachenry> Good you?
17:13 <Tre> Good thanks :P
17:13 <Tre> Just getting into Irc
17:14 <mmachenry> Welcome. Are you already into Haskell?
17:14 <Tre> Just started getting into that aswell
17:14 <Tre> :P
17:15 <mmachenry> Enjoy!
17:15 <Tre> Thanks :P
17:15 al-damiri joined
17:16 yellowj joined
17:16 customminer joined
17:18 thallada joined
17:19 Swizec joined
17:19 sypwex1 joined
17:20 tim joined
17:21 patbecich joined
17:23 <infandum> cocreature: NO! I was right! It
17:23 <infandum> It's the laziness issue I think: 'x = sum [1..1000000 (big number)]'
17:23 <infandum> 'do { print "hi"; y <- return (x + 3); print "man"; return y }'
17:24 <infandum> That will print "hi" and "man" even though x was not evaluated
17:24 <infandum> so y would not be evaluated and thus it looks like return y takes a long time but in reality x is what takes a long time.
17:25 ivanacostarubio joined
17:26 jaspervdj joined
17:26 dsantiag_ joined
17:27 simukis__ joined
17:28 exferenceBot joined
17:29 <glguy> That's right 'y <- return (x + 3)' just binds the unevaluated expression 'x + 3' to the name 'y'
17:29 <infandum> I understand now what the problem is, but now I don't know how to fix it. Is there a way to tell the user what "step" in a do function the program is at?
17:29 <cocreature> infandum: well that’s how lazyness works. if you want to force the evaluation you can do so using "evaluate" and maybe some deepseq
17:29 peterbecich joined
17:29 <infandum> glguy: Yeah, that's now my issue
17:29 <Squarism> anyone got some recomendation if you just want simple variable text-file-templating
17:29 <infandum> cocreature: I'm unsure about that though, because I don't know if it's worth sacrificing performance just to let the user know the current step.
17:30 <infandum> (or memory)
17:30 <cocreature> infandum: that’s probably a decision you’ll have to make for yourself :)
17:30 yogsotot_ joined
17:30 <infandum> :(
17:31 obadz joined
17:31 <ExpHP> x_x okay, I've stuck traces literally everywhere I can in my program and I still can't figure out where it's getting stuck in a loop
17:31 <infandum> cocreature: Then how do programs like System.ProgressBar work? Would they just print out the entire bar at the end? It must have a use case I'm missing.
17:32 <cocreature> infandum: IO will be executed immediately (unless you play dirty tricks) so you can just call "incProgress" somewhere in your program and the progressbar will update
17:33 <infandum> cocreature: Ah, ok. I have that to test but it hasn't reached that point yet. I guess I'll need another location for it. Will progress bar slow down the program significantly?
17:34 <cocreature> infandum: that depends on way too many factors too answer that question generally
17:34 <cocreature> how often do you update it? what kind of calculations does your program perform? …
17:34 osa1 joined
17:35 KarboniteKream joined
17:35 replay joined
17:35 <cocreature> in most cases I doubt it will significantly slow down your program but if you update the progressbar too often things will slow down
17:35 <MarcelineVQ> ExpHP: is it on github?
17:36 <infandum> ah. It would print on each increment even though the rounded percentage is the same?
17:36 WhiskyRyan joined
17:37 <cocreature> dunno, I haven’t looked at the implementation
17:37 <ExpHP> MarcelineVQ not currently
17:38 <ExpHP> I could throw something up but it'd probably take too much effort for others to get it running :P
17:38 <ExpHP> Hmmmm though I guess the solution to that is the same solution that would help debug it: Minimize it
17:38 <MarcelineVQ> ah alrighty, did you want help? because the middle ground is showing code :>
17:39 <infandum> cocreature: OK, thanks for your help!
17:39 eacamero_ joined
17:39 data_hope joined
17:40 tomphp joined
17:40 <ExpHP> I guess this is like walking into the DMV without one's diver's license
17:40 <MarcelineVQ> people respond best to a question, "Can anyone tell me why my program loops when I do <the thing that loops>? Here's the runnable code." will get you pretty quick answers around here
17:40 Rainb joined
17:40 <johnw> ExpHP: :)
17:40 <Disavowed> Morning all. Tackling 99 Haskell Problems and was wondering: does anyone know of a repo somewhere that has unit tests for all of them? If not, I'll build it myself, but I thought I'd save the work if I could!
17:40 <ExpHP> Problem is it's a script that shells out to three half dozen python and bash scripts
17:41 <ExpHP> I rewrote it in haskell because I couldn't stand bash any more :)
17:41 <frontendloader> Disavowed: think what you're looking for there is integration tests
17:41 <ExpHP> aye aye aye guess I'll have to figure something out
17:41 mariano_ joined
17:41 <MarcelineVQ> ExpHP: Alrighty then minimizing it like you mentioned sounds like a great starting point
17:41 <frontendloader> all you wanna test is the input/output of a compiled program right?
17:42 afldcr joined
17:43 certainty joined
17:45 cmsmcq joined
17:48 <ExpHP> actually I guess I was hoping for the magic command that tells me where all the hot lines of code are so I can see where it's spinning
17:48 davama joined
17:48 Claudius1aximus joined
17:48 davama left
17:48 sypwex joined
17:49 <ExpHP> or I guess, "hot CAFs", as it were
17:49 tangled_z joined
17:50 ortmage joined
17:51 peterbecich joined
17:53 tangled_z joined
17:53 Rodya_ joined
17:53 psniper joined
17:54 <ExpHP> hm yeah as I feared, the Module.prof file is only written when the program finishes, since it's a summary
17:54 baldrick1 joined
17:55 inad922 joined
17:55 tangled_z joined
17:56 codep joined
17:56 Lord_of_Life joined
17:57 dylukes joined
17:57 simendsj` joined
17:57 Lord_of_Life joined
17:58 <Sornaensis> what is the best function
17:58 aarvar joined
17:58 tomphp joined
17:59 <Gurkenglas_> Is there a neater way to write "\x m -> state $ \s -> fromMaybe (x, s) $ runState m s"?
17:59 funkshun joined
17:59 balor joined
17:59 <ExpHP> undefined; it'll give you anything, and ask for nothing in return (yet it will take what you give it!)
17:59 carlosdagos joined
18:00 <Squarism> CAnt i just load my "lib" in ghci? It keeps asking for executable?
18:00 m1dnight_ joined
18:00 <Gurkenglas_> absurd; it'll give you anything without even halting, provided you can produce a value from the empty set
18:00 <Gurkenglas_> *hanging
18:00 <mauke> Sornaensis: fmap fix pure
18:00 <ExpHP> ah yes that's a good one. Gotta love absurd for being total
18:01 vydd joined
18:02 robertkennedy joined
18:02 <t7> @hoogle Data.Set.Set (Data.Set.Set a) -> Data.Set.Set a
18:02 <lambdabot> Data.Set splitRoot :: Set a -> [Set a]
18:02 <lambdabot> Data.Set.Internal splitRoot :: Set a -> [Set a]
18:02 <lambdabot> Data.Set.Monad singleton :: Ord a => a -> Set a
18:02 <Sornaensis> mauke: id?
18:02 <t7> how is this not a function
18:03 <lep-delete> :t mconcat
18:03 <lambdabot> Monoid a => [a] -> a
18:03 twanvl joined
18:03 <t7> tfw haskell prelude is not generic enough
18:03 <lep-delete> :t toList
18:03 <lambdabot> error:
18:04 <lambdabot> Ambiguous occurrence ‘toList’
18:04 <lambdabot> It could refer to either ‘F.toList’,
18:04 <lep-delete> :t Data.Foldable.toList
18:04 <lambdabot> Foldable t => t a -> [a]
18:04 Sonolin joined
18:04 carlosda1 joined
18:04 <t7> my code is already full of toList and fromList
18:04 <t7> disgusting
18:04 edsko joined
18:04 <lep-delete> :t join
18:05 <lambdabot> Monad m => m (m a) -> m a
18:05 <t7> is Set a monad
18:05 <t7> i did look for Set.join :P
18:05 <lep-delete> not in haskell
18:05 <mauke> no
18:05 <t7> wrong location
18:05 <t7> ah bummer
18:05 <lep-delete> :hoogle IMonad
18:05 wraithm joined
18:06 tomphp joined
18:07 <mizu_no_oto_work> t7: note that (Set a) is both a Monoid (if a is Ord) and Foldable
18:07 <mizu_no_oto_work> :t fold
18:07 <lambdabot> (Monoid m, Foldable t) => t m -> m
18:07 <t7> huh
18:07 <lep-delete> there it is
18:07 <t7> awesome
18:08 <mizu_no_oto_work> Hoogle is a bit unfortunate in that it doesn't track down applicable typeclass functions.
18:09 <Gurkenglas_> Doesn't return any type signatures more general than the one asked for either
18:09 <mizu_no_oto_work> t7: Set is a monoid under union, if that's what you want
18:10 <mizu_no_oto_work> So that's the union of every set in there
18:10 <mauke> @hoogle Int -> String
18:10 <lambdabot> System.Console.ANSI cursorUpCode :: Int -> String
18:10 <lambdabot> System.Console.ANSI cursorDownCode :: Int -> String
18:10 <lambdabot> System.Console.ANSI cursorForwardCode :: Int -> String
18:10 <t7> mizu_no_oto_work: thats exactly what i want
18:11 <cocreature> wow that’s a really bad hoogle response
18:12 ertesx joined
18:13 <mizu_no_oto_work> t7: you could use newtypes to make a monoid instance like 'FinitelyEnumerable a => Monoid (SetIntersection a)', but I don't think that's on hackage anywhere
18:13 <mizu_no_oto_work> Also, it's not the most useful monoid
18:13 <t7> i will make a github pull request on the ghc mirror
18:13 brynedwards joined
18:13 <mizu_no_oto_work> since you really don't want to make a set of every Int or Double
18:13 <mizu_no_oto_work> but it might sometimes be useful
18:15 tangled_z joined
18:16 <mizu_no_oto_work> You'd want to be dealing with types with only a few inhabitants, like an enum of some sort or maybe a Word8.
18:16 <t7> why
18:16 <mizu_no_oto_work> Since the identity for intersection is the set with every value of that type
18:17 <t7> i though we were doing union
18:17 <mizu_no_oto_work> That's why the standard library has Set as a monoid under union, not intersection
18:17 Cassiopaya joined
18:17 <t7> ah
18:17 <t7> gotya
18:17 <mizu_no_oto_work> But you could write a library for the set intersection monoid
18:17 balor joined
18:17 <Gurkenglas_> Sounds like it should be a semigroup instead
18:18 <mizu_no_oto_work> The semigroup is much more useful, yeah.
18:18 fractalsea joined
18:18 tomphp joined
18:18 <mizu_no_oto_work> The intersection monoid is also probably not what you want if you're folding, either.
18:18 tangled_z joined
18:19 <mizu_no_oto_work> If you have a non-empty set of sets, you'd get everything that's in all of them. If you have no sets, you have every element, ever
18:19 <Gurkenglas_> You could get around the finite-enumerability-restriction by giving the set an extra constructor to stand for the full set, but that's just the general construction of a monoid from a semigroup
18:19 <Gurkenglas_> -giving the set +giving Set
18:19 fnurglewitz joined
18:22 <EvanR> a set with every value of that type
18:22 iblizmuda joined
18:23 connrs joined
18:23 <EvanR> this only makes sense for certain types
18:23 patbecich joined
18:23 <Sornaensis> :t on
18:23 <lambdabot> (b -> b -> c) -> (a -> b) -> a -> a -> c
18:25 <EvanR> cantor, etc called that a totality
18:26 snowalpaca joined
18:27 peterbecich joined
18:28 plutoniix joined
18:29 Kreest__ joined
18:30 mada joined
18:30 ompaul joined
18:31 wing joined
18:32 Denthir joined
18:32 wraithm_ joined
18:33 peterbec` joined
18:33 psychici1t__ joined
18:33 balor joined
18:34 Detrumi joined
18:34 sepp2k joined
18:34 meoblast001 joined
18:35 araujo joined
18:35 marsam joined
18:36 robkennedy joined
18:37 <ExpHP> IT'S ALIVE!
18:37 <t7> im kinda into unit testing haskell now
18:37 <t7> its my thing
18:38 <ExpHP> on my machine, haskell is calling python and bash calling c++ all in one big great code mess
18:38 <ExpHP> and it works
18:38 <ExpHP> it is doing the physics
18:39 supersimmetria joined
18:39 <ExpHP> ...uh oh
18:39 <supersimmetria> hi, guys
18:39 <supersimmetria> is 'A Gentle Introduction to Haskell, Version 98' still relevant?
18:39 <ExpHP> scratch that, it *was* doing the physics
18:40 <ertes> supersimmetria: hardly
18:40 orbifx joined
18:40 <supersimmetria> ertes, are you ironic/sarcastic?
18:40 roconnor joined
18:41 Rainb joined
18:41 <ertes> supersimmetria: no, haskell has evolved since that one was written, and also it's not "gentle" in the sense one might think
18:41 Noldorin joined
18:41 cyborg-one joined
18:41 <supersimmetria> ertes, what is the best book to learn haskell if you dont know functional programming at all?
18:42 mansa joined
18:42 <supersimmetria> i know programming
18:42 <ExpHP> this is where I more or less started: http://learnyouahaskell.com/introduction
18:43 <supersimmetria> ExpHP, and when you needed more info where did you look?
18:43 <MarcelineVQ> supersimmetria: My own response for that would be http://haskellbook.com/ & irc
18:43 <ExpHP> supersimmetria: the wiki
18:43 <ertes> supersimmetria: that's a good question
18:44 <ExpHP> there are some pages on the wiki that do leave "excercises to the reader"
18:44 <ertes> supersimmetria: so far the only book i might like i haven't actually read myself, so this is a blind suggestion: http://www.cs.nott.ac.uk/~pszgmh/pih.html
18:44 <ExpHP> :)
18:44 Owatch joined
18:44 <Owatch> Hello.
18:44 <ExpHP> howdy
18:44 <ertes> supersimmetria: it has good reviews from people i respect
18:45 Darwin226 joined
18:45 <supersimmetria> i dont wanna learn solely haskell, i wanna get a good grasp of functional programming too
18:45 <Darwin226> So, an unboxed vector of pairs is implemented as a pair of vectors. Is there a way to get the sequential behavior where elements are just put one after another?
18:45 ChaiTRex joined
18:45 <Darwin226> this seems better for the cache
18:45 <ertes> supersimmetria: the way you do FP actually depends a lot on the language… FP is more a set of related techniques based on functions
18:46 <ertes> supersimmetria: for example in scheme you wouldn't start by constructing an infinite data structure and then transforming it
18:46 <ExpHP> supersimmetria: actually, I came in having learned a lot of functional techniques alrady from imperative languages
18:47 <ExpHP> most modern languages now have lambdas and etc
18:47 coltfred joined
18:47 <ertes> yes, but none of them really support FP
18:47 <ertes> it's not a matter of supporting lambdas
18:48 snowalpaca joined
18:48 <ExpHP> to me it's kind of a fuzzy distinction
18:48 <greymalkin> ertes: I disagree, FP is a programmer feature as much as a language feature. Any language which can support functions (or something equivalent) as first-class citizens can be used as FP.
18:48 <ExpHP> rust has a lot in common with haskell despite being very clearly not a functional language
18:48 latro`a joined
18:49 <greymalkin> Myself, I didn't grok monads until I found myself accidentally writing one in Java to solve a problem that I was having with (what I thought of then as) a "pipeline problem"
18:49 <ertes> greymalkin: JS has that, right? try doing serious FP in JS and not bang your head against the table
18:49 <ertes> things like syntax matter
18:50 <ExpHP> EmcaScript 6 is doing quite a lot to help make FP in JS more comfortable
18:50 <t7> ertes: it has Object.assign
18:50 <t7> which is better record updating than haskell
18:50 <greymalkin> ertes: Yes, there are features to languages which make FP simpler, less verbose, more complete, etc. But building an understanding of FP with a traditionally imperative language is not impossible.
18:50 <ExpHP> There's some nasty corners where oh, suddenly you need parentheses here or there due to some grammatical ambiguity; but it's not the worst thing ever
18:51 <supersimmetria> do you code only in haskell?
18:51 <Clint> i wish
18:51 <Sonolin> yea modern JS is actually pretty nice, at least compared to other modern imperative languages
18:51 <ertes> t7: so?
18:52 <t7> so nerrr
18:52 <ertes> t7: i don't care what *imperative* features JS has ;)
18:52 <greymalkin> I would rather never program in anything but haskell -- but that's more because the language spoils you by its brevity and expressiveness
18:52 <rotaerk> Sonolin, meh; no type system -> garbage
18:52 detrumi joined
18:52 mariano_ joined
18:52 <Sonolin> true, that is a definite flaw
18:52 <ExpHP> I mostly program in python, actually
18:52 <t7> ertes: Object.assign is immutable, and an expression :|
18:52 <rotaerk> of the mainstream languages, I generally prefer C#
18:52 balor joined
18:52 <t7> nothing imperative about that
18:52 <Sonolin> I suppose I was mostly thinking of other dynamic languages
18:52 <maerwald> greymalkin: most people say that because they're working on their own codebase only. That quickly changes once you're working with otuer haskellers codebase, because expressiveness comes with a price
18:52 <ExpHP> (this is because I've been using python for long enough to know all its warts)
18:52 <ertes> t7: oh, well… in that case my response is lenses =)
18:53 Luke joined
18:53 <t7> ertes: lenses are too hard without type holes
18:53 <ertes> t7: huh?
18:53 <ertes> what do you mean?
18:53 <t7> like agda
18:53 <cocreature> lenses also don’t easily allow for updating multiple fields at once
18:53 wing joined
18:54 <ertes> cocreature: Lens' X (Y, Z)
18:54 <cocreature> t7: we have those in Haskell!
18:54 govg joined
18:54 <greymalkin> maerwald: Every time you grab something from hackage/stackage you're working with someone else's code. I've found that the libraries I end up using in haskell are best documented by the language itself, rather than the actual documentation. But that may just be me.
18:54 <wing> hi everyone, i'm looking for gui expert for small project, anyone intersted?
18:54 <ertes> cocreature: or, when applicable: Traversal' X Y
18:54 <cocreature> ertes: yeah but you can’t construct that from two separate lenses in general
18:54 <t7> cocreature: not with auto solve etc :D
18:54 <maerwald> greymalkin: I strongly disagree on that
18:55 <ertes> cocreature: i've never tried, but are you sure? i bet at least some fairly generic special cases are well possible
18:55 <maerwald> greymalkin: and no, you're just working with API, not with implementation details
18:55 Yuras joined
18:55 <cocreature> ertes: the problem is that they can overlap and in that case the resulting lens would violate the laws.
18:55 <maerwald> I like to write haskell, I don't like to read it though, because everyone does things differently, pretty much
18:56 <ertes> cocreature: and if not, i don't mind doing (l1 %~ f) . (l2 &~ g)
18:56 <ertes> cocreature: true
18:56 <cocreature> ertes: oh sure in most cases it’s not a problem, but if you are updating 5 fields or more it gets annoying
18:56 edsko joined
18:57 <ertes> cocreature: use a state monad with 'zoom'
18:57 <supersimmetria> if i want to understand fully haskell actions, what should i read?
18:57 <greymalkin> maerwald: We'll have to agree to disagree here, I find myself delving into the "how" (implementation) as often as the "why" (api) and coming away with a clearer understanding in haskell than I do in other languages.
18:57 mansa joined
18:57 peterbec` joined
18:57 <ertes> supersimmetria: first learn the basics of the language, then read this: https://www.vex.net/~trebla/haskell/IO.xhtml
18:57 <ExpHP> I'm with maerwald. The cost of highly factored code is that we don't "think" factored
18:57 <greymalkin> Perhaps because of the "easier to reason about" that is touted so often.
18:57 <cocreature> ertes: I still haven’t figured out how to use zoom properly. it doesn’t work with MonadState so I would need to write all my code against a fixed monad and that seems annoying
18:57 <ertes> supersimmetria: (i'm assuming that by "actions" you mean "IO actions")
18:57 <ExpHP> highly factored /abstractions/ are cool, but highly factored implementations take time to digest
18:58 <maerwald> ExpHP: yeah, it's a little bit like maths... the thing a mathematician comes up with in the end is not what one would _intuitively_ come up with. It's forged.
18:58 <greymalkin> I just have to remember that haskell is more information-dense than other languages. It's a breeze to read java, but the verbosity detracts from the overall picture.
18:58 patbecich joined
18:58 <ertes> cocreature: just use narrow runState/runStateT
18:58 <blackdog> right, you know what's going on in the small, but the large is a total mystery
18:58 <cocreature> ertes: I don’t see how that helps?
18:58 <blackdog> (with java)
18:58 <ertes> cocreature: or in fact most likely execStateT
18:58 <supersimmetria> ertes, are there non-IO actions too?
18:58 marsam joined
18:59 <ertes> cocreature: well, you have a value 'x' that you want to update: x' = execState (… zoom …) x
18:59 <ertes> use State only for that purpose
18:59 <ertes> you can use it anywher
18:59 <ertes> anywhere
18:59 <ertes> supersimmetria: yeah
18:59 <cocreature> ertes: well that assumes that I have state that is only local
19:00 <ertes> cocreature: if you have non-local state, use StateT instead of State
19:00 erikd joined
19:00 <supersimmetria> ertes, what should i read to understand non-IO actions too?
19:00 <ertes> cocreature: StateT local (State nonLocal)
19:00 <cocreature> ertes: that’s exactly what I’m talking about. I then want to use MonadState instead of programming against a fixed StateT and then I can’t use zoom
19:00 mmachenry joined
19:00 <maerwald> greymalkin: the density is not the problem, it's the disconnection of intuition and final expression
19:01 <ertes> cocreature: let's say you're writing a ((MonadState nonLocal m) => m ())
19:01 <ertes> just use StateT for the local one there
19:01 sypwex joined
19:01 <ertes> or at least the parts where you want to use 'zoom'
19:01 alx741 joined
19:01 snowalpaca joined
19:01 <cocreature> ertes: what I want is to plug in some "MonadState smallerPartOfNonLocal m => m ()" into that bigger context
19:02 <ertes> cocreature: that requires some plumbing, but it's really minor plumbing
19:02 ystael joined
19:03 <ExpHP> supersimmetria: perhaps you can clarify what you meant by in your original question when you said "haskell actions"
19:03 <cocreature> ertes: I don’t think it is. the last time I looked into it I found several issues in the lens repo stating that it’s not possible to use zoom in a polymorphic context
19:03 <ertes> in any case the answer is to use StateT over MonadState, if you want to zoom and still keep the generality of MonadState
19:03 <cocreature> e.g. https://github.com/ekmett/lens/issues/316
19:03 MP2E joined
19:03 napping joined
19:03 <supersimmetria> ExpHP, i just read that in order to print to screen, haskell action is needed
19:04 <ExpHP> ah
19:04 <supersimmetria> i wanna understand haskell action not io action
19:04 epsilonhalbe joined
19:04 <ExpHP> supersimmetria: I don't think the phrase "haskell action" usually means anything :)
19:05 <supersimmetria> im a noob, have mercy, ExpHP
19:05 <ExpHP> I know :P
19:05 <ertes> cocreature: let me write a short example
19:05 <napping> as much as it means anything, an "IO action" is what you need for printing to the screen
19:05 <ertes> cocreature: i think i'm not communicating what i mean properly =)
19:05 <napping> like, putStrLn "Hello World" :: IO ()
19:05 <cocreature> ertes: or I failing to communicate what my problem is :)
19:05 <ExpHP> supersimmetria: I'm not sure what ertes meant when he said there are "non-IO" actions. Generally speaking, to print to screen in haskell, you need IO
19:05 <supersimmetria> napping, i just want to go as deep as possible
19:06 <napping> anything with a type like IO a can be called an IO action
19:06 <nitrix> cocreature: MAybe you want `use` ?
19:06 <nitrix> cocreature: I remember doing `gets` on MonadState and then `view` from lens and someone told me to look at `use` from lens.
19:06 <napping> Because it's like a description of something to do - you can put it in a datastructure or pass it around for a bit before actually "running" it
19:07 <supersimmetria> im not afraid to go deep, i cant stop at 'io action is needed to print to screen'
19:07 <cocreature> nitrix: I don’t want to read a part of the state. I want to embed something that modifies part of the state in a larger state
19:07 <napping> like, main = do let sayHi = putStrLn "Hello"; sayHi; sayHi
19:07 <nitrix> cocreature: Isn't `state` sufficient for this?
19:07 <napping> will print two lines - as an expression (putStrLn "Hello") doesn't print something and then return ()
19:07 <nitrix> cocreature: state of MonadState ?
19:08 <supersimmetria> napping, how did you learn haskell?
19:08 <cocreature> nitrix: no? that uses the exact same state
19:08 <cocreature> nitrix: are you familiar with what "zoom" gives you?
19:08 cfricke joined
19:08 <nitrix> cocreature: Oh I see what you have in mind.
19:08 <napping> supersimmetria: long ago. I read the "Gentle Introduction to Haskell"
19:08 <cocreature> "zoom" is exactly what I want. the only problem is that it doesn’t work properly inside of a MonadState context
19:08 <nitrix> cocreature: So a zoomed lens on the state which lets you only change that part of the state focused by a lens?
19:08 theelous3 joined
19:08 <supersimmetria> napping, how obsolete is 'gentle introduction'?
19:09 <cocreature> nitrix: exactly
19:09 <napping> also, how "gentle" is it
19:09 <nitrix> cocreature: Yet it'll update the state as a whole? I've done that before; I wonder how I did it.
19:09 <supersimmetria> napping, i care only about how obsolete it is
19:09 osa1 joined
19:09 <napping> but it's not really obsolete, definitely if you want to get deep into the basics of the language
19:09 zcourts joined
19:10 cobreadmonster joined
19:10 <nitrix> cocreature: I think I ended up with a wrapper for `modify . zoom`
19:10 <cocreature> nitrix: yep that’s what I’m after. but the important part is really that I want to do this without forcing some concrete monad transformer stack. otherwise "zoom" works beautifully
19:10 <napping> It won't tell you anything about what libraries are good these days, but it has a lot about the language
19:10 <supersimmetria> napping, is there a more relevant contemporary equivalent to 'gentle introduction'?
19:10 <napping> I don't know
19:10 <nitrix> cocreature: I'm not sure but I think it should be doable to implement an instance for ZoomLike.
19:11 <ExpHP> supersimmetria: #haskell-beginners may also be able to help more.
19:11 <napping> You could take a look at this chapter and see if it's at a useful level https://www.haskell.org/tutorial/io.html
19:11 <supersimmetria> ExpHP, ok, sorry, i forgot about it
19:11 <nitrix> cocreature: Sorry, Zoom type class, LensLike'
19:12 <cocreature> nitrix: the problem is that without a concrete monad transformer stack it is unclear what instance should be applied
19:12 <nitrix> cocreature: https://hackage.haskell.org/package/Chart-1.1/docs/Control-Lens-Zoom.html
19:12 <nitrix> cocreature: class (Zoomed m ~ Zoomed n, MonadState s m, MonadState t n) => Zoom m n s t | m -> s, n -> t, m t -> n, n s -> m where
19:12 <cocreature> nitrix: yeah I’m familiar with that
19:12 splanch joined
19:12 yqt joined
19:13 <nitrix> cocreature: Ah nevermind it's making the stateful computation happen in a MonadState
19:13 <nitrix> My grep failed :P
19:13 <cocreature> there is https://stackoverflow.com/questions/30827838/how-do-i-use-zoom-with-a-monadstate-constraint-of-a-newtype but iirc it didn’t work in my case but I forgot why
19:13 <cocreature> maybe I should give it another shot
19:14 <ertes> cocreature: https://gist.github.com/esoeylemez/22e4a8a11c64cf73fa486b1b07825b7a
19:14 ludat joined
19:14 <nitrix> cocreature: https://github.com/ekmett/lens/issues/316
19:14 <nitrix> ertes: asStateT, that's a meh hack :P
19:15 peterbec` joined
19:15 <ertes> cocreature: of course another option would be to add a Zoom constraint, but i can see why you wouldn't want to do that =)
19:15 <ertes> nitrix: i don't really consider it a hack =)
19:15 tomphp joined
19:16 <nitrix> In the end, you end up with some helper for `modify . zoom`. edward seems to say in the issue on github that the types cannot allow it currently.
19:16 <cocreature> ertes: ah that actually looks pretty reasonable
19:17 <ertes> cocreature: the only caveat is that you might switch to a different StateT flavour (e.g. lazy → strict), but that gives you the opportunity to pick the one that best fits your update action
19:17 <cocreature> yeah that’s not too bad
19:18 <Owatch> Why can't I use a `where` in a `do` statement?
19:19 <Owatch> I.E. in my main I've got my final line: print (if a > 1 then a else 0) where a = ...
19:19 <cocreature> Owatch: because the haskell standard says so :)
19:19 <ertes> Owatch: 'where' always belongs to an equation, so if that do-block is within a function clause you can use it
19:19 <ertes> Owatch: f x = do … where …
19:20 <geekosaur> Owatch, where is part of declaration syntax, because that way it can scope over any guards in the pattern
19:20 <ertes> Owatch: you can use 'let' (without 'in') within 'do' though
19:21 <Owatch> I guess I'll assign the result with let before, then print.
19:22 <ertes> Owatch: i would suggest using 'max', but it's off by one =)
19:22 <ertes> > map (max 0) [-10, -1, 0, 1, 2]
19:23 <lambdabot> [0,0,0,1,2]
19:23 Sgeo joined
19:23 <ertes> … literally
19:23 <Owatch> Uh well. Not exactly in my case.
19:24 sypwex joined
19:24 <Owatch> I need 1 to always be 0.
19:24 albertus1 joined
19:24 <ertes> as in 1 = 0?
19:25 <ertes> > let 1 = 0 in 1 + 1
19:25 <lambdabot> 0
19:25 <rotaerk> lol
19:26 <ExpHP> ... huh, that isn't what ghc says...
19:26 <ExpHP> ghc*i*
19:26 Rainb joined
19:27 epsilonhalbe left
19:27 <wing> why even it compiles
19:27 <ertes> ExpHP: :seti -XAllowIncorrectEquations
19:27 <ExpHP> *snrk*
19:28 <ExpHP> oh you liar!
19:28 <ExpHP> :F
19:28 <* ExpHP> walks away with lambdabot
19:29 <boxscape> shouldn't that result in a non-exhaustive pattern error, because 0 can't be pattern matched to 1? at least without extensions
19:29 <ertes> i messed with lambdabot in /query =)
19:30 <ertes> @let import Prelude hiding (Num(..))
19:30 <lambdabot> Defined.
19:30 <ertes> @let _ + _ = 0
19:30 <lambdabot> Defined.
19:30 <boxscape> I mean just regularly in ghci
19:30 <ExpHP> so the puppet master reveals his strings!
19:30 <ertes> > let 1 = 0 in 1 + 1
19:30 <lambdabot> 0
19:30 <ertes> @undef
19:30 <lambdabot> Undefined.
19:30 BlueRavenGT joined
19:30 <ertes> boxscape: 'let'-bound patterns are irrefutable by default
19:30 <ertes> > let !1 = 0 in ()
19:30 <lambdabot> *Exception: <interactive>:3:5-10: Irrefutable pattern failed for pattern 1
19:30 <boxscape> right, I still need to get used to irrefutable patterns
19:31 <boxscape> > let f ~3 = 4 in f 4 -- I would've expected this to fail as well
19:31 <lambdabot> 4
19:31 <ertes> on the lambdas are strict
19:31 <ertes> > (\1 -> ()) 0
19:31 <lambdabot> *Exception: <interactive>:3:2-9: Non-exhaustive patterns in lambda
19:31 <ertes> *on the other hand
19:31 raycoll joined
19:31 <boxscape> oh, nevermind
19:31 Detrumi joined
19:31 <boxscape> it never tries to match it, obviously
19:32 <ExpHP> > case 1 of 0 -> error "party time"
19:32 <lambdabot> *Exception: <interactive>:(3,1)-(4,22): Non-exhaustive patterns in case
19:32 <ertes> yeah, you don't actually use it
19:32 <ertes> > let f x@(~3) = x `seq` () in f 4
19:32 <lambdabot> ()
19:32 Unhammer joined
19:32 <ertes> huh?
19:33 <orion> https://www.reddit.com/r/haskell/comments/61zs2l/regarding_dsls_what_are_the_recommended_use_cases -- "The initial encoding approach is more flexible and amenable to optimization (e.g. if you want to analyze your Free program and rewrite/optimize it before interpreting it)" Does anyone know how to do this?
19:33 <boxscape> let f ~(x@(3)) = x `seq` () in f 4
19:33 <boxscape> > let f ~(x@(3)) = x `seq` () in f 4
19:33 <ExpHP> > case 1 of ~0 -> error "party time"
19:33 <lambdabot> *Exception: <interactive>:3:5-27: Irrefutable pattern failed for pattern x@(3)
19:33 <orion> Or, does anyone know of any examples of this being done?
19:33 <lambdabot> *Exception: party time
19:33 <boxscape> ertes: you made the inner pattern irrefutable instead of the whole pattern
19:33 takle joined
19:34 <wing> any gui expert here?
19:35 <johnw> wing: I don't think anyone will admit to that without knowing what they're getting into...
19:35 teppic joined
19:36 <ertes> orion: i'll use FreeT vs. FT: usually you would construct as FT and at the very end convert to FreeT, if at all
19:36 dsub joined
19:36 <Owatch> Can I prematurely end a do block? I.E: if (...) then print 0 and return ?
19:36 <ertes> orion: you really only need FreeT, if you want to suspend the interpreter and have a first-class representation of "the rest of the action"
19:36 <ertes> for all other cases you can just interpret FT directly
19:36 snowalpaca joined
19:37 <greymalkin> What is the '~' used for in type signatures?
19:37 <lyxia> Owatch: if (...) then print 0 else continue
19:37 <ertes> Owatch: ending prematurely is an effect
19:37 <ertes> greymalkin: equality constraints
19:38 <ertes> > () :: (Int ~ Int) => ()
19:38 <lambdabot> ()
19:38 <ertes> > () :: (Int ~ Bool) => ()
19:38 <lambdabot> error:
19:38 <lambdabot> Couldn't match type ‘Int’ with ‘Bool’ arising from a use of ‘it’
19:38 uglyfigurine joined
19:38 <boxscape> Owatch: you can start a new do block in the else branch
19:38 <orion> ertes: What if one of my optimizations is, "If you see OperationA followed by OperationB, replace it with OperationC" How exactly do I go about "looking ahead" at arbitrary instructions, and then make changes to the program?
19:38 <wing> johnw: fine, i have f# gui to be ported, i dont know any of haskell gui tools/libraries
19:38 <greymalkin> ertes: thank you. I can google the words from here :)
19:39 mkoenig joined
19:40 splanch_ joined
19:40 <Owatch> boxscape: Thank you!
19:40 Rodya_ joined
19:40 <boxscape> Owatch: (something like this: http://lpaste.net/354027)
19:40 <Owatch> That did what I wanted
19:40 <boxscape> ok, good
19:41 yogsotot_ joined
19:41 <Owatch> IO is confusing with Haskell
19:42 splanch joined
19:42 <ertes> orion: that's not the kind of optimisation that the encoding gives you… rewriting can be done with both FreeT and FT, although the latter is more mind-bending
19:42 douglascorrea joined
19:43 splanch__ joined
19:43 <ertes> Owatch: https://www.vex.net/~trebla/haskell/IO.xhtml
19:44 <Owatch> Thank you
19:45 <ertes> or: why ending prematurely means something entirely different from returning from a procedure in most other languages =)
19:45 bjz joined
19:46 splanch joined
19:47 diegoksp joined
19:47 <EvanR> "deep into the basics"
19:47 <EvanR> only in haskell baby
19:47 <orion> ertes: So if I use FreeT or FT, I can arbitrarily inspect and rewrite programs using whatever rules I want?
19:48 <ertes> orion: yes, but
19:48 <c_wraith> orion, well, not arbitrarily. you only get visibility into them while interpreting them.
19:48 <ertes> orion: the problem with both FreeT and FT is that interpreting causes effects
19:49 <ertes> optimisation requires interpretation
19:49 <ertes> if you don't want that, you need to use Free/F
19:49 <orion> If you're interpreting, doesn't that preclude you from looking "ahead" at future instructions within the interpreter?
19:50 data_hope joined
19:50 <c_wraith> even those require interpreting to inspect.
19:50 <c_wraith> it's the nature of Monad.
19:50 <ertes> orion: you can't look deeper into a (FreeT F M) without causing M effects
19:50 <c_wraith> when effects are chosen at runtime, you need to run it to see what effects it chooses.
19:51 <EvanR> nice chiasmus
19:51 roundhouse joined
19:51 jgertm joined
19:52 ChaiTRex joined
19:53 <orion> Makes sense. So if I want to inspect/rewrite a program without interpreting it, I must use Free/F?
19:53 <ertes> orion: or some other structure
19:53 <ertes> free applicatives and free arrows come to mind
19:53 <hexagoxel> Owatch: if your control flow is more complex and you end up with too many nested ifs, there are abstractions that really give you "early return". But I'd consider those options only when ifs become annoying.
19:54 splanch joined
19:54 <orion> ertes: Do you know of any examples of arbitrarily rewriting a Free/F program?
19:55 theelous3 joined
19:55 <ertes> orion: not really, but it should be fairly straightforward… an optimiser is really just a kind of interpreter
19:55 <ertes> one that returns a new Free expression instead of some final result
19:55 ubsan_ joined
19:56 animated joined
19:56 <hexagoxel> TF = "tagless final" here, right?
19:57 <orion> ertes: It would seem to me that for certain things I want to do, I would need to interpret the entire Free expression -- collecting each operation in to a list along the way -- and then at the very last moment consider the entire List for the transformations I want to apply, then create a new Free expression.
19:57 Kundry_Wag joined
19:57 Jacoby6000__ joined
19:57 <ertes> orion: actually the rewrites you can do are fairly limited… you can't actually descend deeper into an expression
19:58 <ertes> that's inherent in the nature of monads
19:58 <ertes> blame (>>=)
19:58 unK_ joined
19:59 <johnw> orion: another alternative to free arrows is to translate your program into the language of closed cartesian category
19:59 <* hexagoxel> meant to ask FT=finally tagless
20:00 <ertes> hexagoxel: it's more liky F-transformer =)
20:00 <ertes> State → StateT, F → FT
20:00 <johnw> orion: I just happen to be reading this paper as we speak, for a project at work that needs to do static analysis and optimization of effect-bearing programs: http://conal.net/papers/compiling-to-categories
20:00 zero_byte joined
20:01 <johnw> I think FT refers to the church encoded FreeT from the 'free' package
20:01 <ertes> it does
20:01 <hexagoxel> ah, thanks.
20:01 ompaul joined
20:01 conal joined
20:02 <ertes> also i think it's an initial encoding, but i'm not sure… it's definitely an algebraic encoding, not a coalgebraic one
20:02 <johnw> ertes: which one is an initial encoding?
20:02 <ertes> F and FT
20:02 <Owatch> Can you treat a Vector like a list in haskell?
20:02 <Owatch> I.E: (x:xs)
20:03 <johnw> they are both final, ala Church
20:03 <ertes> type List a = forall r. (a -> r -> r) -> r -> r
20:03 <ertes> FT is to FreeT what List is to []
20:03 averroes joined
20:03 <averroes> hi everyone
20:03 <ertes> johnw: do you have an example of an initial encoding? i'm not entirely sure what it means
20:03 <johnw> data Free f a = Pure a | Free (f (Free f a)) is initial
20:04 <averroes> I am run this ghci (*) <$> (Just 5)
20:04 takuan joined
20:04 <averroes> getting an error error: • No instance for (Show (a0 -> a0)) arising from a use of ‘print’
20:04 <ertes> ah, so it's not related to whether it's algebgraic or coalgebraic
20:04 <johnw> newtype Free f a = Free (forall r. (a -> r) -> (f r -> r) -> r) is final
20:04 <boxscape> averroes: what would you expect to get?
20:04 <Cale> Owatch: Well, you can't match it against the pattern (x:xs), that would be a type error. However, you probably could write a function Vector a -> Maybe (a, Vector a)
20:04 <averroes> boxscape: it should return maybe type
20:05 <Cale> (and then pattern match the result of that)
20:05 <averroes> Just (+5)
20:05 <boxscape> averroes: then what does the (*) do in that case?
20:05 <boxscape> oh, or did you mean (*5)?
20:05 <Owatch> Damn, okay. :(
20:05 <johnw> funny, I was just discussing initial vs. final related to Free earlier today on reddit
20:05 <averroes> yes
20:05 <averroes> sorry typo
20:05 <Cale> Owatch: However, doing so will negate nearly all of the performance benefit of using Vector in the first place.
20:06 <boxscape> averroes: that's what it's doing; haskell just doesn't know how to actually print out (*5), because functions don't have instances of Show
20:06 rcat joined
20:06 <Cale> Owatch: If you're going to take something apart as if it's a list, it might as well be a list.
20:06 <boxscape> :t (*) <$> (Just 5)
20:06 <lambdabot> Num a => Maybe (a -> a)
20:06 <Owatch> I need the indexing capability
20:06 <ertes> johnw: well, it's a mundane topic, i guess
20:06 <Owatch> But I also need to remove what I index
20:06 <averroes> weird ghci is complaining
20:06 <Owatch> It's frustrating because I can't find a way to do it.
20:06 <johnw> ertes: https://www.reddit.com/r/haskell/comments/61zs2l/regarding_dsls_what_are_the_recommended_use_cases/
20:07 <ertes> johnw: i saw that one earlier =)
20:07 <boxscape> averroes: if you try :t (*) <$> (Just 5) (with the :t) ghci should not complain
20:07 <Cale> Owatch: well, you can use take and drop
20:07 <averroes> hm I see
20:07 <averroes> (*) <$> (Just 5) <*> (Just 3)
20:07 <Owatch> In another language like C I'd just mark visited indices as visited and move on.
20:07 <johnw> ertes: lots of comments added in the thread that clarifies final vs. initial
20:07 <averroes> returns Just 15 as expected
20:07 <boxscape> > (*) <$> (Just 5) <*> (Just 3)
20:07 <lambdabot> Just 15
20:07 <boxscape> yup
20:07 <Cale> Owatch: What are you actually implementing?
20:08 <averroes> thanks I was freaking out for nothing I guess
20:08 bgamari joined
20:08 <orion> johnw: Thanks. My use case is that I need to perform transformations on already existing programs -- rewrite the expression based on certain rules. You think representing my language as a CCC will allow this?
20:08 <Cale> Owatch: Most of the time if I have to keep track of which graph vertices I've visited, I just accumulate them in a Set.
20:08 <Owatch> I'm trying to implement a program that iterates down a vector. At each index, it visits the index pointed to by the value of that index.
20:08 <averroes> boxscape: Thank you buddy
20:08 <johnw> orion: the basis of Conal's paper is that you can take straight Haskell and convert it to a CCC, and then from there use choice-of-category to apply an interpretation
20:08 <Owatch> I.E: Index 1 has 5 in it, so go to 5.
20:08 <boxscape> you're welcome
20:08 <nitrix> Are the forkIOs inside a forkOS guaranteed to happen on the same OS thread?
20:09 <Owatch> I then continue until I've finished a cycle, and mark each visited index as visited along the way.
20:09 <ertes> nitrix: no
20:09 <johnw> orion: this allows you, for example, to write circuits using regular Haskell functions, rather than requiring a custom circuit-building DSL
20:09 <ertes> nitrix: also forkIO vs. forkOS is really only meaningful in the context of FFI calls
20:09 <Cale> Owatch: Okay, yeah, use a Data.Set to keep track of the indices which you've visited.
20:09 data_hope joined
20:09 <nitrix> ertes: I'm aware. I'm working with SDL which has local thread storage.
20:10 <nitrix> ertes: Is there a way for me to have multiple threads that are guaranteed to all run on the same OS thread?
20:10 <ertes> nitrix: note that the main thread is bound by default, so if forkIO within forkOS would be bound, you could only ever create bound threads
20:10 <nitrix> ertes: Unless you're using GHCi.
20:10 <ertes> nitrix: there is forkOn
20:10 <ertes> but i'm not sure if it does exactly that
20:11 <nitrix> ertes: I found a bug where with GHCi, the main thread isn't bound (checked with isCurrentThreadBound)
20:11 sypwex joined
20:11 <orion> johnw: That's pretty cool, although it doesn't seem all that different from Free, where you keep the program the same and simply provide a different interpreter.
20:12 <ertes> nitrix: even with :main?
20:12 <nitrix> ertes: Mhh, forkOn seems to be about processors capabilities rather than OS threads.
20:12 jdnavarro joined
20:12 <nitrix> ertes: Not sure for :main, checking.
20:12 <Cale> .oO(If people spent half the time just implementing their DSL that they spent on discussing which variant of free monad to program it with, they could just do everything by hand and be done in less time.)
20:13 freth joined
20:13 <geekosaur> sounds like most of programming :p
20:13 <nitrix> ertes: Both `main` and `:main` gives False.
20:13 <ertes> nitrix: i guess if you really want to be safe, you should create a single thread via forkOS and throw actions at it
20:13 <nitrix> ertes: (under GHCi)
20:13 ExpHP joined
20:13 <ertes> nitrix: good to know
20:13 <thoughtpolice> nitrix: GHCi always launches computations in a new thread by default, FWIW, so it very well may not be a bug. You can disable this behavior with -fno-ghci-sandbox (but it will cause things like the GHCi debugger to stop working)
20:14 orphean joined
20:14 <thoughtpolice> I can't recall exactly why this is in place (i.e. the real reason), but there it is.
20:14 <Owatch> Alright, I guess I can use a set. Then check if it's already in it.
20:14 <nitrix> thoughtpolice: Good to know.
20:14 <thoughtpolice> Unless you already turned it off or something, then it's almost definitely a bug.
20:14 <Cale> Owatch: Yep!
20:15 <Cale> Owatch: Given that your set is full of Int values, you may also try IntSet and see if that affects performance, but usually it is quite irrelevant.
20:15 <nitrix> ertes: Yeah I'll run my main in a forkOS thread all the time for extra safety, but the question becomes, am I able to forkIO different things (like polling for event, drawing to screen, etc) for my game, within the same OS thread.
20:15 electrostat joined
20:15 <Cale> (they have the same interface as well, so it's easy to try both)
20:16 <ertes> nitrix: no, different forkOS threads aren't guaranteed to run on the same OS thread
20:16 <ertes> and i don't see a way to do that
20:16 sypwex joined
20:17 anton joined
20:17 Itkovian joined
20:17 <nitrix> ertes: I'm trying to separate window drawing and window even polling into two independent threads so that one doesn't slow donw the other, but SDL mendates me that they need to both have access to thread local storage and happen from the same OS thread.
20:17 <ertes> nitrix: well, OpenGL and SDL don't actually need to run on the same OS thread
20:17 cdg joined
20:17 <ertes> so that would work with separate forkOS threads
20:18 <nitrix> ertes: SDL_WaitEvent has to open in the thread that initialized the video rendering :/
20:18 <nitrix> *happen
20:18 <geekosaur> that requirement sounds contradictory
20:18 <geekosaur> "don't slow each other down" "must have access to the same thread local storage"
20:19 <ertes> nitrix: does SDL's video initialisation actually involve OpenGL?
20:19 <ertes> you may want to ask in #SDL
20:19 <nitrix> ertes: It can.
20:19 <ertes> but yeah, that sounds weird
20:19 <ertes> but i guess most SDL applications don't actually use SDL_WaitEvent
20:19 <Owatch> Hopefully just normal Set should be okay for now
20:20 <nitrix> So people normally poll events between frames being rendered? That just seems odd to me.
20:20 <ertes> nitrix: do you want to stop rendering when no events are occurring?
20:20 <ertes> nitrix: usually you would read all pending events, process them, draw a frame, repeat
20:21 wraithm joined
20:21 snowalpaca joined
20:21 snowalpaca joined
20:21 animated joined
20:21 <nitrix> ertes: So far, my vision is to poll for events in a blocking manner, feed the events to the game engine asynchronously, the game engine does whatever it wants, periodically it has a snapshot of the game to render, which is given to the render thread to render.
20:21 sypwex joined
20:21 <nitrix> ertes: When nothing needs to be rendered, that thread should just wait.
20:22 splanch joined
20:22 <ertes> nitrix: then why don't you just wait on the same thread?
20:23 <nitrix> The problem with my original model is that I can't both have blocking events and render based on an MVar change, if they're both done by the same OS thread.
20:23 <ertes> well, this is really ugly, but one option is to push SDL events onto the queue
20:23 <nitrix> ertes: If I'm blocking on waiting for events, I can't be waiting on the mvar change for the snapshot to render o.<
20:23 <hexagoxel> nitrix: afaik sdl supports opengl context sharing. that might allow you to move a large part of rendering to another thread. not sure though.
20:24 <nitrix> ertes: I was tempted to do that. User events, but our haskell sdl2 lib has poor Raw handling of custom sdl user events.
20:24 peterbec` joined
20:24 <nitrix> It's my fallback option :/
20:25 ner0x652 joined
20:25 <nitrix> ertes: See the issue? I can't even poll for events between frames either, because if there's no render updates, I'll accumulate events and deadlock again.
20:26 <nitrix> It's very, very hard to make a game engine with SDL and haskell that doesn't wastefully poll events or render frames.
20:26 <nitrix> :(
20:26 <ertes> nitrix: there is one more option, which is only slightly dirty: poll for events and process them… when there is no event, wait for an MVar
20:26 neo03 joined
20:27 <nitrix> ertes: What if the MVar doesn't come?
20:27 <ertes> right, forget that
20:27 <nitrix> ertes: If there were no events, the game will have very little reasons to update the render MVar.
20:27 JagaJaga joined
20:27 <ertes> what is the MVar? game state?
20:27 <nitrix> ertes: Yup.
20:28 <nitrix> My Game money is entirely pure, the renderer lives in IO.
20:28 <nitrix> *monad.
20:28 <ertes> hehe
20:28 <EvanR> timing passing is not an event!
20:28 <EvanR> zeno proved it
20:28 <ertes> nitrix: why the MVar? why not just have a stateful game loop with event waiting?
20:30 Berra joined
20:30 <nitrix> ertes: Is it problematic? Because I liked the idea that the game engine can struggle computing something yet can still receive more events. Heck, maybe if the events are not too related, maybe it's possible to have the game engine compute things asynchronously.
20:30 <johnw> orion: Free's utility comes from overloading do-notation, combining with "smart constructors" (i.e., functions that call liftF behind the scenes), and maybe even pattern synonyms to make destruction nicer. But you're still effectively hand-coding what could be done automatically by compiling your functional program directly to sufficiently representative category.
20:30 <Owatch> How can I insert nothing into Data.Set ?
20:30 <Owatch> I want to return after adding some stuff/
20:30 <Owatch> But Data.Set.empty gets added to the set.
20:31 <johnw> Owatch: using mappend instead of insert?
20:31 <Owatch> No using insert.
20:31 <johnw> i meant, maybe *use* mappend instead of insert :)
20:31 <Owatch> Oh.
20:31 <ertes> nitrix: library developers really need to stop using thread-local storage
20:32 <Owatch> Can't see that in the Data.Set page.
20:32 augur joined
20:32 <orion> johnw: I don't understand that statement. What do you mean by "hand-coding"? What process is happening automatically that I would have to do myself?
20:32 <nitrix> ertes: I agree. The bane of every C program :P
20:32 latro`a_ joined
20:32 <ExpHP> @index mappend
20:32 <lambdabot> Data.Monoid, Prelude, System.Console.Terminfo.Base, System.Console.Terminfo
20:32 <ertes> nitrix: i don't even really understand *why* they do it
20:32 <EvanR> how do you even use thread local storage
20:33 sophiag joined
20:33 <EvanR> ive never noticed an api for that
20:33 <johnw> orion: so, with Free you define your algebra, then your type wrapper: type Grammar = Free Myalg, then your constructors for building Grammar terms, etc., etc. This is all machinery you have to write, every time. I'd been thinking about using TH to automate it; but now I'm realizing that if all you want is reification of the program to allow separate analysis and interpretation, perhaps this CCC approach is just the ticket.
20:33 <mizu_no_oto_work> Owatch: mappend is from Monoid
20:33 nick_h joined
20:33 Denthir joined
20:34 <EvanR> johnw: which CCC approach? link?
20:34 <mizu_no_oto_work> Owatch: it's the same as Set.union, though, for the Set instance of Monoid
20:34 carlosda1 joined
20:34 <johnw> EvanR: http://conal.net/papers/compiling-to-categories
20:34 peterbec` joined
20:35 <EvanR> thanks
20:35 <nitrix> ertes: I just had an idea.
20:35 <ertes> "i'm not gonna use SDL" =)
20:35 <mizu_no_oto_work> Owatch: where the idea is that instead of inserting items, you union the set with either a set with a single item or the empty set
20:35 <nitrix> ertes: I can make the game logic, and the game renderer their own thread, than the main thread which is OS bound, will just be dispatching channel messages back and forth between threads.
20:36 <Owatch> Ah, using union and returning Data.Set.empty as a base case will work I think
20:36 <nitrix> ertes: errr no.
20:36 <nitrix> But I'm close.
20:36 <ertes> nitrix: is your game logic pure?
20:36 <nitrix> ertes: IT is.
20:36 <boxscape> is there a difference between mappend and union for Data.Set?
20:36 <boxscape> oh nevermind
20:36 <boxscape> mizu already said no
20:37 <ertes> nitrix: because pure haskell parallelism doesn't interfere with SDL/OpenGL
20:37 b_perez joined
20:37 <ertes> so you wouldn't need to use concurrency
20:37 <nitrix> ertes: What if it isn't pure?
20:37 <nitrix> I doubt it'll stay for for long :S
20:37 <nitrix> pure*
20:37 <ertes> nitrix: then you can still use parallelism =)
20:38 <ertes> or use concurrency locally
20:39 locallycompact joined
20:39 <Cale> boxscape: There should be, but no.
20:39 <boxscape> why should there be?
20:39 <Cale> Because it would be far more useful in practice usually to have the lifting instance Semigroup m => Monoid (Set m)
20:40 <glguy> Cale: Were you thinking of Map?
20:40 <Cale> Also for Map
20:40 <Cale> er, hm
20:40 <boxscape> I see
20:40 <Cale> Actually, no, I'm being silly
20:40 <boxscape> so no it should be the same?
20:40 <Cale> I guess you only get collisions on equal elements anyhow
20:40 <Cale> So it would be a little weird
20:40 <boxscape> yeah
20:41 sypwex joined
20:41 <glguy> There's a question of how the Monoid instance for Map k v should work, should mappend be: union (left-biased union) or unionWith (<>)
20:41 <Cale> In Map's case you don't combine keys in any way, after all
20:41 <Cale> Well, there is technically a question of what to do with colliding keys, but not one that anyone usually cares about :)
20:41 BernhardPosselt joined
20:42 {emptyset} joined
20:43 <BernhardPosselt> how do you formulate this in FP: while(elem = elem.parent) ...
20:44 <rotaerk> in what context? what's elem and parent exactly?
20:44 <Cale> That's not a complete thought, I'm not sure how to translate it
20:44 <BernhardPosselt> its an html element
20:44 <BernhardPosselt> div for instance
20:44 <BernhardPosselt> basically search upwards
20:44 <BernhardPosselt> and stop if you found something
20:44 peterbec` joined
20:44 <ertes> BernhardPosselt: you leave a level of recursion
20:45 <Cale> Well, do you have a parent function? You might produce a list of the parents of the element, and dropWhile some condition
20:45 <c_wraith> BernhardPosselt, in general, you work at a higher level of abstraction than a while loop. so we want to know what the goal is more than the code you'd use to write it.
20:45 <Cale> e.g. using iterate
20:45 ChaiTRex joined
20:45 <Cale> Or just plain recursion
20:45 <Cale> Loops can generally turn into lists in some way
20:45 <BernhardPosselt> right
20:46 Rodya_ joined
20:46 <BernhardPosselt> i also thought of creating the full dom path to the root
20:46 <BernhardPosselt> but that seems expensive (at least in non lazy languages)
20:46 Rodya__ joined
20:47 <BernhardPosselt> maybe making it lazy would make sense
20:47 <BernhardPosselt> like creating an iterator
20:47 <Cale> Well, the whole mechanism of turning loops into lists is very much a lazy-evaluation sort of idiom.
20:48 ExpHP_ joined
20:48 <Cale> If you don't have lazy evaluation, you're more likely just to do some recursion
20:49 napping left
20:49 <BernhardPosselt> if you have tail recursion :D
20:50 <Cale> BernhardPosselt: There's always something you can do to translate an imperative program to a functional one: all the local mutable variables become function parameters, and all the points of control become functions, and you have the result of each function be the function for the next point of control, applied to the new values of the mutable variables.
20:50 <BernhardPosselt> i mean general element depth should not be that high to overflow the stack
20:50 sypwex joined
20:50 <Cale> I'm assuming that whether imperative or functional, your language implementation doesn't suck.
20:50 <BernhardPosselt> its js :D
20:50 <sophiag> hi. i just have some simple question about using data constructors with Maybe. here's my code: http://lpaste.net/354029 . i'm wondering why i can't compile any of the first three functions with my type constructors, so for example "Maybe SList" instead of "Maybe [String]." also why i'm getting the error in the paste when trying to compose them using (<*>)
20:51 <Cale> ah, in that case, you'll need to do some awful trampolining shenanigans if you want to translate
20:51 <BernhardPosselt> right
20:51 <Cale> Might as well just use GHCJS ;)
20:51 <BernhardPosselt> i mean theres TCO but only safari supports it
20:51 <benzrf> sophiag: what type is exprs?
20:51 <geekosaur> sophiag, a data constructor is a value, not a type
20:52 <geekosaur> you can't say Maybe True either
20:52 <geekosaur> you can say Maybe Bool
20:52 <benzrf> whoops
20:52 <BernhardPosselt> Cale: i mean there's also purescript but its tricky for new contributors if you work on it together
20:52 <benzrf> right ,heh
20:52 <sophiag> benzrf: it's type Exp from ASTs returned by haskell-src-exts
20:52 <benzrf> o
20:52 <glguy> sophiag: You seem to be misunderstanding <*>
20:52 <glguy> :t (<*>)
20:52 <lambdabot> Applicative f => f (a -> b) -> f a -> f b
20:52 <glguy> but you have: parseSList a <*> parseCList a
20:53 <glguy> sophiag: parseSList a :: Maybe [String]
20:53 <glguy> sophiag: and so when you're using <*>, then f is Maybe and (a->b) and [String] can't match
20:53 sz0 joined
20:54 <sophiag> glguy: i thought if you're using <*> with Maybe then it only returns the one that returns Just?
20:54 <glguy> no
20:54 <glguy> That's more like <|>
20:54 <glguy> But that's not going to work here either because your types still don't match
20:55 <sophiag> wouldn't i need to make them an applicative instance to use the choice combinator?
20:55 <glguy> parseSList a :: Maybe [String], parseCList a :: Maybe [Char], and parseIList a :: Maybe [Integer]
20:55 mson joined
20:55 <glguy> [String] , [Char] , and [Integer] don't match
20:55 <glguy> You need to use your HList type
20:55 <bjs> sophiag: you need to apply your HList contructors to the values inside the Maybe for that to work
20:55 <glguy> SList <$> parseSList a <|> CList <$> parseCList a <|> ...
20:56 <glguy> which looks like this with explicit parentheses: (SList <$> parseSList a) <|> (CList <$> parseCList a) <|> ...
20:56 <sophiag> can't i use the constructors inside the functions themselves? that's what i was trying to do initially
20:56 <Owatch> I'm not sure why, but haskell is telling me there is a problem with this line: visited :: Integer -> Integer -> Vector v -> Set s -> Set s
20:56 <glguy> Owatch: You can paste your whole code to http://lpaste.net
20:56 <Owatch> It states: "Couldn't match type ‘s’ with ‘Integer’"
20:57 <bjs> Owatch: you'll need to paste the full code :)
20:57 peterbec` joined
20:57 <sophiag> glguy: when you suggested type signatures like "parseSList a :: Maybe [String]" are you also suggesting i use an argument for the function?
20:57 <Owatch> http://lpaste.net/354031
20:57 <Owatch> Got it.
20:57 <Owatch> That is the function. Do you want the whole program?
20:57 <sophiag> *an argument other than the one already
20:57 <glguy> sophiag: I wasn't suggesting anything, I was telling you that those were the types
20:58 <sophiag> well, those functions compile now...just (i think) not the way i want them to
20:58 <glguy> Owatch: If you want to insert an Integer into a set, then the type of the set needs to be 'Set Integer'
20:58 <glguy> and not 'Set s' which suggests that a set of any type at all will do
20:59 <bjs> Owatch: you're inserting j (an Integer) into s (a Set Integer) so your types need to be (Set Integer) to type check
20:59 <geekosaur> Owatch, a type signature is exact, and tells a caller what it can expect. if you advertise "Set s" then you are saying "the caller can pick any s", not "I can pick some s (and here picked Integer)"
21:00 <Owatch> Okay, switched it for both Vector and Set. Cleared the errors!
21:00 <nitrix> What's the main difference between forkIO and async?
21:01 <nitrix> Minor the API, do they operationally work the same?
21:01 <bjs> Owatch: i don't think your Vector was as strict, you could've removed the type signature and used GHCi to see what it infers as the type :)
21:01 <bjs> Owatch: i do that sometimes when I get type errors
21:01 <glguy> nitrix: async is forkIO + some extra stuff to help you get the final result or error at the end
21:01 <nitrix> Okay great :D
21:03 <Owatch> Well, aside from really annoying conversions between Int and Integer all my errors are gone.
21:03 <Owatch> There's no way the program will work though. So I guess now it's debug time. :(
21:03 <Owatch> Thanks for helping me solve those!
21:04 vitalij joined
21:04 sypwex joined
21:06 splanch joined
21:06 <sophiag> thanks everyone, i got that snippet working. i'm still wondering, though, just as a design issue whether it's wise to use fromJust like that since it assumes one of the functions will return a Just type. and i don't have <?> for error handling as in Parsec, right?
21:07 <bjs> Owatch: conversions between Int and Integer are always annoying :)
21:07 mojjo joined
21:08 <BernhardPosselt> Cale: found http://caniuse.com/#search=closest
21:08 <BernhardPosselt> tried various examples, all ugly
21:09 e14 joined
21:09 Jacoby6000 joined
21:09 sypwex joined
21:10 <Cale> BernhardPosselt: What are you doing that requires that?
21:11 <BernhardPosselt> find a form group element that has an input field, starting from the input field
21:11 <Cale> BernhardPosselt: I guess I live in a world where absolutely every DOM node was put there by my program, and I would usually statically know the answer to questions of that sort.
21:11 <BernhardPosselt> right, you could use a framework where your template language handles that thing for you
21:12 <Cale> We use reflex-dom
21:12 <BernhardPosselt> however i dont yet want to go that way since mixing serverside and clientside templating is awkward
21:12 <Owatch> Great, vector.internal.check error.
21:12 <Owatch> Guess I'll have to try this another day.
21:12 <Cale> (and no templating at all)
21:12 BlueRavenGT joined
21:13 Rainb joined
21:13 <BernhardPosselt> looks a bit like elm :)
21:13 <Cale> It's like elm, except with FRP that doesn't suck
21:14 <dmwit_> sophiag: Like what? Generally fromJust is a bit scary, especially if you don't think you've proved that the value will be a Just.
21:14 peterbec` joined
21:14 simukis_ joined
21:14 sypwex joined
21:14 <BernhardPosselt> tbh i think thats the only sensible approach to templating :)
21:14 <BernhardPosselt> make it typesafe
21:15 zar joined
21:15 <BernhardPosselt> prevents XSS entirely
21:15 <Cale> (I have to agree with Elm's decision to move away from their FRP system, because they lacked a lot of the stuff that is needed in order to really make FRP practical for larger applications.)
21:16 <sophiag> dmwit_: i was thinking either something like maybe (the function) that will return 0 if the type is Nothing or something like how parsec allows error messages with <?>
21:16 <Cale> Yeah
21:16 conal joined
21:16 <dmwit> sophiag: I have no context, so your clarification hasn't helped me much.
21:16 <Cale> BernhardPosselt: Not to mention that we never have to worry about JSON being out of sync between our frontend and backend, because the code which defines the types and instances used in communication is shared.
21:17 <BernhardPosselt> its the 90ies re-invented (view models :D)
21:17 <sophiag> dmwit: i'm saying just for error handling (because as you mentioned, you're often not certain one function is guaranteed to return Just)
21:17 <Cale> and we can do stuff like compiling our frontend to native ARM code for running on mobile devices
21:17 sleffy joined
21:17 <Cale> That gives a really nice performance boost :)
21:17 <sophiag> although i'm not sure that even matters now...i'm passing these to a record where one of the fields is Maybe (because it's optional) so it seems the record itself needs to be wrapped in a Maybe as well?
21:18 cdg_ joined
21:19 <Cale> (mind you, right now Android and iOS both require a bit of hackery to get going...)
21:19 zar joined
21:20 <dmwit> sophiag: If you post some concrete code to debate, we might be able to say more. At the moment the only advice I feel qualified to give for the information I've gotten from you is "if you're not sure, don't call fromJust".
21:20 <sophiag> dmwit: ok cool. i'll kill two bird with one stone that way :)
21:21 <Cale> sophiag: and if you *do* ever feel tempted to use fromJust/head and the like, one thing I can recommend is to instead use a pattern matching lambda
21:21 <Cale> > (\(Just x) -> x) Nothing
21:21 <lambdabot> *Exception: <interactive>:3:2-15: Non-exhaustive patterns in lambda
21:21 <Cale> ^^ when it fails, you get a source location
21:21 azahi joined
21:22 <sophiag> Cale: this is for a parser, so that's not the type of error handling i'm talking about :)
21:24 alhariel joined
21:24 <Cale> Yeah, fromJust is for those cases where you expect Nothing to be physically impossible.
21:24 sypwex joined
21:25 <sophiag> dmwit & Cale: here's my code http://lpaste.net/354029
21:26 <sophiag> you can see the function i was referring to commented out, but then i dropped fromJust and had it return the Amb record as Maybe because it wouldn't compile otherwise (although i'm still getting that odd error)
21:26 <Cale> oh!
21:26 <Cale> Well, you're actually going in the other direction there
21:26 <Cale> setTaggedValue wants a Maybe String, but what you have, tag, is a String
21:26 Sonolin joined
21:26 <Cale> So you can just apply Just
21:27 <sophiag> but the function parseString returns Maybe String
21:27 <sophiag> that's what confused me
21:27 <Cale> Well, you're using Maybe as a monad there.
21:27 <sophiag> it still returns something like "Just "foo""
21:27 <Cale> If parseString t is Nothing, then the whole do-block there is Nothing
21:28 <Cale> and if it's Just x, then tag = x
21:28 <sophiag> huh, ok
21:28 <sophiag> i was just thrown because when i run it in ghc it prints "Just "x""
21:28 <sophiag> *ghci
21:28 mstruebing joined
21:28 <Cale> When you run parseString?
21:29 <sophiag> yes
21:29 <Cale> Yes, that's expected.
21:29 <sophiag> but it still doesn't mean it's return a vale of type Maybe?
21:29 <sophiag> just that it's inside the Maybe monad?
21:29 <Cale> It's a value of type Maybe String
21:30 <sophiag> so then why is it saying it's of type [Char] (or String)?!
21:30 <Cale> Well, in a do-block for the monad M
21:30 <Cale> If you have x :: M t
21:30 <Cale> and you write v <- x
21:30 <Cale> then v :: t
21:30 <sophiag> and outside of that the maybe is unwrapped?
21:31 <Cale> and the whole do-block then has type M s for some s (it'll have the same type as the type of the last action in it)
21:31 <Cale> So, here, parseString t :: Maybe String
21:31 <Cale> So tag :: String
21:31 <sophiag> that's super confusing to me. i never would have thought that without you explaining it
21:31 <glguy> For some of this stuff you won't be able to guess how it works, you'll have to read a Haskell tutorial or some kind
21:32 <sophiag> tbh this may have even been in Learn You and i just forgot it
21:32 <Cale> The Monad instance for Maybe is handy when you have a bunch of possibly-failing operations and you want to write something which will fail if any of them fails.
21:32 <Cale> For example...
21:32 <sophiag> anyway...now that i have that sorted out i'm back to wanting parseList to *not* be in side a Maybe monad, meaning the error handling issue is still at hand
21:33 <sophiag> so that version i commented out wrt to what you were discussing earlier
21:33 marsam joined
21:33 Itkovian joined
21:33 <Cale> > let dict = [(0,1), (1,3), (2,2), (3,4)] in do x <- lookup 0 dict; y <- lookup x dict; z <- lookup y dict; return (x,y,z)
21:33 <lambdabot> Just (1,3,4)
21:33 <glguy> There's no "inside Maybe monad", there's just values that have type 'Maybe something'
21:33 <Cale> > let dict = [(0,1), (1,3), (2,2), (3,4)] in do x <- lookup 0 dict; y <- lookup x dict; z <- lookup y dict; w <- lookup z dict; return (x,y,z,w)
21:33 <lambdabot> Nothing
21:34 <robkennedy> Are there existing rewrite rules that make multiple lookups in a do block or an Applicative single pass?
21:34 <Disavowed> frontendloader: Thank you!
21:34 <Cale> sophiag: Well, perhaps you don't want to use do-notation at all.
21:34 <sophiag> Cale: but even tho lamdbabot prints "Just (1,3,4)" if you were to pass that to another function then it would simply be "(1,3,4)." that's what i find confusing
21:35 <Cale> hm?
21:35 <Cale> If we were to pass the whole do-block to another function, it would be equal to Just (1,3,4)
21:35 <sophiag> again, i have parseString returning Maybe String, yet i still need to apply Just to it in parseAmbTagged
21:36 <geekosaur> sophiag, if you are working in the Maybe monad then (>>=) (or do's <-) will process the Maybe
21:36 <Cale> Maybe just use let?
21:36 <Cale> let tag = parseString t in ...
21:36 <Cale> Then if parseString t = Nothing, you'll have tag = Nothing
21:36 <sophiag> geekosaur: that's what i was asking earlier when i said "inside the monad." thanks
21:36 <geekosaur> and yes, to avoid it use let instead
21:36 <Cale> tag <- parseString t doesn't mean "let tag be equal to parseString t"
21:37 halogenandtoast joined
21:38 mstruebing joined
21:38 <Cale> It means "let tag be the result of 'running' parseString t" -- and what it means to run it depends on the monad in question -- in the case of Maybe, it means that if parseString t is Nothing, we give up and the whole do-block is Nothing, and if it's Just x, then the result is x.
21:39 <sophiag> Cale: i get it. i'm wondering now why parseAmb and parseAmbTagged are expecting Amb to be Maybe...also the error handling question i originally asked
21:39 weridfjij joined
21:39 atomi joined
21:40 <Cale> Well, you said they would produce a Maybe result, and you used operations which got you there...
21:41 <Cale> Note, you might have just written parseAmbTagged t v = do val <- parseList v; return (setTaggedValue (parseString t) val)
21:41 <Cale> which would be different from what you wrote there
21:41 yogsotot_ joined
21:41 <Cale> and that would mean the same thing as:
21:42 <Cale> parseAmbTagged t v = case parseList v of Nothing -> Nothing; Just val -> Just (setTaggedValue (parseString t) val)
21:42 <sophiag> well i changed it to "parseAmbeTagged :: Exp -> Exp -> Amb" now that you explained what's going on with parseString
21:42 <Cale> Well, what should it produce when parseList v = Nothing?
21:43 <Cale> If you give it that type, it still needs to produce a result of type Amb in that case.
21:43 <sophiag> i think you're confusing two distinct questions
21:43 <sophiag> the error handling question, again, is about the function specifically marked with a comment
21:43 <sophiag> parseList v cannot equal Nothing...
21:43 <Cale> er
21:43 e14 joined
21:43 <sophiag> it's not in the Maybe monad
21:44 <Cale> I see parseList :: Exp -> Maybe HList
21:44 <Cale> Is that not what you wanted? It seems sensible to me.
21:44 <sophiag> yes, and this is the fourth time i'm politely mentioning that i'm switching back to the version commented out
21:44 <Cale> oh, sorry
21:44 <Cale> okay
21:44 Denthir joined
21:44 <Cale> Well, then you now can't write val <- parseList v
21:44 yellowj joined
21:45 ChaiTRex joined
21:45 <sophiag> why?
21:45 <Cale> Because parseList v isn't an action in any monad, so that doesn't make sense.
21:45 vlatkoB joined
21:45 <athan> Can stack generate haddocks for executables?
21:45 <sophiag> oh, that's why you suggested case instead of do?
21:45 Unhammer joined
21:45 tomboy64 joined
21:45 <Cale> That was why I suggested let instead of do
21:46 <Cale> The case was just translating what the do actually meant.
21:46 <sophiag> two let statements?
21:46 <Cale> let tag = parseString t
21:46 <Cale> val = parseList v
21:46 <sophiag> i'm also still getting an eror with "tag <- Just $ parseSring t"
21:46 <Cale> in setTaggedValue tag val
21:47 <sophiag> ah ok
21:47 <sophiag> except parseString needs to be Just
21:47 <Cale> Well, that should work, and be the same as let tag = parseString t
21:47 Rodya_ joined
21:48 <Cale> However, nobody would tend to write that, in the midst of a do-block, you can use let without the 'in' portion to define things that scope over the remainder of the do-block
21:48 coot joined
21:49 <sophiag> yeah i got rid of the do block
21:49 <Squarism> is there any way to change "CWD" in ghci wo unloading modules. I just wanna mimic "code as if executed from directory X"
21:49 <Cale> sophiag: Seems sensible if you don't want to produce a Maybe result.
21:49 <sophiag> and you're saying since i'm not using a monad comprehension then i no longer need to apply Just to the output of parseString
21:49 <Cale> Squarism: I believe there's something like setCurrentDirectory
21:49 <geekosaur> :!cd
21:49 <geekosaur> er no
21:49 <geekosaur> :cd
21:49 <Cale> oh, right, there's also that
21:49 <Cale> hah
21:49 <geekosaur> :!cd might work on windows though
21:49 <Squarism> :cd unloads all loaded modules
21:50 <* geekosaur> needs to watch those fingermacros, he knows better than that
21:50 <Squarism> and it seems i cant import them again
21:50 <Cale> sophiag: Right, you wouldn't.
21:50 <sophiag> Cale: ok...still wrapping my head around that, but it's been a good learning experience :)
21:51 <geekosaur> "Note: changing directories causes all currently loaded modules to be unloaded. This is because the search path is usually expressed using relative directories, and changing the search path in the middle of a session is not supported."
21:51 <sophiag> so now i'm just left with wondering about fromJust and the Nothing case. i really wish i could just use something like <?> from Parsec to supply an error message
21:51 <geekosaur> you would have to change to absolute search path within ghci
21:51 <Cale> sophiag: You could just case
21:51 <Cale> @src fromJust
21:51 <lambdabot> fromJust Nothing = undefined
21:51 <lambdabot> fromJust (Just x) = x
21:51 <Cale> another way to write that would be
21:52 <Cale> fromJust m = case m of
21:52 <Cale> Nothing -> undefined
21:52 <Cale> Just x -> x
21:52 <nitrix> Do I understand this right that killThread will always be able to stop a thread, unless it is blocked on an MVar or a foreign call?
21:52 data_hope joined
21:52 <sophiag> Cale: you're saying to use the case expression on all those arguments?
21:52 hiratara joined
21:53 <geekosaur> nitrix, there's a hacky way to make it stop when in a foreign call, but you can't rely on it
21:53 <geekosaur> (think about it)
21:53 <sophiag> or just override the regular fromJust i guess?
21:53 secki joined
21:54 <Cale> sophiag: Either way
21:54 <nitrix> geekosaur: Looks like I can avoid it for now, but what's the wacky way?
21:54 obadz joined
21:54 ExpHP_ joined
21:54 <geekosaur> nitrix, https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ffi-chap.html#interruptible-foreign-calls
21:55 <geekosaur> the problem is C doesn't have the concept of critical sections, so there is no guarantee you wouldn't be leaving some library data (including libc, think malloc() etc.) in an inconsistent state
21:55 <nitrix> geekosaur: Gotcha.
21:56 <nitrix> geekosaur: So if it's ever used, it has to be as a force quit mechanism as undefined behavior ensues.
21:56 <geekosaur> yes
21:56 <Cale> nitrix: Another exception to add to that list would be if the thread you're trying to kill is in a non-allocating loop.
21:56 <nitrix> How about the MVar part, can one interrupt a thread blocked on it?
21:56 <Cale> yes
21:57 laserpants joined
21:57 shayan_ joined
21:57 <nitrix> But then I risk other threads being deadlocked on writes, if the one a killed was a reader?
21:57 <nitrix> (I guess the other around amounts to the same problem)
21:58 <nitrix> *way
21:58 <Cale> In fact, if the garbage collector collects the last other instance of the MVar, it will send the exception to kill your thread itself.
21:58 eacamero_ joined
21:58 <nitrix> So if I kill thread A (reader), thread B (writer) will simply die since it's dead locked?
21:59 Koterpillar joined
21:59 <Cale> Yeah, it'll get a "thread blocked indefinitely on MVar" exception.
21:59 <sophiag> Cale: if i overload fromJust then the problem is i have it returning a string as an erorr message in response to Nothing, but need it to be of type Maybe HList -> HList
21:59 <nitrix> Okay. Just being sure. I'll obviously try to do things proper here.
22:00 <Cale> sophiag: Did you want to produce a result of type Either String HList?
22:00 oats joined
22:00 <athan> would anyone here happen to know how to hyperlink haddocks relatively, or with a custom base url? http://stackoverflow.com/questions/43080693/haddock-relative-hyperlinking
22:00 <oats> hello, can I paste 4 lines of code here?
22:00 <Cale> sophiag: Or did you want your whole program to just die immediately with a message?
22:00 <athan> oats: please use lpaste.net :)
22:00 <nitrix> ertes: So far I have the main event thread, a logic thread, a render thread, a network thread and a timer thread.
22:01 acro joined
22:01 <nitrix> ertes: It works all great, no lag, no shenanigans, very "clean" with MVar, TChan and MSampleVar :)
22:01 <sophiag> Cale: not the whole program, but the parse that uses it yes...i'd like it ot just return an error message rathe than creating a useless record
22:01 <oats> in this main function, why does the program wait for input before printing the first line? https://ptpb.pw/0_Jm/haskell
22:01 <Cale> Right, then probably you want the result to have type Either String HList
22:02 <nitrix> ertes: The part to figure out is when the logic thread needs to communicate to the main thread that it needs to quit, but I think I'll hack that by pushing an even in the SDL queue.
22:02 <Cale> oats: Line buffering
22:02 <nitrix> ertes: And pretend the user is closing the window :)
22:02 yogsotot_ joined
22:02 <nitrix> Making progress :] !
22:02 <Cale> oats: You'll need to import System.IO and hFlush stdout after the putStr, because otherwise, line buffering will wait for a complete line before writing to the terminal.
22:03 yogsotot_ joined
22:03 <Cale> You can also turn off line buffering (at the cost of some performance) if this is an inconvenience
22:03 <oats> Cale: gotcha, thanks!
22:03 <Cale> hSetBuffering stdout NoBuffering
22:06 watom- joined
22:07 verement joined
22:08 <sophiag> Cale usine Maybe HList -> Either String HList
22:08 <sophiag> oops...was going to say it now expects different types from the cases. do i need to add constructors?
22:08 oats left
22:09 MarioBranco joined
22:09 skeuomorf joined
22:12 zcourts_ joined
22:12 data_hope joined
22:18 carlosda1 joined
22:19 ramzifu joined
22:22 WhiskyRyan joined
22:23 JagaJaga joined
22:23 SAL9000 joined
22:24 migimunz joined
22:24 obadz joined
22:26 conal joined
22:28 tromp joined
22:28 Jesin joined
22:30 systadmin joined
22:30 <athan> Joke's on me, haddock hyperlinks are already relative u_u
22:31 hiratara joined
22:32 dopey_ joined
22:32 migimunz joined
22:32 troydm joined
22:34 uglyfigurine joined
22:34 splanch joined
22:34 <dopey_> Is there a recommended way of "cleaning up" when a process is being killed? I've got a C file handle as well as some malloc'ed variables that I probably want to free before the process actually dies.
22:35 perrier-jouet joined
22:38 zcourts joined
22:39 Gloomy joined
22:39 shennyg left
22:40 <johnw> dopey_: bracket
22:41 peterbec` joined
22:41 louispan joined
22:41 <johnw> if lexical scoping doesn't work for you, then resourcet or pipes-safe
22:42 <dopey_> taking a look. googling turned up MVar() as an alternative too
22:42 <johnw> MVar won't free a file handle, though
22:44 <dopey_> I figured that I would just call fclose() once the MVar is tripped
22:44 <geekosaur> depends on how it's being killed, actually. if it's a unix signal other than SIGINT then bracket won't help because it doesn't translate to an exception
22:45 <Cale> sophiag: Did you figure it out?
22:46 <sophiag> Cale: i was just about to ask again! i got distracted with something else...so no: http://lpaste.net/354029
22:46 cmsmcq joined
22:46 <geekosaur> (and I have no idea how Windows' TerminateProcess shows up in Haskell)
22:47 <Cale> sophiag: Well, you'll probably want to rename that from fromJust to something else, but all you need to do is apply Left to the error string, and Right to the successful value.
22:47 <dopey_> I assume it would normally be sigint or w/e the signal would be for when a process runs into a code exception (im just running a warp server)
22:47 <geekosaur> code exception would be a haskell exception not a signal
22:48 <geekosaur> but "being killed" normally means from an external source of some kind
22:48 <sophiag> ah ok
22:48 e14 joined
22:48 WhiskyRyan joined
22:48 <dopey_> gotcha, I think I wanna cover both of those scenarios in this case
22:48 <Cale> sophiag: As it happens Either e is also a monad, it's similar to Maybe, but where you get the first error (Left) value which occurs
22:49 <Cale> sophiag: and if none occur, you get Right of the final result
22:49 <sophiag> right. i suppose i could have looked up the constructors
22:49 <Cale> > do x <- Right 3; y <- Right 10; return (x + y) :: Either String Integer
22:49 <lambdabot> Right 13
22:49 <Cale> > do x <- Left "oops!"; y <- Right 10; return (x + y) :: Either String Integer
22:49 <lambdabot> Left "oops!"
22:50 <Cale> Can be useful instead of deeply nested cases.
22:50 <sophiag> although now the function i apply it in isn't matching the return value...do i need to use a constructor there?
22:50 <Cale> What are you getting?
22:51 <sophiag> it expects type HList and is getting Either HList String
22:51 peterbec` joined
22:51 <Cale> It should be Either String HList btw
22:51 <sophiag> it almost seems like i've passed the buck on the whole error handling situation
22:51 <Cale> By convention, Left is always the error
22:51 <sophiag> oh ok. that's good to know
22:51 chenyu joined
22:52 <Cale> Well, you've enriched your error information with a message, whereas before, you had Nothing which just meant "something went wrong"
22:52 eacameron joined
22:52 <sophiag> i could still go that route i suppose
22:53 suls joined
22:53 <sophiag> hmmm...yeah actually i think that makes more sense
22:53 <sophiag> otherwise it just seems like i'm propogating the error through everything and not sure how to eventually handle it
22:54 <sophiag> so now i have Nothing just returning undefined
22:54 WhiskyRyan joined
22:55 <sophiag> welp, before i deal with the more complicated record type i suppose it's time to actually set up IO and have it store the Amb record in a state monad
22:57 dan_f joined
22:58 louispan joined
22:59 afnizarnur joined
23:00 migimunz joined
23:00 sigmundv_ joined
23:01 cdidd joined
23:01 peterbec` joined
23:03 gugah joined
23:09 lambda-11235 joined
23:10 MarioBranco joined
23:10 nomicflux joined
23:11 eacameron joined
23:13 conal joined
23:14 markasoftware joined
23:15 ebzzry joined
23:16 Kundry_Wag joined
23:19 Ferdirand joined
23:20 dylukes joined
23:20 cdidd joined
23:21 peterbec` joined
23:22 zero_byte joined
23:22 ChaiTRex joined
23:22 markus1209 joined
23:22 markus1219 joined
23:22 vaibhavsagar joined
23:25 theDon_ joined
23:25 puregreen joined
23:26 e14 joined
23:27 louispan joined
23:28 nakal joined
23:28 ddere joined
23:30 data_hope joined
23:30 carlosda1 joined
23:32 xochozomatli joined
23:34 Axman6 joined
23:35 hucksy joined
23:36 e14 joined
23:44 MrWoohoo joined
23:50 CMCDragonkai joined
23:51 jmcarthur joined
23:52 migimunz joined
23:52 kappter joined
23:52 marsam joined
23:57 YongJoon joined
23:59 <ExpHP> I am tempted to replace all of my imports of Turtle with the following: https://gist.github.com/ExpHP/16244a04abe9a3810b4172611aeeea29
23:59 <ExpHP> I can't imagine why I feel so strongly about argument order