<    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:00 <davean> And showing you similar, more well defined things
00:00 <sophiag> yeah i get it
00:00 bydo joined
00:00 atk joined
00:00 <sophiag> i would really like to just get something working with the simplest input, frankly
00:01 <sophiag> then build up from there
00:02 <sophiag> davean: i'll either use that function with choice like you suggested or cut it down to one type for starters
00:03 zxtx left
00:03 <davean> mmm
00:04 <davean> I mean, this is why chars have single quotes around them in most languages while strings have double, and numbers none
00:04 <davean> it allows disambiguation
00:04 Welkin joined
00:07 <sophiag> i'm confused how you suggested i write this function with all these other functions in it? parseI, parseS, etc.?
00:07 <davean> oh
00:07 <davean> sorry I failed to define those
00:08 <davean> parseC = char
00:08 <davean> er
00:08 <davean> no
00:08 gugah joined
00:08 <davean> parseC = anyChar
00:08 <sophiag> why don't i just put that inline?
00:08 petervaro joined
00:08 <davean> Oh, because I wasn't looking up the functions
00:08 <davean> I was jsut suggesting what goes in there
00:08 <sophiag> oh ok
00:08 <davean> "some char parser"
00:09 <davean> because how your chars, nums, and string are formated are specific to you
00:09 <davean> I don't know how you represent an Integer
00:09 <davean> I can assume, I just wasn't
00:10 <sophiag> digit
00:10 <davean> probably many1 digit actually?
00:10 <davean> but yah, I just wasn't assuming
00:10 <davean> fill those in as makes sense for your specific case
00:11 <sophiag> using parseList :: String -> HList still doesn't compile tho
00:11 <davean> thats not a type I ever gave you
00:11 <davean> 19:52:58 davean parseList :: Parser String u HList
00:12 fizbin joined
00:12 <davean> parseC :: Parser String u Char
00:12 <davean> parsecS :: Parser String u String
00:12 gugah joined
00:12 <davean> parsecI :: Parser String u Integer
00:12 <sophiag> ok, i tried String -> HList because the one you gave didn't compile either
00:13 <davean> what was the error?
00:13 <sophiag> " parse error (possibly incorrect indentation or mismatched brackets)"
00:14 <davean> paste the program?
00:14 <davean> sounds like a transcription error
00:14 sypwex joined
00:14 <sophiag> http://lpaste.net/353955
00:15 <davean> (CList <$> parseSub (many1 string))?
00:15 <sophiag> yeah you suggested i look it up
00:15 <davean> and yah, it would have to be anyChar for example
00:16 <sophiag> that's not in the docs
00:16 <davean> char parses ONE specific char
00:16 <davean> sure it is
00:16 <davean> https://hackage.haskell.org/package/parsec-3.1.11/docs/Text-Parsec-Char.html
00:16 <davean> anyChar :: Stream s m Char => ParsecT s u m Char
00:16 <davean> string parses the SPECIFIED string
00:16 <davean> so the string you want is many1 anyChar
00:16 <davean> but note theres nothing that will ever terminate that!
00:17 <sophiag> the ending bracket should
00:17 justicefries joined
00:17 <davean> so maybe you want "endBy1 anyChar "char ',' <|> char ']')"
00:17 <davean> as your string
00:17 <davean> but then your strings can't have , or ] in them
00:18 <davean> this is why C strings use \ escaping
00:18 tmtwd joined
00:18 JeanCarloMachado joined
00:18 <davean> and ""s
00:18 fizbin1 joined
00:18 <sophiag> i'm just still trying to get it compile
00:18 <sophiag> the type signature is still not correct
00:19 <davean> also, "many1 digit" will return a string of only digits
00:19 <davean> you can convert that to a num like "read <$> many1 digit"
00:19 <davean> those changes should do it
00:19 <sleffy> Has anyone here tried to use the bound library for a term type which may contain two distinct variable types, and which allows substitution on either one independently?
00:19 <sophiag> still type signature is wrong
00:19 <sophiag> same error
00:20 <davean> paste the error?
00:20 <davean> the full one
00:20 <sophiag> "Amb.hs:24:1: error: …
00:20 <sophiag> parse error (possibly incorrect indentation or mismatched brackets)
00:20 <sophiag> Compilation failed."
00:20 <davean> At least what line?
00:20 <davean> its a syntax error
00:20 <sophiag> the type signature for parseList
00:20 <sophiag> "parseList :: Parser String u HList "
00:20 <davean> No, thats NOT a type error
00:21 <sophiag> that's the line the error is on
00:21 <sophiag> you asked
00:21 <davean> yes
00:21 <davean> "20:19:53 sophiag still type signature is wrong"
00:21 <davean> thats not saying the type signature is wrong
00:21 <davean> parseSub
00:21 <davean> its got one more ( then )
00:21 <davean> parseSub p = (between (char '[') (char ']') (p `sepBy` char ',')
00:21 <davean> you could change it to:
00:21 <davean> parseSub p = between (char '[') (char ']') (p `sepBy` char ',')
00:22 <davean> or add a ) to the end
00:22 <sophiag> oh you know what
00:22 <sophiag> Parsec
00:22 <davean> ?
00:22 <sophiag> not Parser
00:22 <sophiag> that was v2
00:22 Jeanne-Kamikaze joined
00:22 <davean> still, the error you ahve there is pre-type checking
00:22 <davean> Haskell can't actually read the file
00:22 <davean> thats the earliest sort of error you can get
00:23 <davean> back in the 60s we did a lot of work on error handling parsers
00:23 <davean> then we never used it
00:24 marcopullo joined
00:24 fizbin joined
00:26 <Welkin> davean: you personally did the research?
00:26 <davean> Welkin: no?
00:26 <Welkin> who is "we"?
00:26 <davean> the computer science community
00:27 mda1 joined
00:27 sypwex joined
00:30 <davean> sophiag: working?
00:32 Jesin joined
00:32 sypwex joined
00:32 ystael joined
00:33 eacameron joined
00:34 takle joined
00:36 shayan_ joined
00:39 <* geekosaur> remembers watfiv again...
00:39 jao joined
00:40 dawehner joined
00:40 conal joined
00:41 plutoniix joined
00:42 andyhuzhill joined
00:42 <davean> I'm not actually sure how interesting error recovering parsers are in the modern age
00:43 <davean> maybe for interactive editing?
00:43 e14 joined
00:43 gugah joined
00:43 plutoniix joined
00:43 Kundry_Wag joined
00:47 thimoteus joined
00:50 fizbin joined
00:51 kylepotts joined
00:51 sypwex joined
00:53 splanch joined
00:53 eazar001 joined
00:53 Stanley00 joined
00:56 ericsagnes joined
00:57 PennyNeko joined
00:58 takle joined
00:58 systadmin joined
01:01 safe joined
01:02 kirillow joined
01:04 afnizarnur joined
01:04 nwf joined
01:04 carlosdagos joined
01:06 Kundry_Wag joined
01:07 nighty- joined
01:08 theelous3 joined
01:12 data_hope joined
01:15 Supersonic112_ joined
01:15 sypwex joined
01:15 takle joined
01:15 mson joined
01:18 MindlessDrone joined
01:19 <Welkin> ezyang: what do you use for the hand-drawn graphs on your blog? Do you input them using a tablet/touchscreen, or scan them in from paper?
01:20 <Welkin> I've tried scanning from paper before and it's hard to get it to look clean
01:20 sypwex joined
01:20 aglorei joined
01:21 tomboy64 joined
01:22 <ezyang> Welkin: it's a tablet laptop
01:22 <ezyang> X61 :)
01:25 {emptyset} joined
01:25 tom7942 joined
01:26 mvr_ joined
01:26 takle joined
01:27 <ezyang> I am braining. Can someone tell me what is wrong with this code: http://lpaste.net/353964
01:28 Goplat joined
01:30 <lyxia> is there supposed to be something wrong
01:30 <ezyang> when I feed it '9' and "aa9a9\154" I get [2]
01:31 <ezyang> I guess I'll debug trace it to death
01:32 <ezyang> maybe this is a bug in Foundation
01:32 systemfault joined
01:33 <glguy> ezyang: I'd guess breakElem isn't working like you want it to
01:33 ystael joined
01:33 <glguy> or that your string literal somehow isn't working for whatever Str is
01:34 takle joined
01:34 mizu_no_oto joined
01:36 <ezyang> ok yep this is a foundation bug
01:38 FreeBirdLjj joined
01:38 <ezyang> if you breakElem on a string from a breakElem (or perhaps it's uncons) it totally chokes
01:39 sypwex joined
01:39 <ezyang> https://github.com/haskell-foundation/foundation/issues/218
01:41 Kundry_Wag joined
01:42 systadmin joined
01:44 handyc joined
01:46 kylepotts joined
01:47 kirillow_ joined
01:47 louispan joined
01:47 boxscape_ joined
01:48 mmachenry joined
01:51 e14 joined
01:51 brynedwards joined
01:51 systemfault joined
01:52 systemfault joined
01:55 <greymalkin> Whats the `[....| .... <- ...]` syntax about? I can't find a reference for it
01:55 WhiskyRyan joined
01:55 <jle`> list comprehension
01:55 benl23 joined
01:55 takle joined
01:56 <jle`> @google haskell list comprehension
01:56 <lambdabot> https://wiki.haskell.org/List_comprehension
01:56 <glguy> https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11
01:57 takle joined
01:58 <greymalkin> Hmm. that still isn't shedding any light on how to use it in `readsPrec` for me -- thank you jle`
01:58 <jle`> greymalkin: did you have a specific question?
01:59 ericsagn1 joined
02:00 pierrot joined
02:00 <greymalkin> Not really, I'm just trying to make a `Read` instance which is slightly different from the default -- yesod's persistent doesn't seem to export the necessities to manually `derivePersistField` which I need for an enumerated type on which I want to do database comparisons.
02:01 hucksy joined
02:01 <jle`> it is unlikely that list comprehensions would help you with that in a meaningful way; they're mostly just syntactic sugar
02:02 <greymalkin> They're used in the primary examples of implementing readPrec, though (a Tree type); which is why I was banging my head against it.
02:03 <jle`> hm. well if you're trying to mimic other instances, then you can maybe ask about some unclear things in those instances. but you can always just write them out in normal haskell, too
02:03 <jle`> without list comprehensions
02:03 sypwex joined
02:03 <greymalkin> specifically https://www.haskell.org/tutorial/stdclasses.html#sect8.3
02:03 <jle`> instead of writing [ f x | x <- xs ], you can just write 'map f xs'
02:04 aarvar joined
02:04 <jle`> when you bind multiple variables, it acts as a nested loop
02:05 divesh joined
02:05 <jle`> so [ (x, y) | x <- xs, y <- ys ]
02:05 <jle`> would return (x,y) for all x in xs, and all y in ys
02:05 divesh joined
02:06 <jle`> > [ (x,y) | x <- [1,2], y <- ['a','b'] ]
02:06 <lambdabot> [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
02:06 <jle`> it returns every possible combination of bindings
02:06 <boxscape_> [ x | x <- [1..10], odd x ]
02:06 <boxscape_> > [ x | x <- [1..10], odd x ]
02:06 <lambdabot> [1,3,5,7,9]
02:07 <boxscape_> you can add boolean predicates
02:07 erisco joined
02:07 <jle`> and one feature that they're using in that example is pattern matching
02:08 <jle`> > [ x | ('c', x) <- [('c', 1), ('c', 2), ('d', 3), ('c', 9)] ]
02:08 <lambdabot> [1,2,9]
02:08 sypwex joined
02:08 <jle`> this only binds x's for tuples that match the ('c', x) pattern
02:08 <jle`> (if you're familiar with pattern matching)
02:09 manek joined
02:09 <sshine_> > do { ('c', x) <- [('c', 1), ('c', 2), ('d', 3), ('c', 9)]; return x }
02:09 <lambdabot> [1,2,9]
02:09 <sshine_> wow.
02:09 <manek> Hello guys! :) Is it possible to disable automatic datatype promotion in GHC? I just want to get error when I forgot to use ' in front of promoted constructor
02:10 JuanDaugherty joined
02:10 <jle`> i'm guessing you are looking for an answer that doesn't involve {-# NoDataKinds #-}
02:10 <erisco> Prelude.foldr1 is throwing but it isn't my code... why does getting a stack trace look insanely complicated?
02:10 <jle`> manek: can you show an example
02:11 <jle`> of a problematic situation
02:11 <jle`> erisco: maybe try turning off optimizations?
02:11 <greymalkin> jle`: I found my major misunderstanding. The default example uses a constructor which is not textually represented in the string
02:11 <erisco> jle`, you never get a trace in ghci when error executes
02:12 e14 joined
02:12 <erisco> jle`, nor when you compile
02:13 <erisco> you just get the error message
02:13 <manek> jle`: of course. `type family Foo (a :: k) :: *; data A = B; type instance Foo B = Int` I want it to return error
02:13 <erisco> Prelude.foldr1: empty list
02:13 <jle`> heh, yeah, that's not a stack trace
02:13 <erisco> to get a stack trace it seems you have to rebuild all your cabal packages with the -p flag
02:13 <erisco> which is insane
02:14 <manek> jle`: however, I want to be able to tell `Foo 'B = Int`
02:14 <MarcelineVQ> manek: you can put -Wunticked-promoted-constructors -Werror but it'll error on any warning not just that one
02:14 <manek> MarcelineVQ: Ugh :(
02:15 zcourts joined
02:15 <manek> MarcelineVQ: I've heard that GHC will have some day selectiwe -Werror flags
02:15 <manek> then it will be perfect for me, for now I cannot do it ? :(
02:15 <MarcelineVQ> I'm not sure, I really only use -Wall :>
02:15 zcourts joined
02:16 <manek> I'm sure that Werror converts all warnings into errors.
02:16 <manek> currently
02:16 zcourts joined
02:17 <jle`> manek: not sure i follow, are you trying to allow 'type instance Foo B = Int' ?
02:17 <manek> I just spend 30 minuts looking for a bug because GHC ticked automatically a consturctor
02:17 <manek> jle`: no, I want to allow `type instance Foo 'B = Int` but not `type instance Foo B = Int`
02:18 zcourts joined
02:18 zcourts joined
02:19 data_hope joined
02:19 nomotif joined
02:21 Rodya_ joined
02:21 ebutleriv joined
02:22 <jle`> they're the same thing, right?
02:22 <jle`> you just want to be required to use ' explicitly?
02:22 dawehner joined
02:25 exferenceBot joined
02:26 FreeBirdLjj joined
02:28 splanch joined
02:29 Rodya_ joined
02:29 handyc left
02:29 hexagoxel joined
02:31 Koterpillar joined
02:31 raycoll joined
02:34 ystael joined
02:35 wtetzner joined
02:36 aminb joined
02:36 aminb joined
02:40 kylepotts joined
02:41 FjordPrefect joined
02:43 tom7942 joined
02:45 fizbin1 joined
02:45 raycoll joined
02:47 <manek> jle`: sorry I got disconnected and didnt notice it. Yeah they are currently the same, however it is very error prone sometimes
02:47 <manek> jle`: and yeah, I want to enforce using ' explicitly
02:51 takle joined
02:52 mizu_no_oto joined
02:53 plutoniix joined
02:54 FreeBirdLjj joined
02:54 conal joined
02:58 marvin2 joined
02:58 mizu_no_oto joined
02:58 ericsagn1 joined
02:59 takle joined
03:01 bryanlemon joined
03:01 <sophiag> are there haskell libraries that support string literals? as in allowing an IO string to be evaluated as an expression at runtime?
03:03 dfeuer joined
03:03 <geekosaur> that sounds confused, at least twice :)
03:03 <Koterpillar> sophiag: hmm. GHC itself?
03:03 <geekosaur> hint, which isa wrapper for ghc-api, if you actually mean Haskell expressions
03:04 <sophiag> wat?
03:04 <geekosaur> @hackage hint
03:04 <lambdabot> http://hackage.haskell.org/package/hint
03:04 <Koterpillar> well, you want to execute Haskell
03:04 <sophiag> well yeah of course it goes through ghc
03:04 <Koterpillar> so you need a Haskell compiler/interpreter library
03:04 <geekosaur> there's also mueval if you want some safety in what can be done (lambdabot uses mueval, for example)
03:05 FreeBird_ joined
03:05 <geekosaur> however, note that this does not allow introspection into your own program, it creates a separate interpreter instance
03:05 <sophiag> they're usually called "string literals" or "template literals" in other languages and i would imagine there's support for them in haskell, but they're just rarely used due to the obvious downsides
03:05 <geekosaur> there is no eval like there is in python/perl/ruby/javascript that can self-introspect
03:06 <sophiag> e.g. security, lack of full typechecking, etc.
03:06 <geekosaur> because providing that for compilation to native code is difficult and slows everything down
03:06 <Koterpillar> ah, do you mean "Hello, ${username}"?
03:06 <geekosaur> (and, in Haskell, would let you trivially violate referential transparency)
03:06 <sophiag> not quite? if i understand that correctly
03:06 <Koterpillar> what do you want then?
03:07 <sophiag> i found System.Eval.Haskell, but that doesn't take a string specifically
03:07 <Koterpillar> maybe paste an example of what will you do with this library?
03:07 <glguy> sophiag: A string literal is the syntax of including strings directly into the source language, so "example" is a string literal
03:07 <glguy> That's not Haskell specific
03:07 <Koterpillar> assuming it exists as doit :: String -> IO ()
03:07 <glguy> 10 is an integer literal
03:07 <sophiag> glguy: well when they were added to javascript, for example, i think they were officially called "template literals"
03:08 <Koterpillar> sophiag: can you statically compile them in?
03:08 <sophiag> i've used them there to import glsl rather than embedding it in a script tag
03:08 <sophiag> Koterpillar: yes, but not fully since it would be at runtime
03:09 <sophiag> i think actually System.Eval.Haskell looks like it does what i'm referring to
03:09 <Koterpillar> i.e. someone else will give you "Hello ${name}" and you've got to turn it into "Hello Sophiag"?
03:09 <sophiag> no
03:09 <Koterpillar> that's what template literals do in Javascript, though
03:10 <sophiag> like you read a string that says, "map toUpper "sophiag" and you get "SOPHIAG"
03:10 <geekosaur> again, System.Eval.Haskell won't access data in *your* program
03:10 hybrid joined
03:10 <sophiag> that's only one thing you can use them for in javascript
03:10 <Koterpillar> sophiag: OK, that's an interpreter, but it has nothing to do with template literals
03:10 <* geekosaur> just looked up tempate literals; this could be done with a quasiquoter but don't know if anyone has done so
03:10 <Koterpillar> http://exploringjs.com/es6/ch_template-literals.html
03:10 <geekosaur> in fact I'm tempted to say they mean quasiquotes
03:10 <sophiag> ok, lemme reboot this question :)
03:11 <sophiag> i'm looking at System.Eval.Haskell rn. have any of you used that?
03:11 <geekosaur> but that doesn;t mean someone has written quasiquoter that does exactly what you want
03:11 <Koterpillar> geekosaur: template literals are totally quasiquotes, but I think they don't want them
03:11 <glguy> sophiag: Maybe you're asking for a 'string interpolation' library in Haskell then? "In computer programming, string interpolation (or variable interpolation, variable substitution, or variable expansion) is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values."
03:12 <geekosaur> sophiag, I could repeat what I've already said twice but I suspect a third time won't help. what do you believe System.Eval.Haskell will help with?
03:12 <geekosaur> also that functionality was superseded by hint and mueval
03:12 <sophiag> sorry
03:12 <Koterpillar> geekosaur: (14:10:00) sophiag: like you read a string that says, "map toUpper "sophiag" and you get "SOPHIAG"
03:13 <sophiag> geekosaur: i'm considering it in place of parsing a full grammar now that i'm realizing the complexity of what i want and the limited applications
03:13 <geekosaur> yes, the question is whether the constraint I've mentioned matters to you
03:13 <sophiag> so i understand the downsides of evaling strings at runtime, but that might make sense in this case
03:13 <geekosaur> you *cannot* use it to access or modify your own program
03:13 <sophiag> that's goo
03:14 <sophiag> *good
03:14 <sophiag> otherwise it would be a horrible security flaw
03:14 <sophiag> i mean, many people would say it already is
03:14 <geekosaur> that's why mueval :)
03:14 HaskellLord69 joined
03:14 <geekosaur> > putStrLn "hi"
03:14 eazar001 joined
03:14 <lambdabot> <IO ()>
03:15 <sophiag> oh they do make a big deal about safety
03:15 <sophiag> oh, it's lambdabot! lol
03:15 <geekosaur> lb uses mueval to allow safe evals
03:16 <sophiag> geekosaur: i mean, you saw my code earlier...i just realized i don't really want to write 300 lines of parsers for 50 lines of actual logic
03:16 <geekosaur> you can do IO with hint or the plugins wrapper for hint; mueval blocks IO and restricts various other things
03:16 <sophiag> the application is really just so i can build up training it expression by expression and store them in libraries and such
03:17 <sophiag> i think mueval is probably a good thing. but i should look at both
03:17 <geekosaur> also if the idea here is to just use a haskell parser, you might want haskell-src-exts
03:17 splanch joined
03:18 <geekosaur> rather than linking ghc into your application
03:18 <sophiag> hmm
03:18 <sophiag> well, i'm talking about a very limited set of expressions
03:20 <sophiag> but i realized just parsing lists of different types was a bit more heavyweight than i thought and hadn't even gotten on to essentially lambdas
03:20 <Myrl-saki> Liquid Haskell. {-@ predicate Bounded N = 0 < N + maxInt && N < maxInt @-}
03:20 <geekosaur> yes,, that's why pulling all of ghc into your application just for that is a bit weird
03:20 <Myrl-saki> Why 0 < N + maxInt
03:20 <geekosaur> haskell-src-exts you should be able to use one of its subparsers
03:20 takle joined
03:20 <Myrl-saki> Over, say. minInt < 0
03:20 <Myrl-saki> Assuming minInt exists, or something.
03:20 <sophiag> geekosaur: you're saying you think that makes more sense than mueval?
03:20 <geekosaur> yes
03:20 <Myrl-saki> Okay. There's minBound.
03:20 <sophiag> mueval seems more designed for this sort of stuff though
03:21 lavalike_ joined
03:21 <geekosaur> no
03:21 <sophiag> oh wait, yeah now that i'm looking at it
03:21 <geekosaur> I wouldn;t say so, you are used to eval being cheap
03:21 <geekosaur> but using hint or mueval means pulling *all of ghc* into your program
03:21 <sophiag> no, i'm used to this being a kind of stupid thing to do tbh :)
03:21 <Myrl-saki> Or even easier, why `0 < N + maxInt` over `-maxInt < N`?
03:22 tristanp joined
03:22 <geekosaur> haskell-src-exts gives you a parser, and just the parser, not code generators etc. --- and you should be able to pick which parts of the parser to use
03:22 <sophiag> but i see what you mean now because with haskell-src-exts i can just use specific bits of the lexer and such
03:22 <sophiag> right, like i don't need a full evaluator. that would be ridiculous overhead for this
03:22 <sophiag> and even more unsafe
03:23 Conjecture joined
03:23 enitiz joined
03:23 <Conjecture> How extensive is the runtime garbage collector that ghc uses?
03:24 <geekosaur> ?
03:25 <sophiag> Conjecture: http://simonmar.github.io/bib/parallel-gc-08_abstract.html
03:25 fizbin joined
03:26 lavalike joined
03:26 <peddie> Conjecture: it collects all the garbage generated by your program, so quite extensive
03:26 <Conjecture> I should've said
03:27 <Conjecture> In the compiled binary
03:27 <glguy> Conjecture: "extensive" seems like a strange property to ask about of a GC
03:27 <geekosaur> yes, I'm rater confused about what you are asking
03:28 Koterpillar left
03:28 Koterpillar joined
03:28 <Conjecture> geekosaur, When I compiler a binary, there is a garbage collector
03:28 <Conjecture> I compile*
03:29 <Conjecture> At least according to what I've read
03:29 <geekosaur> yes, and?
03:29 <Conjecture> The marketing says that it's very fast
03:29 <Conjecture> Fast is subjective
03:29 <Conjecture> I asked how extensive it was because I'm genuinely curious to know how it affects runtime performance
03:30 <glguy> What are possible levels of "extensive" that you might expect to get in response?
03:31 <Conjecture> Python to the C level
03:31 <glguy> Are you thinking of the word "expensive"?
03:31 afldcr joined
03:31 <Conjecture> oops, I didn't mean to write extensive
03:31 <glguy> efficient?
03:31 <Conjecture> expensive
03:31 <Conjecture> I was a letter off
03:32 <geekosaur> a very confusing letter off, because if it's not extensive then it's leaking memory for no reason :)
03:33 mjz19910 joined
03:33 raycoll joined
03:33 <Conjecture> I put C in my Python to C thing because one could consider the tracking of Stack as garbage collecting
03:34 xtreak joined
03:34 kylepotts joined
03:34 andyhuzhill joined
03:34 ystael joined
03:35 <turnage> Conjecture: I'm not sure that's a helpful analogy
03:35 <Conjecture> Ok, how does it affect performance
03:35 sleffy joined
03:36 raycoll joined
03:36 <turnage> See the introduction to: https://www.microsoft.com/en-us/research/wp-content/uploads/2017/03/haskell-linear-submitted.pdf
03:37 <turnage> it covers the effects of the cost of the gc briefly
03:37 <turnage> really it's not so useful to evaluate cost without also considering what you have to "spend"
03:37 felixsch_ joined
03:38 <Conjecture> turnage, I'm probably conceptualizing this whole thing wrong anyways
03:38 ChaiTRex joined
03:38 <turnage> Conjecture: why are you curious about the cost of the gc?
03:40 mjz19910 joined
03:40 <Conjecture> turnage, To get perspective into how Haskell will perform compared to others
03:41 <geekosaur> I think if you are worried about performance, the gc may be the least of your issues
03:42 <geekosaur> lazy evaluation means you have to optimize differently
03:43 <geekosaur> like, pretty much the first thing everyone asks is whether tail calls are optimized, and the answer is either "trivially yes" or "not relevant". evaluation is *graph reduction*, not call/jump-here-do-this
03:44 <dolio> Well, things would be much worse if tail calls weren't optimized.
03:45 <sophiag> it's not just tail calls tho. technically nothing in haskell is in "proper" tail position because it's all wrapped in thunks
03:45 <dolio> No, that is not true.
03:46 <sophiag> if you have a lazy function, then even if you're recursive call is at the end it's still not technically in what many would consider tail position
03:46 <sophiag> *your, ugh late
03:46 mjz19910 joined
03:47 afldcr joined
03:47 <sophiag> anyway, this is only something i think about because of using clojure which can't do that (at least without a cps transform) because it runs on a fucking stack machine
03:48 eacameron joined
03:48 Rainb joined
03:49 <dolio> Well, doing a CPS transform just makes things worse if you don't have proper tail calls. I guess you could CPS and trampoline yourself, though.
03:49 Rodya_ joined
03:50 <sophiag> you can use CPS to optimize tail calls. that's essentially what's going on in most functional compilers
03:50 pavonia joined
03:51 takle joined
03:52 fizbin joined
03:53 tripped joined
03:53 <Conjecture> Thanks, I think I understand now
03:54 roconnor joined
03:54 splanch joined
03:55 otto_s joined
03:59 sleffy joined
04:03 takle joined
04:03 eklavya joined
04:03 raycoll joined
04:06 <Sornaensis> how dramatically would haskell change if general recursion was removed
04:06 <sophiag> general?
04:06 <Sornaensis> oh I guess it would break
04:06 <sophiag> haha
04:06 <Sornaensis> yea like y f = f y f
04:07 <Sornaensis> y refers to itself
04:07 <Sornaensis> f (y f) sry
04:07 <geekosaur> you already can't do that except via a newtype; the typechecker rejects infinite types
04:07 <Sornaensis> >
04:07 <Sornaensis> ?
04:08 <jle`> `y f = f y f` is already not allowed
04:08 <sophiag> oh yeah, this is an interesting point: http://stackoverflow.com/questions/4273413/y-combinator-in-haskell
04:08 <Sornaensis> > let y f = f (y f) in y (\f n -> if n == 0 then 1 else n * (f (n-1))) 5
04:08 <lambdabot> 120
04:08 fizbin joined
04:08 <Sornaensis> ...
04:09 <geekosaur> if you mean ordinary value recursion, that is certainly permitted and removing it would give you a rather less useful language
04:09 <Sornaensis> you can't write the fixed point combinator like you would in untyped lambda calculus, because haskell is typed
04:09 <sophiag> well you already have fix so that's not really special
04:09 <Sornaensis> but you would have to if general recursion was removed
04:09 <Sornaensis> but you can get around it with newtype
04:09 <Sornaensis> so hm
04:10 sssilver joined
04:10 <geekosaur> well, I'm wndering which general recursion you mean now
04:10 <geekosaur> there is value recursion, where you need to provide a base case or it will recurse forever
04:11 <geekosaur> there is type recursion (data List a = Nil | Cons a (List a))
04:11 <Sornaensis> a function being able to refer to itself
04:11 <geekosaur> and there is Mu (one way to encode a fixpoint combinator via a newtype)
04:12 <geekosaur> (or Fix, or various other ways of slipping the Y combinator into the language by having something that "interrupts" the recursion)
04:12 <geekosaur> ok, ordinary value recursion. you lose lists, trees, etc. because you can't use recursive data types without general recursion
04:13 <geekosaur> you probably lose most functional programming because it's heavily based on inductive recursion
04:13 robotroll joined
04:13 falafel joined
04:13 <sophiag> i suppose actually in haskell you could implement more higher order functions without recursion than in many functional languages
04:14 dfeuer joined
04:15 <jle`> hi all
04:15 <jle`> why is Product/:*: in base twice
04:15 enitiz joined
04:16 fizbin1 joined
04:16 <jle`> oh wait, wrong Product, nvm
04:16 <jle`> oh wait, id o mean it
04:16 <jle`> http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Product.html#t:Product
04:17 jsgrant joined
04:17 <jle`> type Product = (:*:) ...?
04:17 <geekosaur> I eel like someone asked that the other day and the answer is nobody's gone through the trouble of merging them yet?
04:18 <geekosaur> s/through/to/
04:18 <glguy> They serve two different purposes
04:18 <glguy> even if they have the same definition
04:18 <glguy> it's like how even though we have Bool, people make other two constructor data types
04:18 <jle`> i feel like their purposes are the same
04:19 <glguy> One is specifically tied to a compiler generated generics representation of data types
04:19 mac10688 joined
04:20 <jle`> i feel like that could just be one specific usage of (:*:)
04:20 <jle`> there isn't any reason why it has to be tied to generics rep
04:20 <jle`> besides i enjoy typing (f :*: g) better than Product f g
04:20 data_hope joined
04:21 jrajav joined
04:22 Boomerang joined
04:23 fizbin joined
04:27 sleffy joined
04:29 kylepotts joined
04:31 fizbin joined
04:33 takle joined
04:35 ystael joined
04:36 fkurkows1 joined
04:36 augur joined
04:37 eacameron joined
04:40 fizbin1 joined
04:42 Autolycus joined
04:42 takle joined
04:49 andyhuzhill joined
04:49 rossberg joined
04:51 FreeBirdLjj joined
04:52 zar joined
04:56 FreeBirdLjj joined
04:56 fakenerd joined
04:59 takle joined
05:03 dec0n joined
05:04 raichoo joined
05:05 dan_f joined
05:06 ebzzry joined
05:11 {emptyset} joined
05:12 splanch joined
05:13 takle joined
05:14 robertkennedy joined
05:14 vaibhavsagar joined
05:16 vlatkoB joined
05:21 unK_ joined
05:21 fizbin joined
05:21 takle joined
05:21 piyush-kurur joined
05:22 data_hope joined
05:22 xochozomatli joined
05:22 xochozomatli_ joined
05:22 kylepotts joined
05:23 yellowj joined
05:25 c137 joined
05:26 jsoo joined
05:28 meandi_2 joined
05:28 kylepotts joined
05:28 jhrcek joined
05:29 insitu joined
05:29 xtreak joined
05:31 danvet joined
05:32 xtreak joined
05:33 takuan joined
05:36 ystael joined
05:36 tom7942 joined
05:37 raichoo joined
05:40 ichor joined
05:41 kritzcreek_ joined
05:41 takle joined
05:42 osa1_ joined
05:42 tromp joined
05:42 c137 joined
05:43 lok joined
05:44 MrWoohoo joined
05:48 ebzzry joined
05:49 osa1 joined
05:50 fizbin1 joined
05:51 hive-mind joined
05:53 Rodya_ joined
05:53 splanch joined
05:54 JYDoubleU joined
05:55 igniting joined
05:58 SLi joined
05:58 splanch joined
05:59 ThomasLocke joined
05:59 ThomasLocke joined
05:59 Disavowed joined
06:02 <Disavowed> Hey all. Just starting out and looking for a repl with autocompletion whilst I get acquainted. Does such a thing exist? gchi doesn't appear to do this out-of-the-box.
06:03 certainty joined
06:03 caconym joined
06:03 <Freundlich> It doesn't? What exactly are you looking for?
06:04 <Freundlich> You can tab-complete names in ghci at least.
06:04 splanch joined
06:05 shayan_ joined
06:07 freusque joined
06:07 data_hope joined
06:08 zar joined
06:08 <Disavowed> Freundlich: Sorry if I'm being a bit dense - I'm used to tab completion on methods of objects a la ipython but perhaps Haskell doesn't work that way at all. Either way, assigning a list to a variable and then tabbing on that list after a full stop isn't offering me the methods I would expect. Does this sound correct to you?
06:09 ogrady joined
06:10 <Freundlich> Haskell isn't object-oriented, so there are no "methods".
06:10 <kadoban> Disavowed: Haskell is quite different from python and most other languages. Haskell lists don't have methods of that sort
06:10 Hi-Angel joined
06:11 <Disavowed> kadoban: That would explain completely where I am going wrong
06:11 <Disavowed> Thank you
06:12 <Disavowed> Tab completion now working as expected. Thank you both
06:12 <kadoban> Cool, anytime
06:12 fizbin joined
06:14 afnizarnur joined
06:15 suppi joined
06:16 edsko joined
06:20 sypwex joined
06:21 <runeks> Is there a bug somewhere if running with -N1 produces different behaviour from running with -N4? When running with -N4 my program stops gracefully (closes peer connections) (although the process itself never exits), and with -N1 the process exits abruptly, without gracefully closing the peer connections (in a `finally` clause). What gives?
06:21 fizbin joined
06:22 kylepotts joined
06:24 <cocreature> runeks: well multithreading can result in all kinds of bugs. it’s hard to say without seeing some code. one thing to consider is that if your main threads dies, finalizers in other threads are not run
06:24 <cocreature> unless you explicitely wait for them
06:24 razi1 joined
06:25 ebzzry joined
06:26 <runeks> cocreature: I'm waiting for the other threads with a waitAnyCancel: https://github.com/runeksvendsen/haskoin/blob/master/haskoin-wallet/Network/Haskoin/Wallet/Server.hs#L159
06:26 <runeks> When running with -N1, the main thread dies, but with -N4 the main thread never dies
06:26 <cocreature> runeks: which version of async are you using?
06:26 <runeks> I'm trying to rebuild now using lts-8.5, I believe I was using lts-6.14 before (GHC 7.10.3, I believe)
06:27 <cocreature> the behavior changed in 2.1.1 iirc. before that "cancel" will throw the exception but not wait for the thread to exit
06:27 oish joined
06:27 <cocreature> and waitAnyCancel inherits that behavior
06:28 takle joined
06:28 <cocreature> lts 6.14 is still on async 2.1.0 so upgrading that might be worth a try
06:29 fizbin joined
06:29 <runeks> with lts-8.5 I get the same behaviour for -N1 and -N4.
06:29 <runeks> now I just need to figure out why it doesn't exit... :)
06:29 osa1_ joined
06:30 alfredo joined
06:30 laserpants joined
06:32 quchen joined
06:33 connrs joined
06:33 <cocreature> well at least now you only have one problem to figure out :)
06:36 fizbin joined
06:37 ystael joined
06:37 afnizarnur joined
06:38 xinming joined
06:40 <vlatkoB> In ghc7 I had
06:40 <vlatkoB> type DB a = MonadResourceBase m => SqlPersistT m a
06:40 <vlatkoB> but ghc8 complains with
06:40 <vlatkoB> Not in scope: type variable ‘m’
06:40 <cocreature> vlatkoB: try type DB a = forall m. MonadResourceBase m => SqlPersistT m a
06:40 <cocreature> and enable RankNTypes
06:42 <vlatkoB> @cocreature Illegal polymorphic type: forall (m :: * -> *). MonadIO m
06:42 <vlatkoB> A constraint must be a monotype
06:42 <lambdabot> Unknown command, try @list
06:43 <cocreature> vlatkoB: are you sure that error is caused by this code? it doesn’t mention MonadIO
06:44 <cocreature> ah MonadResourceBase is a type synonym
06:44 mr_sm1th joined
06:44 fizbin joined
06:45 arun_t joined
06:46 <arun_t> if any one has ebook of haskell programming from first principles Please send one to me I can't afford to purchase
06:47 <cocreature> vlatkoB: http://lpaste.net/353966 compiles just fine for me
06:47 sypwex joined
06:47 <pacak> arun_t: learnyouahaskell.com/chapters
06:47 free_beard joined
06:47 <cocreature> arun_t: send the authors an email. they openly said that they gift the book to people that can’t afford it or at least give you a discount
06:47 zariuq joined
06:48 <arun_t> I'm sending one now
06:49 zero_byte joined
06:49 <vlatkoB> cocreature: yes, it compiles now. Thanks. Was looking at the wrong line. Thanks a lot. :-)
06:50 kosorith joined
06:50 detrumi joined
06:50 halogenandtoast joined
06:51 sypwex joined
06:52 <Autolycus> if you can't really pay for it it's not difficult to find copies on the web
06:53 ubsan_ joined
06:53 fizbin1 joined
06:53 slomo joined
06:54 harfangk joined
06:55 guiben joined
06:56 kylepotts joined
06:56 CMCDragonkai joined
06:57 <CMCDragonkai> Hi, in regex, you can write something like /\d{1,5}/, what is the best way to achieve this using just Text.ParserCombinators.ReadP?
06:58 orbifx joined
06:59 ali_bush joined
06:59 ali_bush joined
06:59 fizbin joined
07:01 _sg joined
07:01 juhp___ joined
07:01 Grisha joined
07:01 laz joined
07:03 MindlessDrone joined
07:03 insitu joined
07:06 takle joined
07:06 sypwex joined
07:07 hurkan joined
07:08 fizbin1 joined
07:08 <pavonia> CMCDragonkai: catMaybes <$> count 5 (optional $ satisfy isDigit) or something
07:09 vlatkoB_ joined
07:10 BartAdv joined
07:12 curious_corn joined
07:14 albertid joined
07:15 ragepandemic joined
07:17 bennofs joined
07:17 <CMCDragonkai> optional gives ReadP (), not Maybe
07:18 <CMCDragonkai> i can think of a [parse5, parse4, parse3, parse2, parse1] and then fold with symmetric choice
07:18 <CMCDragonkai> actually (<++) choice
07:18 <CMCDragonkai> but that seems inefficient
07:18 <cocreature> CMCDragonkai: you can probably use "optional" from Control.Applicative which does return a Maybe
07:18 raichoo joined
07:19 <pavonia> ^ Yeah, that's the optional I had in mind
07:19 <cocreature> tbh the optional in ReadP seems really weird
07:21 raichoo joined
07:21 mattyw joined
07:22 takle joined
07:23 MindlessDrone joined
07:24 ali_bush joined
07:24 ali_bush joined
07:25 guiben joined
07:25 <CMCDragonkai> Is this what you are thinking?
07:26 <CMCDragonkai> > readP_to_S p "12345"
07:26 <lambdabot> error:
07:26 <lambdabot> Variable not in scope: readP_to_S :: Expr -> [Char] -> t
07:26 <CMCDragonkai> [("","12345"),("1","2345"),("1","2345"),("1","2345"),("1","2345"),("1","2345"),("12","345"),("12","345"),("12","345"),("12","345"),("12","345"),("12","345"
07:26 <CMCDragonkai> ),("12","345"),("12","345"),("12","345"),("12","345"),("123","45"),("123","45"),("123","45"),("123","45"),("123","45"),("123","45"),("123","45"),("123","45
07:26 <CMCDragonkai> "),("123","45"),("123","45"),("1234","5"),("1234","5"),("1234","5"),("1234","5"),("1234","5"),("12345","")]
07:26 <CMCDragonkai> it :: [([Char], String)]
07:26 <CMCDragonkai> Is there a way to make it greedy?
07:26 <CMCDragonkai> Greedy up to say 5
07:27 <CMCDragonkai> there's a lot fo repetition there, 1 for each of the rest of the numbers, then 2 for each of the rest of the numbers... etc
07:27 <nshepperd_> I would use direct recursion to do liftA2 (:) digit (empty <|> liftA2 (:) digit (...))
07:28 <nshepperd_> That way it should avoid any backtracking?
07:28 jsoo joined
07:28 splanch joined
07:31 oish joined
07:32 splanch_ joined
07:32 fizbin joined
07:33 <nshepperd_> Oh, reverse those choices to make it greedy
07:35 <CMCDragonkai> nshepperd_: are you referring to your example or the previous example?
07:35 <nshepperd_> My example
07:36 <CMCDragonkai> is there no way to use just 2 numbers like in regex?
07:36 <nshepperd_> You could package this up into a function
07:37 <CMCDragonkai> This is what I'm doing now:
07:38 ystael joined
07:38 <CMCDragonkai> foldr1 (<++) $ fmap (\x -> count x $ satisfy isDigit) [5,4..1]
07:38 <CMCDragonkai> > readP_to_S p "123456789"
07:38 <CMCDragonkai> [("12345","6789")]
07:38 <lambdabot> error:
07:38 <lambdabot> Variable not in scope: readP_to_S :: Expr -> [Char] -> t
07:38 takle joined
07:38 thc202 joined
07:40 <nshepperd_> upTo 0 _ = pure []; upTo n p = liftA2 (:) p (upTo (n-1) p) <|> pure []
07:41 saurik joined
07:42 <nshepperd_> between x y p = liftA2 (count x p) (upTo y p between)
07:43 <nshepperd_> Er, between x y p = liftA2 (count x p) (upTo (y-x) p between)
07:43 <nshepperd_> Something like that
07:43 tromp joined
07:44 <nshepperd_> To match between 1 and 5 digits first match a digit, then match between 0 and 4 digits
07:44 <CMCDragonkai> Oh the upTo is certainly better, but it still gives me
07:44 <CMCDragonkai> readP_to_S (upTo 5 digit) "123435456789"
07:44 <CMCDragonkai> [("","123435456789"),("1","23435456789"),("12","3435456789"),("123","435456789"),("1234","35456789"),("12343","5456789")]
07:44 <CMCDragonkai> As in, I still have then !! 5 to get the the greedy version
07:44 bjz joined
07:45 <nshepperd_> Hm, that doesn't seem right
07:46 <nshepperd_> The greedy option should come first if the <|>s are done in the right order
07:46 sypwex joined
07:46 Kundry_Wag joined
07:46 <reactormonk> I'm trying to follow the free monad definition - https://gist.github.com/55972ba5a1b95077c46ee872679cd169 - I figured getting the type of (>>= k) would be helpful to understand it. How do I get it? Currently using emacs.
07:48 ehej joined
07:48 cryo28 joined
07:49 yoo_ joined
07:50 kylepotts joined
07:53 <CMCDragonkai> nshepperd_: Your latest one seems pretty much equivalent to: choice $ fmap (\x -> count x $ satisfy isDigit) [5,4..1]
07:53 <CMCDragonkai> nshepperd_: Or: choice $ fmap (\x -> count x $ satisfy isDigit) [1..5]
07:54 <quchen> reactormonk: »impure« is a terrible name for the other constructor of Free.
07:54 ventonegro joined
07:54 sypwex joined
07:55 Rodya_ joined
07:55 <quchen> There’s nothing impure about monads, and nothing impure about bind. »BindFree« would be a better choice, for example.
07:57 Owatch joined
07:57 <Owatch> Hello.
07:57 <Owatch> Is there any way I can instruct haskell how to derive a type I've made?
07:57 <Owatch> I've got a Node with a Point (x,y) and a value (float). I want it to be ordered by Value.
07:58 connrs joined
07:58 Swizec joined
07:58 <cocreature> Owatch: do you want to derive an Ord instance for Point?
07:58 <Owatch> I want to derive an Ord instance for Node, based off value. I.E: Order by value
07:58 <quchen> There is no way to influence auto-deriving typeclasses.
07:58 <Owatch> Not the coordinate of the Node.
07:59 Itkovian joined
07:59 <cocreature> either the autoderived instance works for your application or you have to write one manually
07:59 <Owatch> Well I guess I can try to test and see if it picks up what I want.
07:59 kosorith joined
08:00 fizbin1 joined
08:00 <cocreature> if you care about the result of the Ord instance and do not just need an Ord instance to put things in a Map or something like that, write it yourself
08:01 <cocreature> it’s only two lines or something like that
08:01 <Owatch> Ah, if its that simple then maybe I will. As long as I don't need any non-default packages for it
08:02 <cocreature> you definitely don’t need any packages for that
08:02 mrjake joined
08:02 inad922 joined
08:02 <cocreature> instance Ord Node where compare (Node val1 _) (Node val2 _) = compare val1 val2
08:03 <cocreature> you also want a custom Eq instance in that case.
08:03 marfoldi joined
08:04 fizbin joined
08:04 <quchen> instance Eq Node where a == b = compare a b == EQ
08:04 <quchen> :-)
08:04 augur joined
08:04 <Owatch> I'm quite new to this all. Do I just include that with my type declarations?
08:04 ytrjkr joined
08:04 bennofs joined
08:05 <Owatch> And does that override deriving (Eq, Ord) or must I remove that line from my Data declaration?
08:05 <cocreature> you must remove that line
08:06 <cocreature> and yes you just put this code in the same file as your type declaration
08:06 <Owatch> Okay, thank you.
08:06 <Owatch> How does the Eq one work? Eq Node where a == b = compare a b == EQ
08:07 <Owatch> Doesn't seem to be explicitly picking out the value like in Ord, and comparing them.
08:07 <cocreature> Owatch: it just reuses the Ord instance
08:07 <Owatch> Ah okay.
08:07 <quchen> Owatch: When you already know how to order things, you can find out whether two things are equal. You can spell out the equality yourself as well of course.
08:08 jhrcek joined
08:09 <quchen> instance Eq Node where Node (a,b) == Node (x,y) = a == x && b == y
08:09 <quchen> Like that, for example.
08:10 <Owatch> Yeah, that makes sense to me. At least how I would write it right now.
08:16 xtreak joined
08:16 ramzifu joined
08:18 merijn joined
08:18 takle joined
08:19 bennofs joined
08:20 binaryplease joined
08:21 hurkan joined
08:26 binaryplease1 joined
08:27 magthe joined
08:28 sigmundv_ joined
08:28 CurryWurst joined
08:32 raichoo joined
08:35 certainty joined
08:36 Beetny joined
08:36 mmn80 joined
08:37 kylepotts joined
08:37 takle joined
08:37 sypwex joined
08:38 nick_h joined
08:38 ystael joined
08:41 skeuomorf joined
08:41 fizbin joined
08:43 bennofs joined
08:44 rcat joined
08:44 tromp joined
08:46 govg joined
08:46 splanch joined
08:47 KorriX joined
08:48 Kundry_Wag joined
08:49 splanch_ joined
08:50 biglama joined
08:51 yogsotot_ joined
08:52 <Owatch> Can the same instance of a type exist in different lists?
08:52 <merijn> Owatch: I'm not sure what you mean by that?
08:53 <Owatch> Example: I have a list of Nodes, which I put in a heap. As I extract from the Heap I mark the Node. But it needs to also do the same to the Node in the list.
08:54 mekeor joined
08:54 tomphp joined
08:54 <Owatch> I can always search I guess.
08:54 KorriX joined
08:55 fizbin joined
08:56 Rodya_ joined
08:56 <merijn> Owatch: So you want the change to appear in the heap and the list?
08:56 <Owatch> Right.
08:56 <merijn> Owatch: That's not possible at all with standard lists, etc. since the list and it's content is all immutable
08:57 <Owatch> Well, each type has a unique (x,y) point in it. So I guess I can search through my list with the one I extracted from the heap, and perform the change on it there.
08:57 ccomb joined
08:57 KorriX joined
08:58 <merijn> Owatch: Well, why do you need to maintain the list at all?
08:58 <merijn> Owatch: What are you trying to do?
08:58 <Owatch> I'm finding a minimum spanning tree.
08:58 <Owatch> Using Prim's algorithm.
08:59 pussy joined
08:59 <Owatch> So I need to maintain a heap and a list. As I extract from the heap, I go through the list of all neighbors (AKA, all other nodes since it's a EMSP) and add those whose current cost is greater than the distance between the extracted node and themselves.
09:00 puregreen joined
09:00 prophile joined
09:00 KorriX joined
09:01 <Owatch> That involves marking the node I extracted as visited first, so I don't find itself and re-insert it. So I was asking if it would be possible to change a property that would reflect in the list. I guess not. So I'll do a slower search to set it first, then add the neighbors I guess.
09:01 fizbin1 joined
09:01 Wizek_ joined
09:01 <merijn> Owatch: What representation are you using for the graph? (Also, what's EMSP?)
09:02 KorriX joined
09:03 certainty joined
09:03 <Owatch> I'm using a Data type with a Visited flag (Bool), Value (Double), and a Point (x,y) to represent the graph. an EMSP is an MSP where you're computing the closest nodes by Euclidean distance (so straight line). It means there aren't a set amount of neighbors, and every other node is a potential neighbor.
09:03 dawehner joined
09:04 doomlord joined
09:04 <merijn> This assumes I know what MSP stands for :)
09:04 kylepotts joined
09:04 bennofs joined
09:05 <merijn> I'm also rather unsure of how a point would represent a graph (or, I'm assuming it's supposed to represent a vertex, but I'm not sure how you'd do that using a point unless you have, like, a grid/mesh)
09:06 <Owatch> Oh, a list of points represents the graph.
09:06 <Owatch> I just store all points with their coordinates
09:07 <Owatch> And that's my Graph. I don't need a grid or mesh. MSP means minimum spanning tree. So find the smallest set of edges that connect all nodes together.
09:07 <Owatch> Or is the least costly in terms of distance.
09:08 oish joined
09:09 fizbin joined
09:10 eatman joined
09:12 <merijn> Owatch: Oh, wait. So you have a collection of points in 2D space which you are treating as a fully-connected graph to compute the minimum spanning tree of
09:12 <Owatch> Yes.
09:13 sword865 joined
09:13 <merijn> Honestly, personally I would probably use a mutable vector instead of a list to do this with
09:14 <merijn> Mostly because I tend to think a Compressed Sparse Row representation is the One True graph representation if you wanna be fast. Unless you have a small (<1k?) number of points
09:14 fizbin1 joined
09:14 <Owatch> It can go to several million
09:15 psychicist__ joined
09:15 <merijn> Actually, I'm not even sure a graph representation is the best way to go here at all. Maybe you want to use a metric tree to more quickly find nearby points
09:17 systadmin joined
09:20 fizbin joined
09:23 govg joined
09:24 <Owatch> On an off note, are there any indexable lists in haskell?
09:25 <merijn> What do you mean by indexable list?
09:26 spacedog82 joined
09:26 fizbin1 joined
09:26 zcourts joined
09:32 mekeor joined
09:34 bjz joined
09:35 fizbin joined
09:36 ebzzry joined
09:36 twanvl joined
09:37 xtreak joined
09:37 splanch joined
09:38 benl23 joined
09:39 ystael joined
09:39 migimunz joined
09:40 insitu joined
09:41 arquebus joined
09:43 arpl joined
09:43 lukaramu joined
09:43 ClaudiusMaximus joined
09:44 stephA__ joined
09:45 insitu joined
09:45 <stephA__> hi. Is there a pro or cons for using forM instead of mapM ? I don't see the difference except the order of the arguments. Am I wrong ?
09:45 <merijn> stephA__: They are the same, except for order
09:46 fkurkows1 joined
09:46 <merijn> stephA__: Basically, it depends how you want to partially apply
09:47 Hi-Angel joined
09:47 <lpaste_> merijn pasted “forM vs mapM” at http://lpaste.net/353967
09:47 <merijn> stephA__: Compare those two
09:47 castlelore joined
09:48 <stephA__> nice example, thx
09:49 oisdk joined
09:50 <Athas> I find that I use forM for imperative-ish code, and mapM for functional-ish code.
09:51 michael_ joined
09:54 cpup joined
09:54 oisdk joined
09:54 unit73e joined
09:55 juhp___ joined
09:55 juhp___ joined
09:56 <unit73e> Hey. Does haskell have something equivalent to Scala `Option[String] = request getParameter "name"; name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }` or you just do pattern matching instead?
09:56 <merijn> unit73e: Well, that depends on what the hell that does? :)
09:56 <yushyin> ^
09:56 Rodya_ joined
09:57 locallycompact joined
09:57 xtreak joined
09:57 <unit73e> merijn, it maps and filters if the name is Some[x] (or Just x in case of Haskell)
09:57 Sigyn joined
09:58 <merijn> unit73e: And what happens if it's Nothing?
09:58 <unit73e> merijn, returns Nothing
09:58 kylepotts joined
09:58 <merijn> unit73e: Then it's just "fmap" combined with map/filter, no?
09:58 <merijn> > fmap (map (+1)) $ Just [1..10]
09:58 <lambdabot> Just [2,3,4,5,6,7,8,9,10,11]
09:58 <unit73e> merijn, hum I guess yeah
09:58 c137 joined
09:58 <mekeor> use `fmap (map foo . filter bar) x`
09:58 <merijn> > fmap (map (+1)) $ Nothing
09:58 <lambdabot> Nothing
09:59 <unit73e> cool so that filter map thing just isn't generic
09:59 bennofs joined
09:59 <unit73e> anyway it's this: http://www.scala-lang.org/api/2.12.x/scala/Option.html
09:59 <unit73e> in scala
09:59 <unit73e> thanks
10:00 <unit73e> I'll use that in the Java vs Scala vs Haskell Option thing I'm making :p
10:00 <Owatch> merijn: structures where I can access elements by providing an index.
10:01 <Owatch> Like you would in most imperative languages
10:01 <merijn> Owatch: You probably want a vector? As in the vector package
10:02 <Owatch> Oh nice
10:02 <Owatch> Thanks
10:03 <unit73e> I find it odd that most languages call it Option, Maybe makes more sense to me. Historical reasons?
10:03 jaspervdj joined
10:03 <c137> Can someone please recommend me somewhere to start haskell? I asked this in #haskell-beginner, but there was no ans.
10:03 <brynedwards> c137: haskellbook.com
10:04 <c137> I saw it, but there's no any others?
10:04 <unit73e> c137, learn you a haskell?
10:05 eacameron joined
10:05 <unit73e> or real world haskell
10:05 <unit73e> I learned with those two
10:05 <Owatch> I'll be back later. Goodbye for now! Thanks for the help.
10:05 marr joined
10:06 <c137> OK, thanks brynedwards and unit73e. I saw those sources but did not know which ones are good for pure beginner.
10:06 <unit73e> c137, any of those will do IMO. I started with learn you a haskell but I don't see why not start with the other two.
10:07 splanch joined
10:07 ccomb joined
10:07 <brynedwards> Another http://www.cs.nott.ac.uk/~pszgmh/pih.html
10:08 <brynedwards> I believe all of these are aimed at beginners
10:08 <unit73e> c137, BTW don't be scared of Monad. I don't see what's the deal with people being scared with that. I got it very quickly.
10:09 kuribas joined
10:09 yellowj joined
10:09 <c137> uni73e: Well, I don't even know what it is yet :) but thanks for the remind.
10:10 Kundry_Wag joined
10:10 zeroed joined
10:10 howdoi joined
10:11 silver joined
10:12 phaji joined
10:12 <yushyin> unit73e: with different preludes you can get a generic map (which will be just fmap) so it is no real gain and I stick to fmap. It’s just a name anyway.
10:13 certainty joined
10:13 fizbin1 joined
10:14 zar joined
10:15 insitu joined
10:17 mattyw joined
10:18 <phz_> hey
10:18 <phz_> is there a known abstraction for breaking-folds?
10:18 castlelore joined
10:18 fizbin joined
10:18 <phz_> something like:
10:19 <phz_> foldBreak :: (a -> b -> Maybe a) -> a -> [b] > a
10:19 doomlord joined
10:19 <phz_> foldBreak :: (a -> b -> Maybe a) -> a -> [b] -> a
10:19 oish_ joined
10:19 Flonk joined
10:20 kylepotts joined
10:20 castlelore joined
10:22 systadmin joined
10:22 <barrucadu> What would the semantics of that be? It returns the last `a` for which it was `Just`?
10:22 <hexagoxel> could somebody look at [1] and tell me how you end up with l<=0 by adding 1 or 2 each recursive step? [1] http://hackage.haskell.org/package/text-1.2.2.1/docs/src/Data-Text.html#dropWhileEnd
10:23 FreeBirdLjj joined
10:25 fizbin1 joined
10:27 zcourts joined
10:27 cyborg-one joined
10:27 NeverDie joined
10:28 dawehner joined
10:30 <cocreature> hexagoxel: initially len could be 0 so len - 1 is -1
10:30 <hexagoxel> ah, reverseIter returns -1 or -2.
10:30 <hexagoxel> sorry, i had been looking at iter.
10:31 fizbin joined
10:33 yogsotot_ joined
10:33 bennofs joined
10:35 halogenandtoast joined
10:36 kirillow joined
10:36 deepfire joined
10:36 <unit73e> yushyin, different preludes? I just use the standard one
10:36 <unit73e> I don't mind being `fmap`
10:37 <yushyin> me neither
10:37 <unit73e> Is it common to override the standard prelude?
10:37 <hexagoxel> hmm suppose len==1. then i==0, l==1 => we call reverseIter t 0, which accesses A.unsafeIndex arr (off+0) and A.unsafeIndex arr (off-1)
10:37 <hexagoxel> the last access is bad, is it not?
10:37 <hexagoxel> http://hackage.haskell.org/package/text-1.2.2.1/docs/src/Data-Text-Unsafe.html#reverseIter
10:38 xtreak joined
10:39 <yushyin> unit73e: it’s a matter of taste, I often use BasePrelude, my system ghci also use BasePrelude.
10:40 ystael joined
10:40 <brynedwards> There's a good guide about custom preludes here http://dev.stephendiehl.com/hask/#prelude
10:40 bjz_ joined
10:42 <cocreature> hexagoxel: I think it’s fine assuming your encoding is not screwed up. either the first check will be true then the access is never performed. or it is not but in that case the encoding specifies that there have to be more chars so you can’t be at the end
10:43 fizbin joined
10:44 <kuribas> @hoogle (a -> Maybe b) -> [a] -> Maybe b
10:44 <lambdabot> Data.Maybe mapMaybe :: (a -> Maybe b) -> [a] -> [b]
10:44 <lambdabot> CorePrelude mapMaybe :: (a -> Maybe b) -> [a] -> [b]
10:44 <lambdabot> Agda.Utils.List takeWhileJust :: (a -> Maybe b) -> [a] -> [b]
10:44 emc2 joined
10:45 tromp joined
10:45 kritzcreek_ joined
10:45 <cocreature> kuribas: what is that supposed to do?
10:45 <kuribas> cocreature: find the first value returning Just
10:47 <kuribas> :t \f -> listToMaybe . mapMaybe f
10:47 <lambdabot> (a1 -> Maybe a) -> [a1] -> Maybe a
10:47 carlosdagos joined
10:47 <cocreature> :t \p -> join . find isJust . map p
10:47 <lambdabot> (a1 -> Maybe a) -> [a1] -> Maybe a
10:48 ccomb joined
10:48 rubenz joined
10:49 <kuribas> :t join
10:49 <lambdabot> Monad m => m (m a) -> m a
10:49 fizbin1 joined
10:50 carlosdagos joined
10:50 <cocreature> join is just used to smash the two layers of Maybe together
10:52 NeverDie_ joined
10:53 <hexagoxel> cocreature: yeah true, the unsafeIndex should never happen. but why is reverseIter looking at the second byte to determine if there is a 4-byte character?
10:53 <cocreature> hexagoxel: I have no idea how utf16 works so I can’t answer that :)
10:54 TheAuGingembre joined
10:57 nilof joined
10:57 <hexagoxel> cocreature: thanks for looking; utf16 apparently has some property on both words so things are correct. i need to hunt my bug elsewhere.
10:58 gregman_ joined
10:58 Kundry_Wag joined
10:58 <cocreature> hexagoxel: if you have some reasonably small testcase I might be able to take a look at the actual bug you’re seeing :)
10:59 nighty- joined
11:00 Kundry_Wag joined
11:00 <hexagoxel> not yet; it is one of the evil, nondeterministic kind.
11:00 <cocreature> ah those are annoying, good luck finding it :)
11:00 uwgiqq joined
11:01 netheranthem joined
11:02 xtreak joined
11:02 contiver joined
11:02 fizbin joined
11:03 <unit73e> thanks yushyin and brynedwards
11:05 <unit73e> that's actually a pretty nice Prelude
11:06 <yushyin> see? now you want a custom prelude too ^^
11:06 <tdammers> I have a custom prelude too
11:06 <tdammers> wouldn't recommend anyone to use it though
11:06 <tdammers> it's too opinionated
11:07 <cocreature> I even have a project with a project-specific prelude
11:09 <unit73e> yeah I'm going to test these custom preludes. These do fix some things.
11:09 petermw joined
11:10 fendor joined
11:11 <unit73e> protolude seems good enough for me
11:11 ramzifu joined
11:12 xmonader joined
11:12 Gloomy joined
11:13 mohsen_1 joined
11:14 kylepotts joined
11:15 mmhat joined
11:16 <tdammers> cocreature: had that too, then factored it out into a package of its own, and that's my custom prelude now
11:16 zero_byte joined
11:16 <tdammers> it imports a bunch of data structures, lens, aeson, etc., by default
11:17 alfredo joined
11:17 <lpaste_> merijn pasted “No title” at http://lpaste.net/353970
11:17 <merijn> Any suggestions for names of the 2nd field that are less likely to collide with a name I want to use elsewhere?
11:17 fizbin1 joined
11:18 petermw joined
11:20 alfredo_ joined
11:20 <Grisha> merijn: kynd?
11:20 <cocreature> Grisha: needs more unicode
11:20 <cocreature> kγnd
11:21 <Grisha> \kappa \gamma \eta \delta
11:21 <cocreature> can you use emojis in haskell identifiers?
11:21 <merijn> cocreature: Yes, but usually only as operators
11:22 mizu_no_oto joined
11:22 <merijn> > generalCategory '💩'
11:22 <lambdabot> OtherSymbol
11:22 <cocreature> merijn: ah dang, so you can’t use this here
11:22 coot joined
11:22 <merijn> Symbol characters are operator characters
11:22 <cocreature> what a shame
11:23 skeuomorf joined
11:24 fizbin joined
11:27 zcourts joined
11:30 fizbin joined
11:32 al-damiri joined
11:33 xtreak joined
11:34 Xanather joined
11:34 fizbin1 joined
11:35 diskie joined
11:35 ipuustin joined
11:35 certainty joined
11:35 Dembel joined
11:36 JeanCarloMachado joined
11:37 systadmin joined
11:39 augur joined
11:40 bennofs joined
11:41 jship joined
11:41 ystael joined
11:44 NeverDie joined
11:44 ramzifu joined
11:46 robotroll joined
11:50 lukaramu_ joined
11:50 benl23 joined
11:51 Rodya_ joined
11:54 <tabaqui1> > True || undefined
11:54 <lambdabot> True
11:54 mekeor joined
11:54 deepfire joined
11:54 <tabaqui1> > liftA2 (||) (return True) <*> undefined
11:54 <lambdabot> error:
11:54 <lambdabot> • No instance for (Typeable a0)
11:54 <lambdabot> arising from a use of ‘show_M302220984781207142230388’
11:55 <tabaqui1> > liftA2 (||) (return True) <*> (return undefined)
11:55 <lambdabot> error:
11:55 <lambdabot> • No instance for (Typeable a0)
11:55 <lambdabot> arising from a use of ‘show_M901012516416212450130425’
11:55 <tabaqui1> > liftA2 (||) (return True) <*> (return undefined) :: [Bool]
11:55 <lambdabot> error:
11:55 <lambdabot> • Couldn't match expected type ‘[a0 -> Bool]’
11:55 <lambdabot> with actual type ‘f0 Bool -> f0 Bool’
11:55 Itkovian_ joined
11:56 fizbin joined
11:57 Gloomy joined
11:57 <tabaqui1> > liftA2 (||) (return True) undefined
11:57 <lambdabot> error:
11:57 <lambdabot> • Ambiguous type variable ‘f0’ arising from a use of ‘show_M541081117034...
11:57 <lambdabot> prevents the constraint ‘(Show (f0 Bool))’ from being solved.
11:57 <tabaqui1> > liftA2 (||) (return True) undefined :: [Bool
11:57 splanch joined
11:57 <lambdabot> <hint>:1:45: error:
11:57 <lambdabot> parse error (possibly incorrect indentation or mismatched brackets)
11:57 <tabaqui1> > liftA2 (||) (return True) undefined :: [Bool]
11:57 <lambdabot> *Exception: Prelude.undefined
11:58 <tabaqui1> yeah, here
11:58 <tabaqui1> > liftA2 (||) (return True) undefined :: [Bool]
11:58 <lambdabot> *Exception: Prelude.undefined
11:58 <tabaqui1> True || undefined
11:58 <tabaqui1> > True || undefined
11:58 <lambdabot> True
11:59 splanch_ joined
12:01 splanch__ joined
12:01 <cocreature> tabaqui1: you can send private messages to lambdabot :)
12:03 fakenerd joined
12:04 augur joined
12:04 <tabaqui1> cocreature: yeah, sorry
12:04 nomicflux joined
12:05 <tabaqui1> there was a little bit quiet
12:05 fizbin joined
12:05 <tabaqui1> I thought that nobody noticed
12:06 Khisanth joined
12:06 inad922 joined
12:07 deepfire` joined
12:07 deepfire` left
12:07 ebzzry joined
12:08 ziocroc joined
12:09 gillesmajor joined
12:09 gillesmajor left
12:11 augur joined
12:11 <tabaqui1> btw, I wanted to ask about lazyness in <*> operator
12:11 <tabaqui1> but I think that understand already
12:11 CurryWurst joined
12:11 fizbin1 joined
12:12 mr_sm1th joined
12:15 merijn joined
12:15 tromp joined
12:16 splanch joined
12:16 machinedgod joined
12:18 Ferdirand joined
12:18 fizbin joined
12:19 <Axman6> it will depend on which Applicative instance you use
12:19 <Axman6> > liftA2 (||) (return True) <*> undefined :: Maybe Bool
12:19 <lambdabot> error:
12:19 <lambdabot> • Couldn't match expected type ‘Maybe (a0 -> Bool)’
12:19 <lambdabot> with actual type ‘f0 Bool -> f0 Bool’
12:19 mattyw joined
12:20 cpennington joined
12:20 <Axman6> > liftA2 (||) <$> (return True) <*> undefined :: Maybe Bool
12:20 <lambdabot> error:
12:20 <lambdabot> • Couldn't match type ‘f0 Bool’ with ‘Bool’
12:20 <lambdabot> Expected type: Maybe Bool
12:20 <Axman6> > (||) <$> (return True) <*> undefined :: Maybe Bool
12:20 <merijn> Axman6: liftA2 already does <*>
12:20 <lambdabot> *Exception: Prelude.undefined
12:20 <Axman6> yeah -_- it'a late
12:20 <Axman6> > (||) <$> (return True) <*> Just undefined :: Maybe Bool
12:20 <lambdabot> Just True
12:24 kirillow joined
12:25 nitrix joined
12:25 systadmin joined
12:26 <merijn> hmmm, interesting...
12:27 <merijn> -fdefer-typed-holes is making GHC panic...guess I have to finally bite the bullet and upgrade >.<
12:28 <cocreature> you can now witness the very rare event of merijn upgrading parts of his software stack
12:28 fizbin joined
12:29 cchalmers joined
12:29 <merijn> cocreature: See, the real question is: Will I update to 7.10.3 or go for 8.0 :p
12:30 <cocreature> merijn: obviously 7.10.3. otherwise things would actually change
12:30 <merijn> cocreature: Well, I was using the ghcformacosx installer, but that one doesn't seem to have an 8.0 version
12:32 <merijn> So then the question is: Can I be arsed to figure out how the hell stack works, or do I just install binary GHC
12:33 alanb99 joined
12:33 alanb99 left
12:33 <nitrix> glguy: srhb merijn Geekingfrog Apologies for my attitude friday in regards to NF/HNF/WHNF.
12:33 fizbin1 joined
12:34 fendor joined
12:35 doodlehaus joined
12:35 nut joined
12:36 <nut> how to run a Producer (ResourceT IO) FilePath ? in conduit
12:36 <nut> i've tried runConduitRes
12:36 <nut> but the type is wrong
12:38 Yuras joined
12:39 <srhb> nitrix: No worries. :)
12:41 <nitrix> glguy: srhb merijn Geekingfrog I've always been here with the intention of improving my Haskell skills and I don't want to be associated with that sort of talk. I think ignorance and ego lead to it. I'm taking a step back, especially being more cautious with spreading what I'm not totally confident about.
12:42 <srhb> nitrix: Don't worry about getting it wrong every now and then, usually someone will be there to correct it. :)
12:42 merijn joined
12:42 <srhb> No harm done.
12:42 <* srhb> gets things wrong all the time!
12:42 kylepotts joined
12:42 <nitrix> srhb: My reaction to it felt like I was biting the hand that fed me in retrospective.
12:44 jaspervdj joined
12:45 oish_ joined
12:45 <tabaqui1> I get "fdReady: msecs != 0, this shouldn't happen[1] 17452 abort (core dumped)" while trying to read data from namedpipe
12:46 <tabaqui1> while hWaitForInput precisely
12:46 fizbin joined
12:46 <merijn> cocreature: Well, you'll be pleased to know I'm still stubborn and am installing binary GHC and cabal from scratch, rather than figuring out this new-fangled stack stuff :p
12:46 <tabaqui1> why can it happen?
12:46 psychicist__ joined
12:47 <merijn> tabaqui1: Because bugs happen? :)
12:47 Yuras joined
12:47 <lyxia> nut: use `connect`, you must also provide a consumer/sink.
12:47 <tabaqui1> merijn: hm, do you suspect such thing?)
12:48 coot joined
12:48 <merijn> tabaqui1: Well clearly it's crashing, so I'd say that's a bug, yes
12:48 kosorith joined
12:49 <tabaqui1> API for dealing with named pipes is poor, if you ask me
12:49 jgertm joined
12:49 splanch joined
12:49 <tabaqui1> if you try to hGetLine from pipe, you get an exception
12:50 <tabaqui1> but operation must block
12:50 <tabaqui1> not failed
12:50 <tabaqui1> *fail
12:51 <cocreature> merijn: I would be worried about you if you didn’t do this :)
12:51 chlong joined
12:52 <merijn> cocreature: 5 seconds looking at the user guide it's "prefix everything with stack", "creating huge directory hierarchies", "projects", and "YAML files"
12:52 Rodya_ joined
12:52 Kundry_Wag joined
12:53 carlosdagos joined
12:53 bryanlemon joined
12:53 jgertm joined
12:53 bryanlemon joined
12:56 fizbin joined
12:57 Itkovian joined
12:58 Sh4rPEYE joined
12:58 alanb99 joined
12:59 plutoniix joined
12:59 <unknownln> http://m.imgur.com/vme6k3c
12:59 <unknownln> Gaaah
12:59 <unknownln> Screw you riot
12:59 <unknownln> Can't link to the right channel
13:00 <yushyin> ^^
13:00 plutoniix joined
13:00 <unknownln> Phone + fingers + channels sorted by most recently active = bad time
13:01 cdg joined
13:03 alanb99 left
13:03 cdg joined
13:04 <ngWalrus> :(
13:04 sypwex1 joined
13:06 afnizarnur joined
13:06 ExpHP joined
13:06 <hexagoxel> how do i convince stack to call ghc so it dumps the preprocessor output?
13:07 afnizarnur joined
13:07 <hexagoxel> raah i have to look at the -v output of `stack build` to see what wrapper they call, then manually call that wrapper with -v to see how it calls ghc, then call that with modified options that do the dumping?
13:07 <hexagoxel> seriously?
13:07 <hexagoxel> there's another argument against stack.
13:10 <merijn> hexagoxel: Thanks for the validation of my previous decision ;)
13:10 theelous3 joined
13:10 augur joined
13:11 doodlehaus joined
13:11 ijp` joined
13:12 merijn joined
13:12 wei2912 joined
13:13 mutsig joined
13:13 e14 joined
13:13 zar joined
13:14 sypwex joined
13:14 ramzifu joined
13:15 migimunz joined
13:15 zariuq joined
13:17 CurryWurst joined
13:17 Kundry_Wag joined
13:19 <Axman6> hexagoxel: how would you usually get ghc to do that? also, stack's tab completion makes finding those answers a lot easier
13:19 dsh joined
13:20 lampam joined
13:20 <brynedwards> --ghc-options ?
13:20 Itkovian joined
13:21 <hexagoxel> it is trivial on neither cabal nor stack, because -E is incompatible with other options.
13:22 doodlehaus joined
13:23 sdothum joined
13:24 <tabaqui1> yeah, look
13:24 <tabaqui1> H.withFile "/tmp/52169.webengine" H.ReadMode (flip H.hWaitForInput 1000)
13:25 <tabaqui1> ghc 8.0.1 - totally blocks, doesn't react at Ctrl-C
13:25 <Axman6> hexagoxel: you an always use stack exec ghc -- -E
13:25 <Axman6> (I think)
13:25 <tabaqui1> ghc 8.0.2 - crashed
13:25 <tabaqui1> oops
13:25 zar joined
13:25 <tabaqui1> little disclosure
13:25 <tabaqui1> H.withFile "regular_file" H.ReadMode (flip H.hWaitForInput 1000)
13:26 <tabaqui1> *8.0.1 returns correct result after delay
13:27 <tabaqui1> but operation cannot be interrupt before timer expires
13:27 <tabaqui1> *interrupted
13:27 Fairy joined
13:27 mizu_no_oto_work joined
13:27 bennofs joined
13:27 <hexagoxel> Axman6: s/always/if you use only the defaults in your package. no extensions, no includes, ../
13:28 Kundry_Wag joined
13:31 Kundry_Wag joined
13:31 NeverDie_ joined
13:31 ccomb joined
13:36 lukaramu__ joined
13:37 kylepotts joined
13:38 coltfred joined
13:38 thimoteus joined
13:39 meba joined
13:39 ozgura joined
13:40 ystael joined
13:41 armyriad joined
13:41 merijn joined
13:42 kaiserAnd joined
13:42 kylepotts joined
13:43 sea_wulf joined
13:43 <kaiserAnd> just to know, have you ever been able to use haskell as a selling point at an interview? do companies care about that skill set?
13:43 eacameron joined
13:44 cobreadmonster joined
13:44 halogenandtoast joined
13:45 eacameron joined
13:46 robkennedy joined
13:47 WhiskyRyan joined
13:47 <opqdonut> kaiserAnd: in the interview for my current consulting job they asked me to explain monads, and then asked me to stop afer 5 minutes
13:47 <merijn> opqdonut: Oh god...please stop!
13:47 dylukes joined
13:47 <opqdonut> probably would've gotten the job even without that, but it's a fun anecdote
13:48 <opqdonut> writing clojure here at the moment, there are no other haskell guys
13:48 kagcc joined
13:49 <Axman6> kaiserAnd: well, we're specifically hiring FP programmers at the moment, so it's a definite plus for us ;)
13:49 <kaiserAnd> that's quite surprising, in my experience the only stuff the HR people know is java and that's about it
13:49 <merijn> Ah, the fun challenge of figuring out "how the hell can I get my dependencies fixed again" >.>
13:49 pylbrecht joined
13:49 <Axman6> kaiserAnd: HR people shouldn't be doing interviews for technical roles
13:49 orison joined
13:49 <opqdonut> yeah
13:50 <kaiserAnd> Axman6: yeah that's true, but that's how stuff works here :p
13:50 skinkitten joined
13:50 armyriad joined
13:51 <merijn> Is there a way to relax a single bound on a package without first unpacking it?
13:51 <Axman6> unpacking it would be the easiest way I think
13:51 <merijn> bleh
13:52 <Axman6> (making modifications to deps is one of the things stack makes quite easy btw, because you can specify where deps live concisely)
13:52 Itkovian_ joined
13:53 Rodya_ joined
13:53 crobbins joined
13:55 <merijn> Axman6: I prefer just patching and fixing Hackage anyway
13:55 <ezyang> isn't this what allow-newer is for
13:55 <merijn> ezyang: That relaxes *everything*
13:56 <merijn> ezyang: I just want to relax 1 or 2 things
13:56 dfeuer joined
13:56 <ezyang> you can target it
13:56 <merijn> ezyang: Well, that's what I was asking :p
13:56 <ezyang> http://cabal.readthedocs.io/en/latest/nix-local-build.html#cfg-field-allow-newer
13:56 earldouglas joined
13:57 eschnett joined
14:01 nycs joined
14:01 <merijn> @ask edwardk What's the easiest way to get the bounds of bound (hah!) relaxed? Pull request with changes?
14:01 <lambdabot> Consider it noted.
14:02 OriSon joined
14:03 wraithm joined
14:04 sphinxo joined
14:07 cdg_ joined
14:08 venkat24 joined
14:08 PennyNeko joined
14:08 <sphinxo> What's an efficient way to store and traverse arbitrary sql like tables
14:08 Welkin joined
14:09 guampa joined
14:10 ystael joined
14:11 ChristopherBurg joined
14:13 eklavya joined
14:14 mszczygiel joined
14:14 <* hexagoxel> discovers that CPP macros on macOS don't like spaces between function-macro-name and parenthesis for arguments.
14:16 psychicist__ joined
14:16 dan_f joined
14:17 alanb99 joined
14:18 free_beard joined
14:18 mmachenry joined
14:19 mada joined
14:19 binaryplease joined
14:20 ramzifu joined
14:21 animated joined
14:22 conal joined
14:23 mudri joined
14:23 sepp2k joined
14:24 HappyEnte joined
14:24 reptar_ joined
14:25 <mudri> Hi. I've got preëxisting classes A and B, and I want to say that from any instance of B, we can derive an instance of A. Is that possible?
14:26 simukis__ joined
14:26 Luke joined
14:26 <merijn> mudri: Only if you never allow any other instances of A
14:27 <mudri> merijn: hmm, not likely, given that A is Ord in my case. ;-)
14:28 lep_ joined
14:28 <mudri> I guess it causes too much trouble for instance search.
14:28 Fairy joined
14:29 codesoup joined
14:30 HappyEnte joined
14:30 simukis__ joined
14:30 zcourts joined
14:30 puregreen joined
14:30 fendor joined
14:30 fosskers joined
14:31 Luke_ joined
14:31 umib0zu joined
14:31 fizbin joined
14:32 <cocreature> sphinxo: a database? I’m not sure I understand your question :)
14:32 kylepotts joined
14:33 Sh4rPEYE joined
14:35 crobbins joined
14:36 sproctor-work joined
14:37 cyborg-one joined
14:37 caconym joined
14:39 <lampam> protip: don't accidentally have two "packages:" lists in stack.yaml
14:39 <lampam> your errors will suddenly make a lot more sense
14:41 <Rembane> :D
14:42 alx741 joined
14:43 dawehner joined
14:44 mson joined
14:47 dram_phone joined
14:51 gabe4k joined
14:51 ziocroc joined
14:52 inad922 joined
14:52 {emptyset} joined
14:52 <kadoban> ExpHP: Hah
14:52 splanch joined
14:53 Rodya_ joined
14:56 uglyfigurine joined
14:57 tristanp joined
14:58 ziocroc joined
14:58 mekeor joined
14:58 tg joined
14:58 ChaiTRex joined
14:59 <mekeor> #NoteToSelf && #DeMorgan: Instead of `not a && not b`, better use `not (a || b)` because you avoid 1 `not` and `||` is lazy.
15:02 jomg joined
15:02 <sproctor-work> Does anyone know if it's possible to specify multiple name options for the same package in pkgconfig-depends? Some versions of linux have lua 5.1 as "lua-5.1" and some have it as just "lua"
15:02 <mekeor> mekeor: this is not true. `&&` is lazy, too. e.g. if `not a == false`, `not b` doesn't have to be evaluated
15:02 cpennington joined
15:03 tristero joined
15:05 <mekeor> sproctor-work: maybe try asking in #lua, too
15:05 Sh4rPEYE joined
15:07 raichoo joined
15:08 <sproctor-work> mekeor: I think it's more of a cabal issue than a Lua issue (other than the fact that Lua distributors can't decide on a consistent naming scheme)
15:08 sellout- joined
15:09 mkoenig joined
15:09 hackebeilchen joined
15:09 coot joined
15:11 <cocreature> sproctor-work: I thought the job of pkgconfig is to figure this kind of stuff out. e.g. you specify lua53 and then pkgconfig figures out that the lib is called lua
15:11 geekosaur joined
15:11 wraithm joined
15:12 coot joined
15:12 eazar001 joined
15:13 Kundry_Wag joined
15:14 takle joined
15:14 <sproctor-work> cocreature: the pkg-config name for lua is system dependent, apparently. pkg-config --list-all on this computer gives me "lua5.1" and "lua-5.1". elsewhere, it's just "lua" and on my macbook, it's just "lua-5.1"
15:15 <cocreature> sproctor-work: ah that sucks. I have both lua and lua53 (but not lua-5.3)
15:15 <cocreature> would be way to easy if this was consistent
15:15 unK_ joined
15:17 moongazer joined
15:18 marsam joined
15:18 osa1 joined
15:18 <sproctor-work> using autoconf, you could do: PKG_CHECK_MODULES([LUA], [lua-5.1],, [PKG_CHECK_MODULES([LUA], [lua = 5.1])])
15:18 burtons joined
15:20 ramzifu joined
15:20 <robkennedy> If I define `data T a b = T a b`, is it generally better to defined `newtype T a b = T (a,b)` ?
15:21 <quchen> It’s pretty much the same.
15:21 ccomb joined
15:21 <robkennedy> Tight
15:21 <quchen> Up to pattern matching details, which make a slight difference between data types and newtypes.
15:21 <dram_phone> If you want to go from T to tuple and back often the second one can help
15:21 skinkitten joined
15:22 <dram_phone> If you always pattern match on {{ T u v }} in the first case and {{ T (u, v) }} in the second case there isn't any real difference
15:22 <dram_phone> Because (in a way) data (a, b) = (a, b)
15:22 <ertes> robkennedy: you could… you know… just use (,) to begin with =)
15:23 <ertes> unless you're using T mainly to override instances, in which case i'd go with the newtype variant, mostly because you can use GeneralisedNewtypeDeriving
15:24 carlomagno joined
15:26 chlong joined
15:26 kylepotts joined
15:27 Grisha_ joined
15:28 AndreasK joined
15:28 mmo joined
15:28 eklavya joined
15:29 mudri joined
15:29 mmo left
15:30 igniting joined
15:30 JonReed joined
15:30 zcourts joined
15:30 urodna joined
15:33 alanb99 joined
15:33 handyc joined
15:34 caconym joined
15:35 alanb99 left
15:36 Jacoby6000__ joined
15:39 maarhart joined
15:39 sophiag joined
15:40 geekosaur joined
15:43 Gloomy joined
15:44 importantshock joined
15:44 MindlessDrone joined
15:45 jbuurlage joined
15:46 MarioBranco joined
15:48 tangled_z joined
15:48 jbuurlage joined
15:49 Itkovian joined
15:49 certainty joined
15:49 sssilver joined
15:49 skeet70 joined
15:49 maarhart joined
15:55 sz0 joined
15:58 jmiven joined
15:58 maarhart joined
15:58 conal joined
15:59 sanett joined
15:59 <sanett> hey folks, I have a lambda expression like lx.x x, is the last x free or bound?
16:00 <srhb> sanett: Does that space have special meaning? Is it (\x -> x x) (ie. x applied to x)?
16:00 <srhb> sanett: If so, I think you may know the answer? :)(
16:02 <sanett> wait... \x.x x and \x.xx are different?
16:02 shesek joined
16:03 <quchen> Depends on your notation. Please add parentheses to clarify. In normal notation, (λ x. x x) is the same as (λ x. (x x)).
16:04 <JonReed> Hi, is there a way to match uppercase character in Attoparsec?
16:04 jmelesky joined
16:07 fizbin joined
16:07 <sanett> I have never been more confused in my life. This article states that lx.xx is the same with (lx.x)x and is thus different from lx.(xx)
16:07 fendor joined
16:08 Deide joined
16:08 <sanett> if it's lx.(xx), I guess the last x is bound?
16:08 <sanett> but is (lx.x)x the same with (ly.y)x?
16:08 ramzifu joined
16:09 <quchen> »λ x. x« is the same as »λ y. y«, yes. (By α-equivalence.)
16:09 <glguy> (λx.x)x and (λy.y)x will evaluate to the same result
16:09 geekosaur joined
16:09 <quchen> AKA renaming bound variables
16:10 <JonReed> Nevermind, it does not appear to be a single function for this like it Parsec, one would have to use satisfy in attoparsec for this.
16:10 caconym joined
16:10 <glguy> (λx.x)x is different from λx.(x x)
16:10 kylepotts joined
16:10 <quchen> If the article says that »λ x. x x« is the same as »(λ x. x) x«, then it uses horrible nonstandard notation.
16:11 <glguy> Maybe just link the article?
16:11 <sanett> where can I find the conventional notation?
16:11 <glguy> It could just be that you're misunderstanding what it says
16:11 <sanett> it's not written in English
16:11 Jesin joined
16:12 plutoniix joined
16:13 <quchen> λxy.z = λx.(λy.z) ; λx.yz = λx.(yz) ; fxy = (fx)y
16:13 <sanett> so can I say that lambda extends to as far right as it gets until it meets a left parenthesis?
16:13 geekosaur joined
16:13 <glguy> No, it extends beyond any (
16:14 vydd joined
16:14 connrs joined
16:14 ozgura joined
16:14 <quchen> A lambda has scope as long as it can, until it meets a closing parenthesis that wasn’t opened in its body.
16:14 Itkovian joined
16:15 <sanett> so it extends to as far as it gets until a ) then?
16:15 <glguy> not an arbitrary ), but one that closes a ( to the left of the λ
16:15 <sanett> right
16:16 <quchen> For example, λz.λxy.f(xy)z = λz.(λx. (λy.(f(xy))z))
16:16 sleffy joined
16:16 <quchen> Here, the closing parenthesis around (xy) does not finish the lambda.
16:16 cmsmcq joined
16:16 wraithm joined
16:16 <sanett> yep your example clears that up
16:17 geekosaur joined
16:17 <sanett> I'll be back with more questions... Thanks guys.
16:19 sypwex joined
16:19 Sh4rPEYE joined
16:20 newguy joined
16:21 geekosaur joined
16:21 Sonolin joined
16:22 sigrlami joined
16:25 _sras_ joined
16:25 splanch joined
16:26 sanett joined
16:27 geekosaur joined
16:27 gabe4k joined
16:27 jao joined
16:28 tom7942 joined
16:28 trism joined
16:29 {emptyset} joined
16:30 SpinTensor joined
16:30 serendependy joined
16:31 zcourts joined
16:32 augur joined
16:34 replay joined
16:34 sanett_ joined
16:35 <_sras_> Is there any resources for learning how to use hasql?
16:37 gienah_ joined
16:37 atomi joined
16:38 sypwex joined
16:39 boombanana joined
16:40 <cocreature> _sras_: iirc I’ve just used the testsuite and the haddocks. I don’t know of a proper tutorial
16:41 sanett joined
16:42 marsam joined
16:42 MindlessDrone joined
16:42 caconym joined
16:43 <_sras_> cocreature: Have you used it? What are its capabilities?
16:43 Rodya_ joined
16:43 eatsfoobars joined
16:44 sigrlami_ joined
16:45 goldfire joined
16:47 <cocreature> _sras_: yes, I’ve used it but not in a large app. I would say overall it’s quite a nice library and gets the job down. there are however a few limitations: 1. no support for psql notifications (I started working on that at some point but I got busy with other stuff) 2. no direct support for multi-tuple inserts (you can work around this but it is annoying) 3. you quickly run into limitations if you want
16:47 <cocreature> to use custom psql types, e.g. arrays of composites are not supported. sadly I don’t know of any Haskell psql library that properly supports this so even if that’s annoying it’s not a reason against hasql
16:47 splanch joined
16:47 kosorith joined
16:47 roconnor joined
16:48 gabe4k joined
16:48 JeanCarloMachado joined
16:48 <cocreature> _sras_: and you are generally going to write slightly more code for decoding/encoding rows than you would with postgresql-simple
16:49 ner0x652 joined
16:49 govg joined
16:50 tokage joined
16:50 <_sras_> cocreature: So why should one use hasql over postgresql-simple. Speed?
16:50 Speed left
16:51 <cocreature> _sras_: a) you might prefer its API b) speed c) I think it’s slightly better at encoding/decoding custom types but as I said it reaches its limitations very quickly
16:51 prkc joined
16:51 squotro joined
16:52 Kreest__ joined
16:55 fizbin joined
16:55 atomi joined
16:55 fizbin joined
16:55 t7 joined
16:56 connrs joined
16:56 squotro left
16:57 kylepotts joined
16:58 fizbin joined
17:00 atomi joined
17:01 snowalpaca joined
17:01 mmachenry joined
17:01 snowalpa_ joined
17:02 squotro joined
17:02 beerdrop joined
17:02 Aune joined
17:03 kirillow joined
17:04 mac10688 joined
17:04 <squotro> is anybody here?
17:05 <lambdabot> Hello.
17:05 <ExpHP> hi
17:05 <Phyx-> what, lambdabot says hello now?
17:05 <ExpHP> @karma+ lambdabot
17:05 <lambdabot> lambdabot's karma raised to 34.
17:05 yellowj joined
17:07 <mada> lol
17:08 MarioBranco joined
17:11 <squotro> hey
17:11 twanvl joined
17:12 coot joined
17:13 NeverDie joined
17:13 <squotro> (
17:14 Gloomy joined
17:14 _sg joined
17:15 <_sras_> Have any Opaleye users experienced slow query planning for opaleye generated left joins with around 10 tables?
17:15 Luke joined
17:15 alanb99 joined
17:16 bennofs joined
17:16 wraithm joined
17:16 asdfasdf joined
17:18 hits1911 joined
17:19 <squotro> oops
17:20 ramzifu joined
17:20 alanb99 left
17:21 ggVGc joined
17:21 mson joined
17:21 Hi-Angel joined
17:21 hits1911 left
17:21 phyrex1an joined
17:22 fotonzade joined
17:23 aarvar joined
17:24 <fendor> @karma lambdabot
17:24 <lambdabot> lambdabot has a karma of 33
17:25 doodlehaus joined
17:25 ozgura joined
17:26 funkshun joined
17:26 Lord_of_Life joined
17:27 MoALTz joined
17:28 truelean joined
17:30 <sphinxo> are there any libraries for doing reversable binary reading/writing?
17:32 zcourts joined
17:32 jsgrant-_ joined
17:34 atomi joined
17:34 <geekosaur> binary and cereal; attoparsec is often used when you need to model a state machine (for e.g. a binary network protocol)
17:34 mkloczko joined
17:34 byte512 joined
17:35 oisdk joined
17:35 Luke joined
17:36 maarhart joined
17:38 Ferdirand joined
17:38 chlong joined
17:39 <tokage> hello is anybody here? I have a very important meta question.
17:39 Noldorin joined
17:39 simukis__ joined
17:39 <mniip> tokage, don't ask to ask
17:40 freusque joined
17:41 <nitrix> data Phantom a = Phantom; data Foo a = Foo a
17:41 niklasb joined
17:41 <nitrix> Is there a way for Haskell to infer the `a` of Foo based on the phantom `a` of Phantom?
17:42 <mniip> what
17:42 <nitrix> I have a feeling this is muddy territory.
17:42 <mniip> what do you mean
17:42 <glguy> nitrix: example :: Phantom a -> Foo a -> Foo a; example _ x = x
17:42 <glguy> You can use something like that to relate the two
17:43 <nitrix> glguy: err, oh you're right I asked the wrong question.
17:43 <nitrix> I jumped the guns, let's see if the problem is still there once I finish this type equality thing.
17:45 CurryWurst joined
17:46 Edith joined
17:46 atomi joined
17:46 sypwex joined
17:47 drewr joined
17:47 conal joined
17:47 JuanMiguel joined
17:48 binaryplease joined
17:49 skeet70 joined
17:49 sypwex1 joined
17:49 certainty joined
17:50 wraithm joined
17:51 atomi joined
17:53 Rainb joined
17:53 Guest44013 joined
17:55 JuanDaugherty joined
17:56 atomi joined
17:58 conal joined
18:02 osh joined
18:02 g0d355__ joined
18:03 sypwex joined
18:03 wraithm joined
18:03 <nitrix> Wow, that's fascinating. edwardk laid out perfectly lens to support what I'm working on and working with referential data in Haskell in a pure way.
18:04 <sphinxo> How might I make loeb work with an input such as [const [const 1]]
18:04 <nitrix> (Without happing tons of mappings of ids that are O(log n)). I'm back working on it and his work is such ahead of the curve.
18:05 orison joined
18:05 <sphinxo> ( what loeb is https://github.com/quchen/articles/blob/master/loeb-moeb.md )
18:06 raynold joined
18:06 <lyxia> sphinxo: what's wrong with what you wrote
18:08 sssilver joined
18:08 <lyxia> > let loeb f = fix (\x -> fmap ($ x) f) in loeb [const [const 1]]
18:08 emmanuel_erc joined
18:08 <lambdabot> error:
18:08 <lambdabot> • No instance for (Typeable b0)
18:08 <lambdabot> arising from a use of ‘show_M18719631324288613376305’
18:08 <lyxia> boo
18:08 emmanuel_erc joined
18:08 silver_ joined
18:08 <lyxia> :t let loeb f = fix (\x -> fmap ($ x) f) in loeb [const [const 1]]
18:08 <lambdabot> Num a => [[b -> a]]
18:09 sw1nn joined
18:09 <lpsmith> cocreature, well as far as I can see, postgresql-simple is much better at supporting custom types than hasql.
18:09 <lpsmith> Last I checked, you'd have to modify hasql to support extended types.
18:09 <sphinxo> so fmap loeb (loeb input)
18:10 Rodya_ joined
18:10 <lpsmith> postgresql-simple does need support for binary parameters/results though.
18:10 NeverDie joined
18:10 <lpsmith> I do admit that.
18:10 <sphinxo> thanks lyxia
18:11 fuzzy_id joined
18:11 <sophiag> is anyone here familiar with haskell-src-exts? i'm trying to figure out how to process the ASTs it returns
18:12 ertesx joined
18:12 osa1_ joined
18:12 <glguy> sophiag: It's possible that someone simply familiar with Haskell would be able to help. Just ask your actual question.
18:13 osa1 joined
18:13 <sophiag> glguy: i feel like the child who doesn't know enough to ask a question :)
18:13 <sophiag> for example, when parsing a list it returns: "List [Lit (Char 'a'),Lit (Char 'b'),Lit (Char 'c')]"
18:14 <sophiag> let's say i want to covert that into just a list of the chars as it was input?
18:14 <sphinxo> lyxia: how would I evaluate [const [const [const 1]]] or an arbitrarily deep data structure?
18:15 <pikajude> sophiag: why do you want to convert it to a list of chars?
18:15 <pikajude> is that what you get from parsing ['a','b','c']
18:15 BlueRavenGT joined
18:16 <sophiag> pikajude: yes. i'm using haskell-src-exts to avoid having to write complicated custom parsers to handle that sort of input
18:16 Swizec joined
18:16 <pikajude> well why are you parsing it
18:16 <pikajude> what's the use case
18:16 wraithm joined
18:16 <pikajude> if you want to parse ['a','b','c'] and get a list of chars, i wouldn't use HSE because it's going to give you an AST
18:16 <pikajude> which is way more than you need
18:17 <sophiag> it was recommended to me yesterday. the use case is i'd like to pass it as an argument to a data constructor
18:17 <glguy> Whether or not haskell-src-exts is good, sophiag should be able to process that value to extract a Maybe [Char]
18:17 <lyxia> sphinxo: (fmap . fmap) loeb . fmap loeb . loeb
18:17 <sophiag> i'm not sure what the "Lit" token means tbh
18:18 <pikajude> glguy: sure, just checking if it could be avoided by using a library with less of a kitchen sink
18:18 <pikajude> sophiag: Lit means literal
18:18 <sophiag> ah ok, tahnks
18:18 <glguy> sophiag: It's a constructor for the Exp type: http://hackage.haskell.org/package/haskell-src-exts-1.19.1/docs/Language-Haskell-Exts-Syntax.html#t:Exp
18:18 <pikajude> 'a' is a character literal
18:18 Discovery joined
18:19 <pikajude> getChars (List exprs) = mapM (\ expr -> case expr of Lit (Char c) -> Just c; _ -> Nothing) exprs
18:19 zero_byte joined
18:19 <pikajude> getChars _ = Nothing
18:19 <pikajude> off the top of my head
18:19 fizbin1 joined
18:20 MP2E joined
18:20 pera joined
18:20 <sophiag> fwiw i'm also trying out mueval for the same purpose, but am getting an error it can't find an instance of Show (since it prints the output by default) even though i have "deriving (Show)" on the return value of the functions i've been testing
18:20 <sphinxo> lyxia: is that as pointfree?
18:20 <sphinxo> oops yes
18:21 <sphinxo> sorry was not passing in arg correctly
18:21 alexbiehl joined
18:22 <maerwald> s asi xD
18:22 simukis__ joined
18:23 maarhart joined
18:23 atomi joined
18:24 Kundry_Wag joined
18:25 <sophiag> pikajude: thanks for that function! i think i can get the hang of working with these ASTs based on that :)
18:25 <pikajude> cool
18:25 <sophiag> the other thing confusing me though is i need to parse lambdas, but i get an error "lexical error in string/character literal at character ' '"
18:26 <pikajude> that is confusing
18:26 <pikajude> what's the code
18:26 <sophiag> that's just from trying something like "parseExp "(\x -> x == 0)""
18:26 marsam joined
18:26 <pikajude> oh you probably need \\ then
18:27 <sophiag> oh
18:27 <pikajude> because \x isn't valid in a string unless it's followed by some hexadecimal
18:27 <sophiag> ah of course
18:27 <pikajude> > "\x27"
18:27 <lambdabot> "'"
18:27 <pikajude> unlucky that you're using the variable name `x`, the error message probably would have been more helpful otherwise
18:27 <sophiag> or actually i thought a backslash was for using quotes?
18:27 <pikajude> backslash is for escaping things
18:28 <sophiag> right. and because i used the \x it was throwing an error seeing the space
18:28 <sophiag> thanks, i never would have put that together
18:28 tomphp joined
18:30 <sophiag> i seem to need a double slash for any variable actually
18:30 robertkennedy joined
18:30 ompaul joined
18:30 <pikajude> because you're escaping the \
18:31 <sophiag> makes sense
18:31 <pikajude> "\\" is how you write \ in a string
18:31 freusque joined
18:32 niteria joined
18:35 <monochrom> The real horror begins when you need to write in Haskell string literal a string that first goes through a unix shell and then to the grep program, and you need grep to looking for the backslash character (literally) followed by the letter n, because you're searching for \n in C source code.
18:36 <koala_man> one of the many reasons why system(3) semantics must die
18:36 Zialus joined
18:36 <nitrix> Or executing a system command which is a windows program that connects to a linux machine to run a bash script there with arguments.
18:37 <nitrix> I remember some nasty '"\'\\\"\\"'"\''\""" nonsense.
18:37 <koala_man> that sounds even worse since Windows processes try to second guess argv
18:38 <nitrix> It's also when I realised that Haskell's ecosystem is missing a great SSH client library.
18:38 <nitrix> (Native)
18:40 pmade_ joined
18:41 curious_corn joined
18:42 ccomb joined
18:43 sigmundv_ joined
18:44 ozgura joined
18:44 johnw joined
18:45 augur joined
18:45 Berra joined
18:48 wraithm joined
18:49 sypwex joined
18:49 peterbecich joined
18:50 sssilver joined
18:50 <srk> indeed
18:51 zcourts joined
18:51 <srk> propellor uses socket to talk to ssh client
18:51 robkennedy joined
18:52 agjacome joined
18:52 Gurkenglas_ joined
18:53 <cocreature> lpsmith: good point. I think I got a bit further with the builtin parsers in hasql than I got with the builtin ones in postgresql-simple. postgresql-simple is definitely more extensible but writing parsers is really annoying because you need to take escaping in account it gets messy really quickly :)
18:53 sypwex joined
18:54 <cocreature> lpsmith: hasql is mostly bound by the limitations of the binary protocol afaik
18:54 connrs joined
18:55 tomphp joined
18:56 <Jello_Raptor> hey all, I need a propagator library and the only one i can find is ekemett's half finished one. I suspect I'll have to write one myself, any suggestions on papers to read to catch up with useful PL theory? I've got Alexi Radul's thesis, the Nominal Adaption paper, and the Observable sharing paper. (latter two from reading ek's code)
18:56 mudri joined
18:57 <Jello_Raptor> oh
18:57 <Jello_Raptor> edwardk: ping ^
18:58 <Jello_Raptor> (it doesn't help that I've been doing electrical engineer for two years and have fallen super behind on PL stuff that hasn't been posted to /r/haskell :/ )
18:59 sypwex joined
18:59 <sophiag> pikajude: i'm trying to use one function to parse several types of lists, but am not sure how exactly to do it correctly. would you mind taking a look? http://lpaste.net/353983
18:59 zcourts_ joined
19:00 drewr joined
19:00 <pikajude> well this kinda looks like it's replicating the functionality of what an AST does
19:00 <nitrix> foo :: Relation a -> (a -> Relation b) -> Relational b
19:00 <nitrix> :: n a -> (a -> n b) -> m b
19:01 <pikajude> sophiag: why do you have parseList returning Maybe [HList]
19:01 <nitrix> Is there a name or a known idiom for this? I have a type that can only be used by a given monad.
19:01 yellowj joined
19:02 kylepotts joined
19:02 <sophiag> pikajude: well i have that type so i can have a record take lists of multiple types. i suppose you're saying i should just write three different functions to read the ASTs since they're already delimited by type?
19:02 mmachenry joined
19:02 mkoenig joined
19:02 <pikajude> well at the moment actually i'm asking why you're returning possibly a list of lists
19:02 <pikajude> which is what Maybe [HList] would be
19:02 <nitrix> Seems like I can decompose this further to: n a -> (a -> n b) -> n b, n b -> m b ?
19:03 <nitrix> Maybe n needs to be a monad.
19:03 <sphinxo> What's the most efficient way to store [(A,B)] so that I have a function A -> B and B -> A
19:03 Jackneill joined
19:03 <sophiag> pikajude: you realize that's not HList from the library, right? it's just an adt i slapped together that's in the paste
19:04 <pikajude> uh huh
19:04 <sphinxo> like a map that I can lookup both ways
19:04 <sophiag> oh i see what you're saying tho. it should just be "Maybe HList"
19:04 <pikajude> but HList still contains a list
19:05 Zialus joined
19:05 guampa joined
19:06 zcourts joined
19:07 <lyxia> sphinxo: bimap
19:07 <sphinxo> thanks
19:07 <sophiag> pikajude: right. it should be the same as [String], [Char], and [Int]
19:08 Kundry_Wag joined
19:08 <sphinxo> anything I can do if I know the values will never change? lyxia
19:08 <sphinxo> it's just really a lookup table
19:08 <sphinxo> instead of two functions that pattern match
19:09 <nitrix> sphinxo: https://hackage.haskell.org/package/bimap-0.3.2/docs/Data-Bimap.html
19:09 <nitrix> sphinxo: Something like this?
19:10 <sphinxo> Yeah like that, was just wondering if there was anything more optimal since the values will never change at runtime
19:10 zcourts_ joined
19:10 <nitrix> sphinxo: Maybe you'd want to implement a Bihash instead.
19:10 <nitrix> For near O(1) lookups instead of O(log n)
19:11 bgamari left
19:11 <sphinxo> aToB a = case a of AVariant1 => B1, AVariant2 => B1
19:12 Sh4rPEYE joined
19:12 <sphinxo> bToA b = case b of B1 => AVariant1, B2 => AVariant2
19:12 <sphinxo> ( if I write the aToB function correctly )
19:12 Claudius1aximus joined
19:13 <sphinxo> *wrote
19:13 <lyxia> looks like a trie
19:13 <sphinxo> how so?
19:14 HoierM joined
19:14 <lyxia> I mean a generalized tree like it appears in http://hackage.haskell.org/package/MemoTrie-0.6.7/docs/Data-MemoTrie.html
19:14 <sphinxo> ahh awesome
19:15 <lyxia> http://hackage.haskell.org/package/generic-trie-0.3.0.2/docs/Data-GenericTrie.html
19:15 cmsmcq joined
19:16 JeanCarloMachado joined
19:16 Lord_of_Life joined
19:17 <Hi-Angel> Does "fmap print (return 2)" works for anyone? For me it doesn't :/ Besides, the piece of code "fmap print arg2 >>" is a real hog, it uses 10Gb for no reason D:
19:17 oisdk_ joined
19:17 marsam joined
19:17 <monochrom> @type fmap print (return 2)
19:17 <lambdabot> Monad f => f (IO ())
19:18 <Hi-Angel> Well, it should print "2"
19:18 <Hi-Angel> Or anything in the monad
19:18 <monochrom> How do you know?
19:18 <Hi-Angel> Because it's print
19:18 <boxscape> depends on the Monad f, doesn't it?
19:18 <monochrom> but there is also fmap, are you ignoring it?
19:19 <edwardk> Jello_Raptor: sorry, spent the last year sick and didn't get much done on the propagator front
19:19 <monochrom> Also, I just tried it in GHCi, nothing happens, and no consuming 10GB memory.
19:19 <Hi-Angel> I don't understand :( How can I print a monad wrapped value
19:19 <boxscape> which monad does ghci pick if you type "return 2"?
19:20 <boxscape> (without the fmap print I mean)
19:20 <Hi-Angel> monochrom: it's in the other code, the thing is that this single line of code takes 10Gb in profiling, and removing the line makes it run easily
19:20 fizbin joined
19:20 <monochrom> I don't actually know, boxscape. However, I get 2 on its own line as output. Maybe IO.
19:20 <boxscape> hm, ok
19:20 dylukes joined
19:21 <mizu_no_oto_work> @type sequence (fmap print (return 2))
19:21 <lambdabot> (Monad t, Traversable t) => IO (t ())
19:21 <dylukes> Greetings!
19:21 <monochrom> OK, Hi-Angel, have you considered the possibility that the other 99% of your code is the cause?
19:21 <dylukes> So, I'm exploring writing a molecular modeling viewer type program in Haskell...
19:21 <dylukes> and FRP seems a good fit for managing the various time dependent and interdependent attributes of the scene.
19:21 <mizu_no_oto_work> Hi-Angel: ^ that works if your monad is also traversable
19:21 <dylukes> Any suggestions on a FRP library that is *fast*?
19:21 <Hi-Angel> monochrom: yes, so I removed the line to check it out, and turns out this line is the cause
19:21 <sphinxo> I'm not sure the memotrie operates on different types? http://lpaste.net/7001204074422992896 <- I want to get rid of the duplication here
19:21 ew_ joined
19:22 <monochrom> OK, problem solved?
19:22 <dylukes> Doesn't have to be fantastically complex. RxJs equivalent would be plenty.
19:22 <dylukes> Rx*
19:22 <ew_> Hello people, https://www.docdroid.net/YLuNgmx/test-equiv-profile.pdf.html
19:22 <Hi-Angel> mizu_no_oto_work: I have a simple "IO Double" that I need to print
19:22 <lyxia> sphinxo: It can be used as an alternative to Map in a Bimap.
19:22 <ew_> Look at my pretty exponential memory graphs
19:22 <Hi-Angel> mizu_no_oto_work: It's not traversable
19:23 <mizu_no_oto_work> Hi-Angel: If you have an IO Double, you can say "myIODouble >>= print"
19:23 Heero_ joined
19:23 <Hi-Angel> mizu_no_oto_work: you're genious!!
19:23 <mizu_no_oto_work> or join (fmap print (return 2)), if you prefer
19:23 <dylukes> The only thing is, I'm not sure how to nicely use FRP in a dynamic way.
19:24 <mizu_no_oto_work> Not sure why you'd prefer the second one, though
19:24 <dylukes> Euphoria/Elerea seem interesting to this end.
19:25 akermu joined
19:25 spinda joined
19:25 <mizu_no_oto_work> Hi-Angel: and if you have a function that takes some value and generates an IO Double, you can use "print <=< mkIODouble" to compose them
19:25 <sphinxo> How can I remove the duplication here: http://lpaste.net/7001204074422992896
19:25 <Hi-Angel> Thank you
19:26 psniper joined
19:26 <boxscape> looks like ghci doesn't print the result whenever the type is `IO ()' (nothing new about that), or `IO (IO ())', or `IO (IO (IO ()))', and so on
19:26 curious_corn joined
19:26 <augur> anyone know how to make Stack REPL less verbose?
19:27 <boxscape> I would've expected it to try to print it in every case except the first
19:27 <boxscape> (resulting in a missing instance for Show)
19:28 isacloud joined
19:28 billstclair joined
19:28 feltnerm joined
19:29 <mnoonan> boxscape: weirdly, it prints nothing for IO (IO Int) either
19:29 <boxscape> oh
19:29 <c_wraith> boxscape, ghci's heuristic is 1) IO () means don't show. 2) unifies with (Show a) => IO a means show the resulting a value. 3) don't print anything
19:30 <c_wraith> boxscape, IO doesn't have a show instance, so nothing is shown in the case of nested IO
19:31 <boxscape> ok, that makes sense
19:31 Purlox joined
19:31 marcopullo joined
19:31 FULLC00L666 joined
19:31 <boxscape> but wait, how can you show values of type IO Int if IO doesn't have a show instance
19:31 <boxscape> or does ghci do special magic in that case
19:32 <* FULLC00L666> how to get free Uber Rides. https://youtu.be/YGBscwzn_hU :)
19:32 <boxscape> looks like it
19:32 was kicked by monochrom: FULLC00L666
19:32 <boxscape> oh
19:32 <dylukes> Also, what's the canonical way to build a package from hackage (say, a package of examples) with stack?
19:32 <boxscape> I misread your heuristic
19:32 <dylukes> copy source, stack init, etc?
19:32 <c_wraith> boxscape, it's essentially rewriting to >>= print
19:32 <boxscape> ok
19:33 <sphinxo> sphinxo: It can be used as an alternative to Map in a Bimap.
19:33 albertus1 joined
19:33 <sphinxo> what do you mean lyxia? sorry
19:33 <mizu_no_oto_work> Hi-Angel: the problem with "fmap print (return 2)" is that you end up with an "IO (IO ())", which isn't really the type you want. You can think of that as being a computation that, when run, returns a computation that, when run, returns unit. join will take an (IO (IO a)) and turn them into an (IO a). >>= and <=< are equivalent to fmap and join (in that "a >>= f = join $ fmap f a " and "join a = a >>= id", so you can define whichever's
19:33 <mizu_no_oto_work> easiest directly and derive the missing function)
19:33 <c_wraith> boxscape, non-IO is just handled with an implicit print. all the special cases are IO types.
19:33 <boxscape> right, ok. Thank you
19:34 fakenerd_ joined
19:34 <mizu_no_oto_work> As a side question, in what sense is codata "co-" to data?
19:36 <monochrom> Whereas "data" is short for "initial, algebraic" and means you focus on constructors, "co-data" is short for "final, co-algebraic" and means you focus on destructors or generators.
19:36 marsam joined
19:36 marvin2 joined
19:37 <dylukes> Hm.
19:37 <dylukes> What to do when stack init can't select a snapshot?
19:37 <dylukes> says "GLFW not found" for all of them :\.
19:37 <dylukes> Idk why GLFW causes an issue.
19:37 <monochrom> For example, given a "codata list", you speak of destructing it into a head and a tail, and you start talking of the possibility that you can destruct the tail and so on ad infinitum, maybe the co-data list doesn't end.
19:38 peteretep joined
19:38 iphy joined
19:39 drewr` joined
19:39 <monochrom> (I don't like "destruct". Maybe "deconstruct" is less violent and more hip. But also harder to type. :) )
19:39 <dolio> Observe.
19:40 <mauke> nstruct
19:40 bodisiw joined
19:40 canta1 joined
19:40 <monochrom> Oh! Yes "obersve" is so much better.
19:40 chrzyki joined
19:41 drewr` joined
19:41 dgpratt_ joined
19:41 codedmart joined
19:41 <dylukes> monochrom what happens when you "observe" and obtain a superposition of states,
19:42 <dylukes> and have to specify a gauge to map that superposition to a plain value?
19:42 <dylukes> Is this the birth of quantum codata?
19:42 <monochrom> Wait, I thought the observing kills the superposition.
19:42 ekinmur joined
19:42 <dylukes> That's interpretation.
19:42 <dylukes> The concept of "observer" is not in most conversation well defined.
19:43 wraithm joined
19:43 implementation_ joined
19:43 <geekosaur> ob https://www.sciencedaily.com/releases/2017/03/170324192503.htm
19:43 <dylukes> monochrom: the uncertainty principle is amusing. When you try to understand the math from common sense, it makes no sense.
19:44 deepfire` joined
19:44 deepfire joined
19:44 <dylukes> When you accept it a priori mathematically as a necessity, it makes perfect sense.
19:44 foldu[m] left
19:44 <sophiag> what exactly is the purpose of the BooleanFormula type? i could use something very much like that, except it only allows AND and OR and not negation or equality so it seems i'm stuck using lambdas, which have a more complicated AST
19:44 <dylukes> monochrom: There's an often repeated conflation of the observer effect and the uncertainty principle.
19:45 marsam joined
19:45 <dylukes> The observer effect states that you can't observe a physical system without disrupting it.
19:45 <dylukes> The uncertainty principle is much more fundamental.
19:45 paroxp joined
19:45 Kundry_Wag joined
19:46 TheWizardTower joined
19:47 rgrinberg joined
19:47 <dylukes> monochrom: https://hackage.haskell.org/package/QIO-1.3/docs/QIO-QioSyn.html#t:QIO
19:47 eschnett joined
19:47 <dylukes> apparently this has been done already haha.
19:48 canta joined
19:48 bjz joined
19:49 orbifx joined
19:49 avdi joined
19:49 Kundry_Wag_ joined
19:49 mavihs joined
19:49 ubsan_ joined
19:50 <nshepperd_> When you observe something, you become a superposition
19:50 ggherdov joined
19:50 fuzzy_id joined
19:50 certainty joined
19:50 jfokkan__ joined
19:50 <nshepperd_> monochrom: in what category are data and codata initial/final?
19:50 <dylukes> instructions unclear, path integrated genitals through ceiling fan.
19:50 chenshen joined
19:51 asmyers joined
19:51 <monochrom> Given a functor F, have a category of F-algebras, then "data" based on that F is the initial algebra in that category.
19:51 locallycompact joined
19:52 <dylukes> I still haven't really connected the semantics of F-algebras to data structures :\.
19:53 <monochrom> And for the other one, I forgot whether it's the category of F-algebras again, or you need a category of F-coalgebra, but either way you look at the final object for "co-data"
19:53 <dylukes> monochrom but what about F-coalgebras?
19:53 <ertes> dylukes: do you understand the idea that recursive data structures can be represented as fixed points of flat ones?
19:53 <dylukes> Yup.
19:53 <dylukes> So wait,
19:54 <monochrom> Oh w00t I do know of a thick paper rabbit hole I can send you down.
19:54 <dylukes> What is the word for such a structure ertes?
19:54 <dylukes> I know what it is but I want to be precise in my wording.
19:55 <dylukes> I usually just think of them as "factored out".
19:55 sedeki joined
19:55 <dylukes> or free.
19:55 <dylukes> in some sense.
19:55 <ertes> dylukes: "data structure"? good question
19:55 <dylukes> (imprecise sense*)
19:55 <dylukes> No I mean.
19:55 <monochrom> http://www.cs.ru.nl/B.Jacobs/PAPERS/JR.pdf "a tutorial on (co)algebraic and (co)induction"
19:55 <dylukes> I'm missing keywords haha.
19:56 <monochrom> it's how I became a lost lamb. :)
19:56 kylepotts joined
19:57 sypwex joined
19:57 nick_h joined
19:57 <monochrom> Interesting data structures are seldom inital algebras or final coalgebras.
19:58 coot joined
19:58 vlnts joined
19:58 mmhat_ joined
19:59 <monochrom> For example cons-lists and binary trees are initial algebras, but they never satisfy our insatiable quest for performance (even theoretical big-O performance). No, we must inflict extra restrictions like "search tree" and "balanced" and "finger" etc.
20:00 Lord_of_Life joined
20:00 mojjo joined
20:01 <dylukes> monochrom trying to remember what the word for this is....
20:01 <dylukes> okay so
20:01 <dylukes> "data List a = Nil | List a" vs "data List f a = Nil | f a"
20:01 <dylukes> where the latter can be fixed to get the former.
20:01 a3Dman joined
20:02 <monochrom> Yes.
20:02 <dylukes> What is the term for the latter, with the f?
20:02 <ski> syntax error
20:02 <dylukes> ayyy.
20:02 <kadoban> ski: xD
20:02 <monochrom> It doesn't often get called a name, but when it does, people say "the base functor".
20:03 <jle`> that's what it's called in the recursion-schemes library at least
20:03 <ertes> dylukes: [a] ≃ Fix ListF -- solve for ListF (you were close)
20:03 <ski> .. except it's not unique
20:03 <dylukes> ertes my memory is fuzzy haha.
20:03 cdg joined
20:03 <jle`> er i meant that as "i know that, at least"
20:03 <jle`> http://hackage.haskell.org/package/recursion-schemes-5.0.1/docs/Data-Functor-Foldable.html
20:03 <dylukes> I also do not know how to solve for ListF there.
20:03 <dylukes> Well, I do.
20:03 <monochrom> But more often a paper simply says "Let F be a functor. We now talk about the F-algebras." and therefore it can just keep saying "F".
20:03 <dylukes> It's just a congruence I suppose.
20:03 <dylukes> I don't know the rules though.
20:03 sphinxo joined
20:04 <ski> ListF a r = 1 + a + a^2 * r
20:04 <dylukes> Wait what, why is there a characteristic polynomial?
20:04 <dylukes> ;___;
20:04 <jle`> that's just the definition of ListF that you gave
20:04 <dylukes> monochrom What is the relationship (if any) between "base functor" and initial algebras?
20:05 <dylukes> ski: I'm not sure where the a^2 term came from...
20:05 <monochrom> The relationship is exactly the definition of "initial algebra".
20:05 <dylukes> Ok, that's what I thought :).
20:05 <monochrom> I'm going to pull your leg but:
20:06 MindlessDrone joined
20:06 <dylukes> *poot*
20:06 <monochrom> catmorphism :: (F r -> r) -> Meow F -> r
20:06 oish joined
20:06 <ertes> dylukes: and i was being stupid: [a] ≃ Fix (ListF a)
20:06 <ertes> of course =)
20:06 <ski> [a] ≅ μ r. ListF a r = μ r. 1 + a + a² · r
20:06 <ski> also
20:06 <ski> [a] ≅ μ r. 1 + a · r
20:06 <ski> <ski> .. except it's not unique
20:07 <dylukes> I'm not familiar with the notation.
20:07 <dylukes> μ r. in particular.
20:07 <ertes> dylukes: type-level fix
20:07 <monochrom> Now I have to think up the dual joke for anamorphism.
20:08 <ertes> Fix (\r -> 1 + a * r)
20:08 <ski> ⌜μ r. ⋯r⋯⌝ is ⌜Mu (λ r. ⋯r⋯)⌝
20:08 <dylukes> Wait, how does ListF a r ⇒ 1 + a + a² · r?
20:08 <dylukes> I get the basic idea but where'd the a^2 term come from?
20:08 <ski> ⌜x + y⌝ is ⌜Either x y⌝
20:08 <ertes> dylukes: what is a list?
20:08 mjolnir joined
20:08 <ski> ⌜x · y⌝ is ⌜(x,y)⌝
20:08 <dylukes> Oh right.
20:08 <ski> ⌜x²⌝ is ⌜(x,x)⌝
20:08 <ertes> it's either 1 (empty), a (one item), a² (two items), a³ (three items) or …
20:09 <dylukes> data List = Nil | Cons a (List a) ⇒ 1 + a * (???)
20:09 <ertes> data ListF a x = Nil | Cons1 a x | Cons2 a a x
20:09 mjolnir left
20:09 <ertes> no
20:09 <jle`> dylukes: in haskell, List a = Nil | Cons a (List a)
20:09 <ertes> data ListF a x = Nil | Singleton a | Cons2 a a x
20:09 <ski> yes
20:09 <dylukes> the missing "a" was a typo.
20:09 <jle`> dylukes: so L x = 1 + (x * L x)
20:10 <dylukes> Wat, you've got a singleton and a cons now?
20:10 <ertes> dylukes: this ListF is also a valid solution
20:10 <dylukes> I was only considering a much simpler list.
20:10 <jle`> we're expanding out your definition
20:10 <dylukes> jle` right then solve the recurrence?
20:10 <jle`> since it's recursive
20:10 <ertes> dylukes: ski is just proving their point that there are infinitely many valid ListFs
20:10 Kundry_Wag joined
20:10 <jle`> L(x) = 1+ x L(x)
20:10 <dylukes> Sorry getting many explanations at once in slightly different syntax.
20:10 <dylukes> Been a long day :p.
20:10 <ski> dylukes : the point is that there's *more* than one way to get a ⌜ListF a⌝ such that ⌜[a]⌝ is iso to ⌜Fix (ListF a)⌝
20:10 <jle`> L(x) = 1 + x * (1 + x*L(x))
20:10 sypwex joined
20:10 <dylukes> ⌜?
20:11 <jle`> L(x) = 1 + x * (1 + x*(1 + x*L(x)))
20:11 <jle`> so after three expansions, L(x) = 1 + x + x*2 + x*3L(x)
20:11 <ski> dylukes : one being ⌜ListF a r = 1 + a · r⌝, another being ⌜ListF a r = 1 + a + a² · r⌝
20:11 <jle`> er, 1 + x + x^2 + x^3 L(x)
20:11 <ertes> dylukes: but in practice you would of course use this one: data ListF a x = Nil | Cons a x
20:11 <dylukes> ski Oh I wasn't following that at all.
20:11 <jle`> which says, "a list is either nil (1), or a single item x, or two x's, or three x's and another list
20:12 <dylukes> I'm getting a bit overloaded by multiple explanations of different things at once, tbh.
20:12 <* ski> nods
20:12 <jle`> alright i'll drop out :)
20:12 <dylukes> I was trying to just suss out my own understacking/lack thereof.
20:12 <dylukes> Of one concept.
20:12 <dylukes> I also don't know this syntax.
20:12 <dylukes> ⌜⌝?
20:12 <ski> that's just quotation marks
20:12 <dylukes> Oh. Never seen those before.
20:13 <dylukes> ski ertes Ok I follow.
20:13 <boxscape> the symbols in unicode are called "top left corner" and "top right corner"
20:13 <dylukes> So what you're saying is (correct me if I'm wrong)
20:13 <ertes> dylukes: alright… now we have a ListF such that: [a] ≃ Fix (ListF a)
20:13 <dylukes> that the recurrence that defined ListF has countable solutions?
20:14 <ski> countably many different solutions, yes
20:14 <dylukes> That said,
20:14 <dylukes> Cons2 a a x ⇒ Cons a (Cons a x)
20:14 <ertes> dylukes: exercise: look at this function: listCata :: (ListF a r -> r) -> Fix (ListF a) -> r
20:14 marsam joined
20:15 <dylukes> It seems like only the first solution provides (in a very non-rigorous way of putting it) a basis for lists of arbitrary length.
20:15 <ertes> dylukes: do you see how this function might be equivalent to foldr?
20:15 <dylukes> Lemme stare at it one moment.
20:15 curious_corn joined
20:15 kosorith joined
20:16 <ertes> dylukes: (it doesn't have to be, but of course i'm suggesting that one could write a function with this signature that is equivalent to foldr)
20:16 <dylukes> I'm not sure I entirely see it.
20:16 <dylukes> Would you mind elaborating a little bit?
20:16 <dylukes> I see generally, but not the specific correspondence.
20:16 <ertes> ListF a x ≃ 1 + a*x
20:16 <ertes> right?
20:16 <dylukes> Right.
20:17 <* ski> . o O ( ⌜[a] ≅ ∀ r. (ListF a r → r) → r⌝ )
20:17 mson joined
20:17 <ertes> listCata's type is isomorphic to: ((1 + a*r) -> r) -> [a] -> r
20:17 wraithm joined
20:17 <ertes> still good?
20:18 <dylukes> Yeah, I was actually just typing that out myself haha.
20:18 thallada joined
20:18 <dylukes> I'm trying to parse what (ListF a r -> r) means exactly.
20:19 <dylukes> I'm not clear on, concretely, what returning r means.
20:19 <ertes> ≃ r^(1 + a*r) -> [a] -> r ≃ r^(a*r) * r -> [a] -> r ≃ r^(a*r) -> r -> [a] -> r ≃ (a*r -> r) -> r -> [a] -> r ≃ (a -> r -> r) -> r -> [a] -> r
20:19 <* ski> . o O ( ⌜(x + y) → r ≅ (a → r) · (y → r)⌝ )
20:19 <ertes> write this into your editor and lay it out on multiple lines to see it more clearly
20:19 <* ski> . o O ( ⌜0 → r ≅ 1⌝ )
20:19 epsilonhalbe joined
20:20 <* ski> . o O ( ⌜(x · y) → r ≅ x → (y → r)⌝ )
20:20 <* ski> . o O ( ⌜1 → r ≅ r⌝ )
20:20 sypwex joined
20:20 <dylukes> Ok, I follow that.
20:20 <dylukes> I was thinking that before, expanding with exponentiation.
20:21 <dylukes> what I'm not clear on is what r is.
20:21 <ski> (er, ⌜x⌝, not ⌜a⌝, there)
20:21 <dylukes> Oh wait, my bad.
20:21 <dylukes> I was thinking of r as * → *
20:21 <dylukes> for some reason.
20:21 <dylukes> Now I see it.
20:21 <dylukes> That explains my confusion!
20:21 <dylukes> I need to actually get back into haskell properly. Back when I was here so many years ago I was a greenhorn mathematically.
20:22 <dylukes> I still am,
20:22 <dylukes> but at least I have some degrees now.
20:22 <ertes> dylukes: ok, here is a hypothesis: *any* list function can be written in terms of foldr… would you believe that?
20:22 <dylukes> Despite my algebraic intentions I took a very long detour through analysis.
20:22 <dylukes> Ended up in graduate level partial differential equations. That was fun.
20:22 <dylukes> I think I'm ready for some algebra palette cleanser though.
20:22 Rodya_ joined
20:22 ramzifu joined
20:22 <dylukes> ertes Well yeah.
20:23 <dylukes> foldr is, in some sense, uh... it matches the structure of lists.
20:23 <ertes> dylukes: so would it be fair to say that foldr captures the structure of lists entirely?
20:23 <ertes> yeah, exactly
20:23 <dylukes> Again, imprecise wording but I do get that.
20:23 <nitrix> It captures more than lists afaik.
20:23 <ertes> so here is another way to define lists: type List a = forall r. (a -> r -> r) -> r -> r
20:24 <ertes> (the church encoding for lists)
20:24 <dylukes> It could also capture any arithmetic on the naturals I would imagine.
20:24 ystael joined
20:24 <ertes> well, naturals are just [()] =)
20:24 <dylukes> Er wait, thinking of something else.
20:24 <dylukes> But yes.
20:24 <nitrix> ertes: Funky. That looks kinda like ShowS.
20:24 curious_corn joined
20:24 <dylukes> Can you give any other examples of this phenomenon?
20:25 <dylukes> Or foldr capturing the structure of lists, for other structures?
20:25 <dylukes> And what I would call this?
20:25 <dylukes> Concepts are great, but they're better with names so I can do research later..
20:25 <* ski> . o O ( ⌜flip listCata ∷ Mu (ListF a) → (∀ r. (ListF a r → r) → r)⌝ )
20:25 <Sonolin> wow nitrix, mind = blown
20:25 <ertes> dylukes: data TreeF a x = Leaf a | Branch a x x
20:25 <* ski> . o O ( ⌜λ m ↦ m In ∷ (∀ r. (ListF a r → r) → r) → Mu (ListF a)⌝ )
20:25 <ertes> whoops
20:25 <ertes> dylukes: data TreeF a x = Leaf a | Branch x x
20:26 <ertes> dylukes: type Tree a = forall r. (r -> r -> r) -> (a -> r) -> r
20:26 <dylukes> I follow.
20:26 <ertes> more generally:
20:26 <nitrix> > shows 42 "x" -- Sonolin constant time concatenation :P
20:26 <lambdabot> "42x"
20:26 dylukes2 joined
20:27 <dylukes2> Hi.
20:27 <dylukes2> On mobile.
20:27 <ertes> type Mu f = forall r. (f r -> r) -> r
20:27 <ski> dylukes : "And what I would call this?" -- "catamorphism"
20:27 <dylukes> That's what I thought haha.
20:27 <dylukes> I thought it was called a bird.
20:27 <dylukes> ;)
20:27 <ertes> this is the *algebraic* representation, but there is another one
20:27 mjolnir joined
20:27 <ski> as in Richard Bird, of "Algebra of Programming", together with Oege de Moor ?
20:28 skeuomorf joined
20:28 <dylukes> Not familiar with Oege de Moor.
20:28 <dylukes> ertes what is the other one?
20:28 Rodya__ joined
20:28 <dylukes> combinatorial?
20:28 <ertes> data Nu f = Nu (s -> f s) s
20:28 <ertes> the coalgebraic one
20:29 <ertes> the idea is that unfoldr captures the structure of lists just as well as foldr
20:29 ExpHP joined
20:29 <dylukes2> Hmm.
20:29 <dylukes2> I guess yeah, unfoldr illustrates how to generate a list.
20:29 <ski> dylukes : also see "To Dissect a Mockingbird: A Graphical Notation for the Lambda Calculus with Animated Reduction" by David C Keenan in 1996-08-27 (through 2014-04-01) at <http://dkeenan.com/Lambda/> for more birds
20:29 <ertes> exactly
20:29 <ertes> read "s" as "state" =)
20:29 <dylukes2> Actually unfoldr seems like it would intuitively make more sense in general.
20:29 <dylukes2> I'm just very used to folding
20:30 <dylukes2> Ski: word
20:30 kappter joined
20:30 <* ski> hands ertes an ⌜∃⌝
20:30 <ertes> whoops, yeah
20:30 <ertes> data Nu f = forall s. Nu (s -> f s) s
20:30 <dylukes2> ertes: so is a PRNG basically just an unfold?
20:30 <dylukes2> :p
20:30 azahi joined
20:30 <ertes> it's a list =)
20:31 <ertes> you can represent it as a fold or as an unfold
20:31 <jle`> :t unfoldr
20:31 <lambdabot> (b -> Maybe (a, b)) -> b -> [a]
20:31 <dylukes2> How would you represent it as a fold?
20:31 <dylukes2> I'm in the mindset of representing some things as folds and others as unfolds.
20:31 <dylukes2> I'm not entirely clear on their equivalence.
20:32 wraithm joined
20:32 <ski> @type System.Random.split
20:32 <lambdabot> RandomGen g => g -> (g, g)
20:32 arpl left
20:33 <ertes> lrandoms g' f z = let (x, g) = random g' in f x (lrandoms g f z)
20:33 <ertes> dylukes2: ^
20:33 <jle`> > unfoldr (\g -> Just (System.Random.Split g)) (mkStdGen 34234)
20:33 <lambdabot> error:
20:33 <lambdabot> Not in scope: data constructor ‘System.Random.Split’
20:33 <lambdabot> Perhaps you meant one of these:
20:33 <ertes> type List a = forall r. (a -> r -> r) -> r -> r
20:33 <ertes> lrandoms :: (Random a, RandomGen g) => g -> List a
20:33 <ski> `z' is dead
20:34 sypwex joined
20:35 <ertes> lrandoms g0 f _ = let go g' = let (x, g) = random g' in f x (go g) in go g0
20:35 <ertes> ski: better? =P
20:35 <dylukes2> ertes I'm not sure I follow the relationship between ListF and Mu
20:35 <dylukes2> Abstractly yes
20:35 <dylukes2> But mathematically no
20:35 <dylukes2> They seem fundamentally different.
20:36 <ertes> incoming spam…
20:36 <ertes> data ListF a x = Nil | Cons a x
20:36 <ertes> type List a = forall r. (ListF a r -> r) -> r -> r
20:36 <ertes> lrandoms g0 f _ = let go g' = let (x, g) = random g' in f (Cons x (go g)) in go g0
20:36 <ski> ⌜Mu F⌝, aka ⌜μ r. F r⌝, is the least ⌜r⌝ which is iso to ⌜F r⌝
20:36 <monochrom> Not much relationship except we use Mu on ListF, "Mu ListF"
20:36 <ski> ⌜Nu F⌝, aka ⌜ν r. F r⌝, is the greatest ⌜r⌝ which is iso to ⌜F r⌝
20:36 <ertes> oops
20:36 b4ff3r joined
20:36 <ertes> that was nonsense
20:37 <MarcelineVQ> ski: you've upgraded your quotation marks
20:37 <ertes> type List a = forall r. (ListF a r -> r) -> r
20:37 <ertes> lrandoms g0 f = let go g' = let (x, g) = random g' in f (Cons x (go g)) in go g0
20:37 <ski> MarcelineVQ : only with unicode
20:37 <ertes> dylukes2: ^
20:37 deepfire` joined
20:37 <ski> (and it's not new)
20:37 <dylukes2> Er
20:37 deepfire joined
20:37 <dylukes2> I'm a bit confused by the PRNG thing
20:38 dopey_ joined
20:38 <dylukes2> I just mentioned that off hand.
20:38 <ertes> dylukes2: can you write the empty List?
20:38 <dylukes2> Nil
20:38 <dylukes2> :p
20:38 <ertes> no
20:38 <ertes> not the empty ListF, but the empty List
20:38 <dylukes2> Isn't that still Nil? Or do you want []?
20:38 <ertes> no, Nil is a type error
20:39 <dylukes2> I don't think we're on the same page.
20:39 <ertes> nil :: List a
20:39 <ertes> nil = _fillThisIn
20:39 <monochrom> No no, the forall r. (a -> r -> r) -> r -> r version.
20:39 <ertes> remember: type List a = forall r. (ListF a r -> r) -> r
20:39 <monochrom> Or that, yeah.
20:39 <ski> it should have type ⌜∀ a. List a⌝, iow ⌜∀ a r. (ListF a r → r) → r⌝
20:40 <dylukes> I'm still trying to understand the "equivalence" of `data Nu f = forall s. Nu (s -> f s) s' and the algebraic form.
20:41 <monochrom> No, that one is going to be co-algebraic.
20:41 <ertes> dylukes: start by understanding the algebraic form =)
20:41 <ertes> and start that by writing 'nil' ;)
20:41 <dylukes> "[16:27:44] <ertes> this is the *algebraic* representation, but there is another one"
20:41 <dylukes> after that you lost me.
20:41 <dylukes> I wasn't sure what you were trying to illustrate, or misunderstood the destination.
20:42 <monochrom> Yeah we need to go slower.
20:42 <dylukes> I was following fine till then.
20:42 python476 joined
20:43 <dylukes> I just still don't know why you introduced Nu or what you were trying to illustrate with it.
20:43 <ertes> dylukes: i recommend that you ignore that for now
20:43 <dylukes> Ok, haha.
20:44 <ertes> well, i can explain it in prose: a (List a) is a function that takes a (ListF a)-algebra and computes a result from it by feeding it the list elements
20:44 ragepandemic joined
20:44 <ertes> a (ListF a)-algebra is just a function of type (ListF a r -> r), i.e. an object 'r' together with a function of type (ListF a r -> r)
20:45 <ertes> to really understand what this means requires that you implement a few examples
20:45 <python476> hi
20:45 <dopey_> can anyone recommend a guide for calling C functions from haskell code? I have found a number of guides for using the foreign function interface, but nothing recent that steps all the way through compilation. the few articles that I have found with compilation examples seem to be outdated.
20:45 <ertes> start with the simplest: 'nil' =)
20:45 <python476> At a meetup someone mentioned monadic bind, yoneda and something named "cailey"; does this ring (sic) a bell to you ?
20:46 <ertes> python476: the first one is a common haskell concept, the second one is less common, the third i've never heard before =)
20:46 <glguy> python476: http://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor-Cayley.html
20:46 <python476> ertes: thanks, glguy thanks even more
20:46 squotro joined
20:47 Jesin joined
20:48 bennofs joined
20:48 <ExpHP> What the... what on earth is a Pastro!?
20:48 <ExpHP> These look like names out of a Lord of the rings novel: http://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor-Monad.html#t:ProfunctorFunctor
20:49 <ExpHP> (the instances)
20:49 <monochrom> I don't know Pastro. But I know Paw Patrol.
20:49 <python476> I know Castrol
20:49 <ertes> i know Zygohistrol
20:49 <* ski> . o O ( Cryptol )
20:49 <monochrom> haha, what have I done
20:49 wraithm joined
20:49 <python476> and people complain about casual Haskell code..
20:49 dfeuer joined
20:50 simukis__ joined
20:50 asmyers joined
20:50 <dylukes> "a (ListF a)-algebra is just a function of type (ListF a r -> r), i.e. an object 'r' together with a function of type (ListF a r -> r)"
20:50 <Sornaensis> haskell has some of the most comprehensible names imho
20:50 <dylukes> uh wait
20:50 <dylukes> Is it (ListF a r -> r)? Or (ListF a r -> r) together with an object r?
20:50 squotro left
20:50 <ertes> dylukes: yes =)
20:50 kylepotts joined
20:51 <ertes> once you've picked a function of type (ListF a r -> r), you have at the same time picked an 'r'
20:51 <python476> installing stack is a bliss
20:51 <ski> dylukes : it's (for the functor ⌜ListF a⌝) : a pair of a type ⌜r⌝, and a value of type ⌜ListF a r → r⌝
20:51 <monochrom> dylukes, if I write so much as "ListF Int String -> String" then I have already implicitly specified that I want r = String.
20:51 <dylukes> I do understand, vaguely, the relationship between base functor types and expressions, and the fixed (whatever the correct word is) types and evaluations of those expressions.
20:52 <ertes> dylukes: an F-algebra is an object (here: a type) 'a' together with a morphism (F a -> a) (here: a function)
20:52 <ertes> here F = ListF a
20:53 <ertes> of course due to type inference you don't need to specify your pick of 'r'… it will be inferred
20:53 <ertes> (usually at least)
20:54 ExpHP_ joined
20:55 ragepandemic joined
20:55 praduca joined
20:56 <ertes> dylukes: BTW, here is a hint that may help you: there is only one way to write 'nil'
20:56 <ertes> just use the types to guide you
20:58 sypwex joined
20:59 <vlnts> is it considered bad style to not use infix with on, mod etc ?
20:59 <monochrom> No. Either is fine.
20:59 oisdk joined
20:59 <ExpHP_> I think it's a bit confusing; if I saw (div 3) I might misread it as division by 3
21:00 <ExpHP_> but at the same time that sort of stuff is so rare that it's pretty much always a mistake if I ever do see it
21:01 <ExpHP_> er, "that sort of stuff" = "(div 3)"
21:01 <dylukes> One moment ertes, I have to run.
21:01 <michi7x7> > (div 3) 8
21:01 <dylukes> I will come back soon.
21:01 <lambdabot> 0
21:01 <michi7x7> äh?
21:01 <ski> dylukes : in general, for a functor ⌜F⌝, an ⌜F⌝-algebra is a pair ⌜⟨a,c⟩⌝, where ⌜a⌝ is a type and ⌜c⌝ (one can think "construct" or "combine") is a function of type ⌜F a → a⌝
21:01 <dylukes> Thanks for all of your help, all of you :).
21:02 <ski> dylukes : there is a category whose objects are such pairs, and a morphism from ⌜⟨a,c⟩⌝ to ⌜⟨b,d⟩⌝ (with ⌜a⌝,⌜b⌝ types, and functions ⌜c : F a → a⌝,⌜d : F b → b⌝) consists of a function ⌜f : a → b⌝ such that ⌜d ∘ F f = f ∘ c⌝, where ⌜F f⌝ in Haskell terms would be ⌜fmap f⌝. the composition on the left here goes ⌜b ⟵ F b ⟵ F a⌝, while the one on the right goes ⌜b ⟵ a ⟵ F a⌝
21:02 <michi7x7> > 8 `div` 3
21:02 <lambdabot> 2
21:02 <ExpHP_> > (`div` 3) 8
21:02 <lambdabot> 2
21:03 <ExpHP_> Basically, a lot of operators make most sense when curried oer the second argument first
21:03 dfeuer joined
21:03 sssilver joined
21:03 cpup joined
21:04 <monochrom> That is basically failing to see that the other 50% of the people find that the opposite makes most sense.
21:04 CurryWurst joined
21:05 <monochrom> Even within the same person, half of the time they say "substract 5 by 3, divide 6 by 2", and the other half of the time it's "substract 3 from 5, divide 2 into 6".
21:05 <vlnts> I just find it easier reading without infix
21:06 <boxscape> I find it easier typing without infix
21:06 <ExpHP> I can count on two hands all the instances where I've had a single number x, and a bunch of numbers I wanted to subtract from x
21:06 thallada joined
21:06 <monochrom> In fact I just witnessed the Canadian tax forms switch from the latter to the former some 10 years ago.
21:06 zar joined
21:06 <ertes> even GHC has trouble sometimes
21:06 <ertes> > map (- 3) [1,2,3]
21:06 <lambdabot> error:
21:06 <lambdabot> • Could not deduce (Num a0)
21:06 <lambdabot> from the context: (Num (a -> b), Num a)
21:06 <ExpHP> hehe
21:06 <boxscape> :t (`div`)
21:06 <lambdabot> error: parse error on input ‘)’
21:06 CurryWurst joined
21:06 <boxscape> I feel like that should convert it back to prefix form :P
21:07 <Sornaensis> nothx
21:07 <ExpHP> map (flip (-) 3) [1,2,3]
21:07 <ExpHP> > map (flip (-) 3) [1,2,3]
21:07 <lambdabot> [-2,-1,0]
21:07 <ertes> > map (subtract 3) [1,2,3]
21:07 <lambdabot> [-2,-1,0]
21:07 <boxscape> would be much easier if mathematicians hadn't chosen to overload -
21:08 <MarcelineVQ> overload?
21:08 <ertes> (+) vs. negate
21:08 Kundry_Wag joined
21:08 <boxscape> assign two meanings to the same symbol
21:08 <ertes> but mathematicians loooooooooove to overload things
21:08 <boxscape> that is true
21:08 t0by joined
21:09 <monochrom> Did you know they overloaded 0 to no end?
21:09 <ExpHP> MarcelineVQ: one doesn't put a bar over something to indicate a reciprocal
21:09 <ExpHP> oh wait, except material scientists. drat
21:09 CurryWurst joined
21:09 <monochrom> 0 the number (and don't get me started on whether it's nat, int, rational, real, or complex), 0 the vector, 0 the matrix, 0 the function...
21:09 <ertes> well, it's their mempty
21:09 <Sornaensis> :t 0
21:09 <lambdabot> Num t => t
21:10 <ertes> … and rempty and vempty and …
21:10 <Sornaensis> :t (<>)
21:10 <boxscape> to be fair, they say that nat is a subset of rational, which you don't do in programming languages, which means that the 0 really is the same
21:10 <lambdabot> Monoid m => m -> m -> m
21:10 <monochrom> They overloaded it so much, though they don't use 1 for the identity matrix, they do use 0 for the zero matrix.
21:10 <ExpHP> in physics we very much use 1 for the identity matrix
21:10 <ertes> monochrom: huh? i've seen 1 there
21:10 <ExpHP> operator theory and all that shiznaz
21:10 <monochrom> Well yeah the other half of the time they use I
21:11 <boxscape> the current identity matrix notation isn't great either, it differs from country to country. (Or at least from US to Germany)
21:11 <* geekosaur> has seen both; depends on who's doing it and probably what subdiscipline
21:11 jathan joined
21:11 <ertes> i have more trouble with physicists, who don't just overload things, but somehow feel the need to invent their own notation for things that were already there as well
21:11 oisdk_ joined
21:11 <monochrom> whereas for the zero matrix there is no "the other half of the time", it's 0 unanimously.
21:11 <ertes> like that bullshit bra-ket notation they use for vectors
21:11 <ExpHP> ertes: I resemble that statement
21:12 <Sornaensis> have u ever read physicist code?
21:12 <monochrom> I can see the beauty or mnemonic in the bra-ket notation.
21:12 <ExpHP> it's all fortran
21:12 <ExpHP> all of it
21:12 <ertes> no, i don't understand fortran
21:12 <Sornaensis> I think the last time a physicist read about CS may have been 1979
21:12 <ExpHP> all of my colleagues have fortran as the #1 language they want to learn
21:12 <geekosaur> "optimist"
21:12 <hpc> did you hear that microchips have reached parity with vacuum tubes?
21:13 tangled_z joined
21:13 <ertes> monochrom: beauty? all it does is make the math more mysterious, but physicists love mysteries, too
21:14 <boxscape> physicist code https://en.wikipedia.org/wiki/File:FortranCardPROJ039.agr.jpg
21:17 <ExpHP> ertes: I must confess I love the shit out of bras and kets. They can simultaneously represent discrete vectors and continuous functions in real space, and they help let you know when you've made a mistake because then the pointy bits don't match up
21:17 <ertes> ExpHP: it's not bras and kets that represent them, it's vector spaces
21:18 featherlessbiped joined
21:19 <ExpHP> I'm not sure, what's the distinction?
21:19 takle joined
21:19 <ExpHP> I take them just to be a language for linear algebra
21:20 <* ExpHP> quietly shoves the existing vector and matrix notation for linalg under the rug
21:20 Luke joined
21:20 <glguy> And in conclusion it's OK to use div in prefix position?
21:21 <monochrom> Yes.
21:21 <ertes> my problem is this: |a> is a vector, and <a| is the conjugate of it, which to my mind is applying a conjugation function to |a>: (|a>)*, but the application is implicit in the notation, which to my mind makes as little sense as the reference types in C++
21:21 <monochrom> The only contention is the order of the parameters.
21:22 <boxscape> hm, makes me wonder whether perhaps there could be some notation like "div _ 4" for "\x -> div x 4"
21:22 <ExpHP> oh come on it's gotta be a little bit better than C++
21:22 <boxscape> generalized sections, if you will
21:22 sypwex joined
21:23 <monochrom> Do you accept (`div` 4)?
21:23 <boxscape> well, that works for functions with two parameters
21:23 <monochrom> Ah.
21:23 <boxscape> but not in general
21:23 <ExpHP> implicit conjugation beats rule of 5
21:23 atomi joined
21:23 serious joined
21:23 <ertes> boxscape: not with that syntax at least, unless you want to give up typed holes
21:23 <boxscape> ertes: right, that makes sesne
21:23 <monochrom> Well, go 2-dimensional, don't just use left and right, use also above and below.
21:24 <ExpHP> okay, rule of 5 is something else. But whatever the new name is for C++'s rle of 3 that isn't really a rule for 3 anymore
21:24 <monochrom> You can accomodate generalized sections for up to 8 parameters if you use all 8 corners.
21:24 mac10688 joined
21:24 <monochrom> err, sides and corners!
21:24 <boxscape> nice
21:24 <ertes> Haskell2K
21:24 <monochrom> I wonder if you heard of my Einstein notation joke.
21:24 <boxscape> why stop at 2 dimensions though
21:24 <monochrom> Yeah!
21:24 <boxscape> I have not
21:25 niteria joined
21:25 atomi joined
21:25 <ertes> boxscape: because 3-dimensional text editors don't exist yet
21:25 <monochrom> Why did Einstein want 4 dimensions? Because he needs more corners for his Einstein notation.
21:25 <nshepperd_> Isn't the point that <a|b> gives the inner product of a and b
21:25 <serious> foldr const 0 "abc" is actually 'a' `const` ('b' `const` ('c' `const` 0)), why does it fail?
21:26 <boxscape> hm. I'm either missing something or it's just not that funny.
21:26 <ertes> nshepperd_: (a* · b) does that, too, with a simpler and more consistent notation =)
21:26 reem joined
21:26 <serious> foldr (flip const) 0 "abc" does work for some reasons
21:26 <ExpHP> ertes: I think the crux of the matter here is that transposed vectors WITHOUT conjugation are completely, 100%, entirely worthless
21:27 <ExpHP> ...in physics
21:27 <ertes> serious: because your result type is Char
21:27 <nshepperd_> ertes: what's (.)
21:27 <boxscape> > foldr const 0 [1..4]
21:27 <lambdabot> 1
21:27 sypwex joined
21:27 sz0 joined
21:27 <ertes> serious: foldr _ 0 "abc" = 0
21:28 suica joined
21:28 agjacome joined
21:28 <ertes> nshepperd_: inner product
21:28 insitu joined
21:28 <monochrom> This is a debate on basically infix notation vs multifix notation.
21:28 veyd joined
21:28 <veyd> Hello
21:28 <veyd> I was here about 6 months ago while I was getting started with Haskell, asking for book resources
21:29 <nshepperd_> But the point is to distinguish vectors vs covectors
21:29 <kadoban> veyd: Hello. Get recommended anything good?
21:29 <veyd> Someone recommended a book to me that was due to have a new edition published soo
21:29 <veyd> I'm trying to figure out which bok that was
21:29 <boxscape> @where book
21:29 <lambdabot> http://haskellbook.com/
21:29 <boxscape> I'm guessing
21:29 <veyd> no not that one
21:29 <boxscape> ok
21:29 <veyd> it was a more academic book
21:30 <ertes> veyd: http://www.cs.nott.ac.uk/~pszgmh/pih.html
21:30 <ertes> this one?
21:30 <geekosaur> I'm thinking Hutton's
21:30 <veyd> Yep, that's gotta be it
21:30 <veyd> thanks!
21:30 <geekosaur> since he was complaining about AMP/FTP landing while he was revising it :)
21:30 <monochrom> No, I was wrong. This is two debates combined into one, infix notation without Hungarian notation vs multifix notation with Hungarian notation.
21:30 oisdk joined
21:31 <nshepperd_> dot product of |a> with |b> is a type error,
21:31 CurryWurst joined
21:31 eschnett joined
21:31 <nshepperd_> or something like that. I haven't done any physics with those for a while
21:32 <serious> ertes: is my foldr expansion not correct?
21:32 <ertes> nshepperd_: when i was learning the basics of QM i actually translated all bra-ket notation to regular vector notation and found it easier to understand (and much more convenient to work with, too)
21:33 <serious> this one I mean: 'a' `const` ('b' `const` ('c' `const` 0))
21:33 <ertes> serious: it's correct, but you're missing the empty case
21:33 <ertes> in the empty case 0 is actually going to be the result
21:34 veyd left
21:34 <serious> you mean when the list is empty?
21:34 <nshepperd_> ertes: basically, since you only ever use (.) together with (*), you compose them together into one operation, called <•|
21:34 <ertes> serious: so if the list is non-empty, you want the result to be a Char, but in the empty case you want it to be whatever 0 is
21:34 <ertes> and Char is not a Num instance, so i would expect you to get a "no instance" error
21:35 <nshepperd_> The result of which is a function vector -> complex (a covector)
21:36 <serious> ertes: thanks, I haven't thought 'bout the empty list really!
21:36 <monochrom> Today is ertes's emptyness day! :)
21:36 <ertes> indeed =)
21:36 <monochrom> The empty list is a very powerful debugging tool.
21:36 <monochrom> In human society anyway.
21:36 <serious> good to know
21:37 Kundry_Wag joined
21:37 <ertes> which one?
21:37 <ertes> [] or [] or [] or …?
21:37 <monochrom> The lot of them!
21:37 <serious> is there a difference?
21:38 <Sornaensis> :t []
21:38 <lambdabot> [t]
21:38 <Sornaensis> sensors indicate no
21:38 sssilver joined
21:38 ExpHPhone joined
21:38 <ertes> > sum ([] :: [Int])
21:38 <lambdabot> 0
21:38 <ertes> > sum ([] :: [Bool])
21:38 <lambdabot> error:
21:38 <lambdabot> • No instance for (Num Bool) arising from a use of ‘sum’
21:38 <lambdabot> • In the expression: sum ([] :: [Bool])
21:38 <ertes> serious: yes
21:38 <serious> ah, you mean the polymorphic variable
21:39 <ertes> there are infinitely many empty lists, but there is no list of them
21:39 <monochrom> In practice it doesn't matter because the real goal is to get people to think it through.
21:39 <Sornaensis> > [[],[],[],[]]
21:39 <lambdabot> [[],[],[],[]]
21:39 <jle`> there is a "family" of them
21:39 <ertes> not a cons-list though, not even an HList
21:40 ExpHPhone_ joined
21:40 vikram__________ joined
21:40 ExpHPhone joined
21:41 nathanic joined
21:41 ExpHPhone__ joined
21:42 yellowj joined
21:43 shayan__ joined
21:43 safe joined
21:43 sssilver joined
21:45 kylepotts joined
21:45 <serious> how are foldr and foldl implemented under the hood? it looks like the first one is a stack and the latter one is a queue
21:45 <jle`> well, once you get an HList of all kind-* types, you can just map them
21:46 <jle`> serious: how 'under the hood' do you mean
21:46 <jle`> like, how are they implemented within haskell?
21:46 <jle`> (since they are normal haskell functions)
21:46 <jle`> or how this implementation gets compiled in GHC?
21:46 sypwex joined
21:47 coot joined
21:47 <serious> I mean if those are semantically like stack and queue?
21:47 <monochrom> No. They are semantically just recursions.
21:47 t_h joined
21:48 <jle`> oh, you're asking about their semantics, not their implementation?
21:48 <monochrom> But you can ask how to perform recursions on our machines. Then a stack is involved. But there is also laziness too, and so a heap is also involved.
21:48 <serious> I'm a bit confused, it is more about how they are compiled after all
21:49 <jle`> the list type is pretty much equivalent to the 'stack' abstract data type
21:49 <jle`> (semantically)
21:49 <jle`> so foldl could be seen as popping off items in the stack one-by-one and modifying an accumulator during the process against each new item seen
21:49 <serious> it looks like I can implement those with a stack data structure or queue (in case of foldl)
21:50 <jle`> well, list *is* a stack data structure
21:50 Koterpillar joined
21:50 <monochrom> But then you're fine-tuning to the list type, and you don't know how to compile other kinds of code.
21:50 silver_ joined
21:51 <serious> but foldl starts reducing with the first element, no? like "acc f head"
21:51 oish joined
21:51 certainty joined
21:51 <monochrom> If I define a tree type and write an in-order walk, a post-order walk, and a pre-order walk, how are you going to compile that?
21:51 <jle`> yes, foldl pops items off the list and accumulates them one-by-one
21:52 sea_wulf joined
21:52 <monochrom> And no, because of laziness, foldl starts with reducing the recursive call to foldl.
21:52 hiratara joined
21:52 <jle`> but what i'm talking about ins't really related to the bytecode that is compiled eventually
21:52 <Hi-Angel> I can't wrap my head around it. Here's a simple function "foldl' (\acc i -> acc >>= print >> fmap (i+) acc) (return 0) [1..5]" It just sums up a list [1..5] starting with an IO Int, and prints intermediate values. But it prints 31 values! Like, if "acc" turned from IO Int to a list of some kind. I completely ran out of ideas to understand what's wrong in there.
21:52 wraithm joined
21:53 <jle`> Hi-Angel: you do acc twice
21:53 marcopullo joined
21:53 <jle`> under each accumulation
21:54 <jle`> so you're going to be doing ~ 2^5 prints
21:54 contiver joined
21:54 <monochrom> Hi-Angel: I recommend simply myIOInt >>= \x -> print (foldl' (+) x [1..5])
21:54 <monochrom> In fact use do-notation.
21:54 <Hi-Angel> jle`: I don't see it. I do print once, in "acc >>= print", don't I?
21:55 Wizek_ joined
21:55 fDev2179 joined
21:55 <jle`> Hi-Angel: you do 'acc' twice
21:55 <Hi-Angel> monochrom: no, it's a reduced part from another code, where the foldl' is a separate function, and print also a separate one
21:55 <jle`> and acc contains printing statements
21:56 <monochrom> Oh, you want to print intermediate values too. Then I'll have to think again.
21:56 sypwex joined
21:56 <ertes> jle`: you will never get such an HList
21:56 <jle`> Hi-Angel: try unrolling it by hand
21:56 <jle`> and getting the full IO action
21:57 <jle`> Hi-Angel: 'acc' doesn't just return an item...it also prints stuff too
21:57 <jle`> so 'acc >>= print >> fmap (+1) acc' says "do 'acc', which could print stuff, and then print something, and do 'acc' again"
21:58 <jle`> so whatever effects 'acc' does is executed twice
21:58 <ertes> Hi-Angel: do you see that 'acc' is an action?
21:58 <jle`> for IO, fmap doesn't modify the effects
21:58 <ertes> it's not the result of an action, but an action itself
21:58 <Hi-Angel> I think
21:58 wraithm joined
21:58 <jle`> 'fmap f x' has the same effects as 'x'
21:58 splanch joined
21:58 <jle`> (for IO)
21:58 <jle`> for example, 'fmap length getLine' has the same effects as 'getLine'
21:58 <jle`> 'fmap (const 10) (putStrLn "hello")' has the same effects as 'putStrLn "hello"'
21:59 <jle`> so, `acc >>= print >> fmap (+1) acc` has the same effects as 'acc >>= print >> acc'
22:00 <Hi-Angel> Okay, I think I see. But, does that mean "IO Int" causes a print itself?
22:00 <Hi-Angel> I.e. when it's unwrapped in fmap call
22:00 <jle`> so, if 'acc' was `putStrLn "hi!"`, then `acc >>= print >> acc` would be `putStrLn "hi" >>= print >> putStrLn "hi"`
22:00 <jle`> Hi-Angel: it doesn't really get 'unwrapped'
22:00 <jle`> what you're doing is building up a description of an IO action
22:00 <ertes> Hi-Angel: your fold starts with an initial action (return 0) and list item by list item constructs a more and more complex action
22:01 <ertes> so the initial action doesn't print
22:01 <jle`> an 'IO Int' is a data structure that represents IO actions
22:01 <jle`> so what you're doing is building one up bit by bit, and then handing it off to whatever is going to eventually execute it
22:02 <ertes> Hi-Angel: foldl' (\currentAction x -> do currentAction >>= print; (+ x) <$> currentAction) (return 0) [1..5]
22:02 <Hi-Angel> So, every time I do "fmap", all previous IO actions are being executed once, more, right?
22:02 <ertes> no
22:02 <jle`> well, fmap doesn't actually trigger any actions
22:02 <jle`> fmap doesn't affect actions at all
22:02 <jle`> so 'acc >>= print >> acc' does whatever effects in 'acc' *twice*
22:02 <ertes> Hi-Angel: you're thinking in side effects, but you should be thinking in first-class actions
22:02 <monochrom> But fmap preserves whatever action you said.
22:02 <jle`> the fact that you use 'acc' twice in there is what causes the effects to waht happens twice
22:02 locallycompact joined
22:03 <jle`> so, if 'acc' prints 'hello", then `acc >>= print >> acc` prints hello twice
22:03 <Hi-Angel> I think I see.
22:03 <jle`> and also an extraneous something in between
22:03 <jle`> yeah, it might help to think of IO actions as just normal data structures, and not magical effect launchers
22:03 <ertes> Hi-Angel: acc >>= print >> fmap (+ i) acc -- this is the action that first executes the action acc, prints its result, then executes the action acc again, changing its result by the function (+ i)
22:04 <Hi-Angel> That complicates matters though. How would then I print an intermediate value?
22:04 <ertes> note: "is"
22:04 <ertes> not "does"
22:04 <monochrom> foldl' (\acc x -> acc >>= \a -> ... now you can use a ...
22:04 <jle`> Hi-Angel: you can accumulate the values using scanl, maybe
22:05 <jle`> Hi-Angel: but yeah, if you actually unrolled your fold by hand, you'll see where things go wrong
22:05 <ertes> Hi-Angel: BTW, you should probably use foldr
22:05 anemecek joined
22:05 <ertes> not probably, but almost certainly =)
22:05 <jle`> foldl' (\acc i -> acc >>= print >> fmap (i+) acc) (1:2:[])
22:05 <monochrom> Have you read my I/O tutorial? http://www.vex.net/~trebla/haskell/IO.xhtml
22:05 guampa joined
22:05 <jle`> @src foldl
22:05 <lambdabot> foldl f z [] = z
22:05 <lambdabot> foldl f z (x:xs) = foldl f (f z x) xs
22:06 rjg_ joined
22:06 <Hi-Angel> Nope. Why foldr though?
22:06 <ertes> Hi-Angel: read monochrom's tutorial, and once you're finished read my fold tutorial: http://ertes.eu/tutorial/foldr.html
22:06 <Hi-Angel> :D
22:06 <ertes> Hi-Angel: because your fold actually builds an action in memory before it can be executed
22:06 <jle`> => foldl (\acc i -> acc >>= print >> fmap (1+) acc) (return 0 >>= print >> return 1) (2:[])
22:06 <ertes> by using foldr you can have the action executed *during* folding
22:06 <jle`> => foldl (\acc i -> ...) ((return 0 >>= print >> return 1) >>= print >> (return 0 >>= print >> return 2) []
22:07 <ertes> :t foldr (\x continue -> print x >> continue) (pure ())
22:07 <lambdabot> (Show a, Foldable t) => t a -> IO ()
22:07 <jle`> => (return 0 >>= print >> return 1) >>= print (return 0 >>= print >> return 2)
22:07 <jle`> ^ do you see why this causes three prints?
22:07 <ertes> Hi-Angel: this one can print infinite lists
22:07 <ertes> foldl' could never print an infinite list
22:07 <jle`> because 'acc' is (return 0 >>= print >> return 1), if you did 'acc >>= print >> fmap (i+) acc', you'd get (return 0 >>= print >> return 1) >>= print >> (retunr 0 >>= print >> return 2)
22:08 <jle`> and if you did it again, you'd get something that's twice as long
22:08 <jle`> s/i+/1+
22:08 <ertes> Hi-Angel: my fold tutorial explains it in detail
22:08 <monochrom> 15-dimensional curves?! I don't think we ever really did that in Calculus, not even Multivariate Vector Manifold Calculus.
22:08 reinjg joined
22:08 <jle`> foldl yourFunction (return 0) (1:2:3:[])
22:09 <monochrom> Also, no smiling graphs in the exam.
22:09 <jle`> => foldl yourfunction (return 0 >>= print >> return 1) (2:3:[])
22:09 <jle`> => foldl yourfunction ((return 0 >>= print >> return 1) >>= print >> (return 0 >>= print >> return 3)) (3:[])
22:09 <ertes> monochrom: then it probably wasn't a machine learning course =)
22:09 fizbin joined
22:09 <monochrom> Oh! I see.
22:10 <jle`> => foldl yourfunction (((return 0 >>= print >> return 1) >>= print >> (return 0 >>= print >> return 3))) >>= print >> ((return 0 >>= print >> return 1) >>= print >> (return 0 >>= print >> return 6))) []
22:10 <Hi-Angel> I think I got it, IO accumulates the action. I just still don't see how to make it not do it, to print intermediate values. monochrom wrote it, but I don't see.
22:10 reinjg left
22:10 <ertes> Hi-Angel: read the IO tutorial
22:10 anuxivm joined
22:10 <jle`> after three values, there are 7 print statements
22:10 sypwex joined
22:10 <jle`> after 4 there will be 15, and after 5 there will be 31
22:11 rjg_ joined
22:12 <monochrom> I can tell an analogy with imperative languages (C or Java or ...)
22:12 BlueRavenGT joined
22:12 <jle`> Hi-Angel: if you ever have problems understanding the reuslt of a fold, unrolling it by hand often helps, too :)
22:13 <jle`> the unrolling here should have made it clear why the number of prints is what it is
22:13 <monochrom> If you wrote "rand(6) + rand(6)" and it gave you an odd number, you wouldn't be saying "I don't understand, I only mean to get one random number and double it!"
22:13 <ertes> unfortunately unrolling foldl' is not that easy =)
22:13 <Hi-Angel> jle`: well, to understand it I'd need to see that IO accumulates the action, and I didn't know it.
22:13 <ertes> unrolling foldr on the other hand is literally trivial: just substitute
22:14 <jle`> Hi-Angel: i don't think you'd have to know that...how elese would you have unrolled it?
22:14 <jle`> it's basically simple function application
22:14 <jle`> there's only one way to unroll (\acc i -> acc >>= print >> fmap (+1) acc)
22:14 <jle`> when applied to (return 0)
22:14 <jle`> all you have to do is apply the functions blindly :)
22:14 Netwolf joined
22:15 <rjg_> hello
22:15 <jle`> (\acc i -> acc >>= print >> fmap (+1) acc) (return 0) -- you don't have to know anything about IO to apply this
22:15 <jle`> all you do is substitute 'return 0' where acc is
22:15 orbifx joined
22:16 <jle`> (\acc i -> acc >>= print >> fmap (+1) acc) (return 0 >>= print >> return 1)
22:16 <jle`> ^ you don't have to know anything about IO to apply that
22:16 <jle`> imagine that it's (\x y -> x * 10 + y) 100
22:16 splanch joined
22:16 <jle`> and just do normal function application :)
22:17 <jle`> the nice thing about the IO tpye in haskell is that it works like any other data type with regards to function application, purity etc.
22:17 <jle`> there's no magic involved when working with IO
22:17 <jle`> it's just like any other pure value
22:17 <ertes> foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) (return 0) [1,2,3] = foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) ((\acc i -> acc >>= print >> fmap (+ i) acc) (return 0) 1) [2,3] = foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) (return 0 >>= print >> fmap (+ i) (return 0)) [2,3] = foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) (print 0 >> return 1) [2,3]
22:17 <Hi-Angel> jle`: well, the thing is: to me it looked like acc >>= print >> fmap (+1) acc is (return (0+(whatever_is_in_acc). I'd need to know that prints are gets accumulated in IO
22:17 <ertes> now this (print 0 >> return 1) becomes the new state
22:18 <jle`> Hi-Angel: wait, why?
22:18 <jle`> you're sort of assuming things about IO there that don't need to be assumed
22:18 wraithm joined
22:18 <jle`> giving it special treatment, when it should just be treated like a normal value
22:18 louispan joined
22:19 <jle`> (\acc i -> acc >>= print >> fmap (+1) acc) is a pretty clear function on normal haskell values
22:19 <rjg_> does anyone know how a alpha beta algorithm could be implemented in haskell? I thought the loop over the child nodes could be tracked with a foldr but how could I update the alpha and beta values?
22:19 <ertes> foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) (print 0 >> return 1) [2,3] = foldl' (\acc i -> acc >>= print >> fmap (+ i) acc) ((print 0 >> return 1) >>= print >> fmap (+ 2) (print 0 >> return 1)) [3]
22:19 <monochrom> "whatever_is_in_acc" is what goes wrong. acc is not trying to hide away a simple answer and make you go through hoops to get it.
22:20 <Koterpillar> rjg_: pass them as parameters
22:20 <jle`> yeah, i think you made some assumptions that IO is more magical than it is
22:20 <ertes> Hi-Angel: it is at this point that you see how the prints build up
22:20 <jle`> an 'IO Int' is just a normal value
22:20 rcat joined
22:20 <jle`> just like any other haskell value
22:20 <ertes> Hi-Angel: note that i have only done substitutions
22:20 <jle`> there isn't many magical "extraction of contents" that goes on
22:21 <Hi-Angel> Okay, let me read the unroll again :)
22:21 <jle`> `(\acc i -> acc >>= print >> fmap (+1) acc) blahblah`
22:21 <rjg_> oh yeah thanks
22:21 <ertes> Hi-Angel: what you should be reading is the IO tutorial
22:21 <monochrom> For all you know, acc could be asking a user for a number. Do you want to ask the user twice? But that's exactly what "unwrapping" acc twice will get you. Asking the user twice. No, the "unwrapping" idea is all wrong.
22:21 <jle`> ^ how would you apply that?
22:21 fizbin joined
22:21 <jle`> it's unambiguously `(\acc i -> blahblah >>= print >> fmap (+1) blahblah)`
22:21 <ertes> Hi-Angel: you're making assumptions about IO which lead you nowhere
22:22 e14 joined
22:23 <jle`> Hi-Angel: in general, if you see `(\x -> ... something involving x) foo`, then all you do is just substitute 'foo' everywhere there is x
22:23 <jle`> if you did this with your original fold, you'll see why the printing happens the number of times it does
22:23 <jle`> > (\x -> x * 2) 100
22:23 <lambdabot> 200
22:23 <jle`> ^ in there, wherever x occures in (x * 2), you'd substitute in 100
22:23 e14 joined
22:24 fDev2179 left
22:24 <rjg_> Koterpillar do you know how you can break out of the foldr when alpha>=beta?
22:24 gabe4k joined
22:24 <jle`> rjg_: i am not sure that a foldr is the best way to go about alpha-beta
22:24 <jle`> last time i did it i just used explicit recursion
22:24 <ertes> @let myNull = foldr (\_ _ -> True) False
22:25 <lambdabot> Defined.
22:25 <ertes> > myNull [1..]
22:25 <lambdabot> True
22:25 <ertes> hmm
22:25 <jle`> it's a pretty straightforward algorithm with just explicit recursion. it writes itself :)
22:25 <ertes> myNotNull i guess
22:25 <Koterpillar> rjg_: I agree with jle`, but you surely can if you think about how can you implement, for example, any using fold
22:25 dawehner joined
22:25 <jle`> to answer your specific question we'd have to know more about how exactly you're formulating your alphabeta as a foldr
22:25 <monochrom> Write explicit recursion first, then see if you recognize where foldr appears in disguise.
22:25 <jle`> but "breaking out" of a foldr is more or less just ignoring the second argument in the accumulating function
22:26 <jle`> but yeah, alphabeta is as textbook a case as it gets when talking about explicit recursion functions
22:26 <monochrom> And I suspect it is not just list's foldr, there is also tree's catamorphism involved somewhere.
22:26 <rjg_> Im trying to fold over the next possible moves and accumulating the highest value
22:26 <rjg_> but maybe explicit recursion is better
22:26 <ertes> rjg_: in general you just ignore the recursive result
22:27 <jle`> rjg_: if you want to select the highest value then you can use maximum or maximumBy
22:27 ChaiTRex joined
22:27 <ertes> > @let myTake n0 xs = foldr (\x go n -> if n > 0 then x : go (n - 1) else []) (const []) xs n0
22:27 <jle`> oh, i think i see, i misunderstood
22:27 <lambdabot> <hint>:1:1: error: parse error on input ‘@’
22:27 dsantiago joined
22:27 <jle`> you weren't talking about implementing alphabeta using foldr
22:27 <ertes> what?
22:27 <jle`> but about just finding the maximum of the child nodes
22:27 <ertes> @let myTake n0 xs = foldr (\x go n -> if n > 0 then x : go (n - 1) else []) (const []) xs n0
22:27 <lambdabot> Defined.
22:28 conal joined
22:28 <ertes> > myTake 10 [1..]
22:28 <lambdabot> [1,2,3,4,5,6,7,8,9,10]
22:28 <jle`> yeah, finding the maximum of the child nodes you can just use maximum or maximumBy
22:28 <ertes> rjg_: like that
22:28 <ertes> rjg_: however, you can't really use the foldr from Foldable like that for tree-shaped types
22:28 <jle`> if you want to stop after a certain threshold is found, you can look at the implementation of 'find'
22:28 <jle`> @src find
22:28 <lambdabot> find p = listToMaybe . filter p
22:28 <ertes> you need to construct an actual tree fold
22:28 <jle`> oh that's not helpful lol
22:29 <jle`> sry
22:29 <monochrom> foldr (&&) is a simple example of early quitting.
22:30 <monochrom> > foldr (&&) undefined (repeat False)
22:30 <lambdabot> False
22:30 gabe4k joined
22:30 <monochrom> I gave it an infinite list. It clearly quitted early.
22:30 ExpHP joined
22:30 MP2E joined
22:30 <ertes> > foldr (const . Just) Nothing [1..] -- here is another one: listToMaybe
22:30 <lambdabot> Just 1
22:31 <monochrom> Yeah, the trick is avoiding evaluation of the 2nd operand.
22:31 <kadoban> That's fairly clever, I wouldn't think of foldr for listToMaybe.
22:31 hiratara joined
22:32 <monochrom> Wait, quitted? quit?
22:33 <ertes> > foldr (\x ~(ys1, ys2) -> (x:ys2, ys1)) mempty "abcdefg"
22:33 <lambdabot> ("aceg","bdf")
22:33 <monochrom> I cutted a big slice of cake for myself...
22:33 ebzzry joined
22:33 Sonolin joined
22:33 <boxscape> monochrom: either one
22:33 ddere joined
22:34 <ertes> kadoban: the reason is probably that you would just use foldr (or even traverse/traverse_) instead of first converting to a Maybe =)
22:34 <kadoban> I think both are correct, but "quit" seems way more common currently.
22:34 <ertes> :t foldr (\x _ -> print x) (putStrLn "No first element")
22:34 <lambdabot> (Show a, Foldable t) => t a -> IO ()
22:34 sypwex joined
22:34 <ExpHP> the regex package has apparently been updated not once, not twice, but three times since I wrote my unit tests yesterday
22:34 <kadoban> ertes: Heh, sounds right
22:35 <kadoban> That pattern strikes me as novel for myself though, not a pattern I've used before. I'll have to keep it in mind.
22:35 <rjg_> but when I use explicit recursion in my negamax I get nested lists
22:36 geppettodivacin joined
22:37 Vaelatern joined
22:37 Bob8989|2 joined
22:37 wraithm joined
22:38 bla_ joined
22:38 dan_f joined
22:39 kylepotts joined
22:40 Micamo joined
22:40 mudri joined
22:41 <jle`> if you're having issues still, you can paste your code :)
22:42 afnizarnur joined
22:42 <ertes> rjg_: you might be interested in my fold tutorial, too: http://ertes.eu/tutorial/foldr.html
22:42 event_null joined
22:43 cyborg-one joined
22:43 <Hi-Angel> jle`: okay, to begin with: foldl' is a strict version, it doesn't build thunks. Anyway, even lazy foldl upon building up thunks doesn't execute anything, including prints. It does it upon consuming, and every thunk consumed once, so every print also should happen once.
22:44 e14 joined
22:44 mmachenry joined
22:44 jmcarthur joined
22:45 <jle`> >> and >>= are pure for IO
22:45 <Hi-Angel> If I correctly understood, you're assuming prints are executed upon building thunks, and then once more upon consuming
22:45 <jle`> they shouldn't execute anything in either case
22:45 <jle`> i'm not assuming prints are executed upon building thunks
22:45 <jle`> did you try unfolding the foldl?
22:45 <ertes> Hi-Angel: you keep insisting that IO is side-effecting
22:45 <ertes> *no* fold will *ever* execute *anything*
22:45 <Hi-Angel> I've read your unfold
22:46 <jle`> >>= and >> *never* cause side-effects during evaluation
22:46 <adarqui> trying to build haskell platform (for 8.0.2) from source, lots of stuff like this: src/OS/Win/WinNsis.hs:90:28: Not in scope: `<$>' .. anyone compile it from source here who maybe has some tips?
22:46 <jle`> foldl or foldl'
22:46 <jle`> Hi-Angel: do you agree that the unfold i put was correct?
22:46 <jle`> if so, you should see that there are 7 print statements
22:46 <jle`> in the final IO action
22:46 Amadiro joined
22:46 <Hi-Angel> Okay, let me try it myself…
22:47 <jle`> 'print' doesn't print anything during evaluation
22:47 <jle`> so whether or not you force 'print 1' or not, or if it's built up as a thunk or it, it doesn't evaluate anything
22:47 <monochrom> If you do "seq (print 5) ()" you will not see 5 printed.
22:47 Voldenet joined
22:47 Voldenet joined
22:47 <adarqui> how do people here install the latest haskell platform on say, ubuntu linux?
22:48 <jle`> IO isn't something that fires of effects when it is evaluated
22:48 <glguy> monochrom: Maybe 5 is special?
22:48 <ertes> Hi-Angel: haskell does not have side effects, not even IO
22:48 <jle`> but yes, unfold even the [1,2] case, and you'll see
22:48 <monochrom> Yeah! It's my answer to the purpose of Haskell!
22:48 <jle`> the [1,2] case when unrolled should resutn in an IO action that has three print statements
22:48 hololeap joined
22:48 <jle`> there is only one way to unroll it...
22:48 <jle`> it's impossible to mess up :)
22:48 <adarqui> i don't get why the haskell platform site just says, apt-get install haskell-platform .. that's going to give you an OLD version
22:49 <ertes> adarqui: i'd install GHC and cabal-install directly
22:49 <adarqui> didn't see the "Generic link"
22:49 <jle`> the only rule: if you see `(\x -> ... x ...) foo`, then simply replace every occurence of 'x' in the body with 'foo'
22:49 <adarqui> maybe that'll help
22:49 <monochrom> adarqui: You're right. I ignore that suggestion and go ahead to choose the generic-linux binary.
22:49 <adarqui> ertes, ya ive done that b4 but just want the platform
22:49 <ertes> adarqui: ("directly" as in directly installing the packages, not the platform package)
22:49 <adarqui> monochrom: ya. didn't see the generic section
22:49 <adarqui> going to try that.. i imagine that'll be what i need
22:50 <jle`> Hi-Angel: don't worry about the fact that 'foo' might have a type 'IO Int'. it's just normal haskell evaluation. do it according to the rule i just posted, and you'll see :)
22:50 <jle`> if you see `(\x -> ... x ...) foo`, then just replace every occurence of x in the body with 'foo', etc.
22:50 <ertes> adarqui: debian-based distributions are known to distribute ridiculously old versions, but on other distributions (arch, gentoo, NixOS) you won't have that problem… in that case i suggest using the package manger
22:50 <ertes> manager
22:51 <adarqui> ya
22:51 <adarqui> thanks ertes
22:51 <adarqui> installing generic now
22:51 wtetzner joined
22:51 <jle`> Hi-Angel: once you have unrolled foldl (\acc i -> ...) (return 0) (1:2:[]), then you'll see that the resulting IO action has three print statements. if it doesn't, come back and let us know what you got
22:52 wtetzner joined
22:52 <boxscape> So, I understand why "foldl' (&&) undefined (repeat False)" complains about the undefined. But shouldn't "foldl' (flip (&&)) undefined (repeat False)" unfold to "let a' = False && undefined in a' `seq` foldl' (flip (&&)) a' (repeat False)", where a' evaluates to False, and presumably leading to an infinite loop? Instead it also complains about undefined
22:52 <ertes> boxscape: no
22:53 <codedmart> What is `'`? I see this `type QuoteDocType = '['CutFile, 'Design]; type BidDocType = '['Bid];` and can I concat QuoteDocType and BidDocType?
22:53 <ertes> boxscape: foldl' will always have to traverse the whole list
22:53 <ertes> it's defined that way
22:53 <jle`> codedmart: it's optional, but '[a,b,c] is a type-level list of types a, b, and c
22:53 <jle`> :k '[Int, Bool String]
22:53 <boxscape> ertes: but that's what I'm suggesting
22:53 <lambdabot> error:
22:53 <lambdabot> • Expecting one fewer argument to ‘Bool’
22:53 <lambdabot> Expected kind ‘* -> *’, but ‘Bool’ has kind ‘*’
22:53 <hololeap> codedmart: it's just a alphanum character
22:53 <jle`> :k '[Int, Bool, String]
22:53 <lambdabot> [*]
22:53 <ertes> boxscape: oh, i misread
22:53 <boxscape> > foldl' (flip (&&)) undefined (repeat False)
22:53 <lambdabot> *Exception: Prelude.undefined
22:53 gillesmajor joined
22:53 <jle`> ^ that's a type-level list of things of kind *
22:54 <jle`> codedmart: you can concat them if you have a concat/(++) type family defined somewhere
22:54 <ertes> foldl' (flip (&&)) undefined (False : xs) = let !x = undefined && False in foldl' (flip (&&)) x xs
22:54 <glguy> boxscape: foldl' f z xs is strict in z
22:54 <ertes> > undefined && False
22:54 <lambdabot> *Exception: Prelude.undefined
22:54 <ertes> boxscape: ^
22:54 <boxscape> glguy: ah, I see
22:55 <jle`> codedmart: when you write `data Bool = True | False`, it defines a type 'Bool' of kind '*' with two value constructors, True and False
22:55 <glguy> > foldl (\_ x -> x) undefined [1,2]
22:55 <glguy> > foldl' (\_ x -> x) undefined [1,2]
22:55 <lambdabot> 2
22:55 <codedmart> jle`hololeap OK thanks?
22:55 <lambdabot> *Exception: Prelude.undefined
22:55 <jle`> codedmart: but, you also define a *kind* Bool, with two *type* constructors, 'True and 'False
22:55 <codedmart> OK great
22:55 <jle`> :k '[ 'True, 'False, 'True ]
22:55 <lambdabot> [Bool]
22:55 <ertes> > foldl' (\_ x -> x) undefined [1]
22:55 <jle`> that's a type-level list of things of kind Bool
22:55 <lambdabot> *Exception: Prelude.undefined
22:55 mojjo joined
22:56 <boxscape> ertes: that alone wouldn't explain it, because (flip (&&)) should get rid of that, but foldl' being strict in the initial value does explain it
22:56 <ertes> oh, then my definition is off-by-one
22:56 <ertes> boxscape: it does, because (undefined && False) is still undefined
22:56 <ertes> oh, no
22:56 <ertes> it should be (False && undefined)
22:56 <boxscape> > (flip (&&)) undefined False
22:56 <lambdabot> False
22:56 <ertes> yeah, sorry
22:57 <boxscape> @src foldl'
22:57 <lambdabot> foldl' f a [] = a
22:57 <lambdabot> foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
22:57 <ertes> i'm a bit surprised that (foldl' f z) is strict in z
22:57 <codedmart> jle`: Thanks for the explanation.
22:57 <boxscape> this is slightly different from the actual code in ghc then, right?
22:57 <jle`> no problem!
22:57 <ertes> in fact that one isn't
22:57 <jle`> codedmart: the keyword to search for for more details is DataKinds
22:58 thimoteus joined
22:58 <ertes> @let myFoldl' f z xs = foldr (\x go s' -> let !s = f s' x in go s) id xs z
22:58 <lambdabot> Defined.
22:58 <glguy> ertes, boxscape: In the past foldl' wasn't strict in the initial "accumulator"
22:58 <ertes> that's how i would define foldl'
22:58 tangled_z joined
22:58 <boxscape> ah
22:59 <ertes> > myFoldl' (flip (&&)) undefined [False]
22:59 <lambdabot> False
23:00 <boxscape> foldl' f z0 xs = foldr f' id xs z0; where f' x k z = k $! f z x
23:00 <boxscape> is ghc
23:00 <glguy> ertes, boxscape: https://mail.haskell.org/pipermail/libraries/2014-November/024065.html
23:00 <ertes> boxscape: hmm? that doesn't sound right, if it throws
23:01 <boxscape> well, that's the one from Foldable at least
23:01 <boxscape> http://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Foldable.html#foldl%27
23:01 suls joined
23:01 <ertes> hmm, strictness analysis is a good point
23:02 HarveyPwca joined
23:03 Wizek_ joined
23:03 hybrid joined
23:03 <boxscape> > GHC.List.foldl' (flip (&&)) undefined (repeat False)
23:04 <lambdabot> error:
23:04 <lambdabot> Not in scope: ‘GHC.List.foldl'’
23:04 <lambdabot> Perhaps you meant ‘Data.List.foldl'’ (imported from Data.List)
23:04 <boxscape> uh
23:04 <boxscape> :t GHC.List.foldl'
23:04 <lambdabot> (b -> a -> b) -> b -> [a] -> b
23:04 <boxscape> ok then
23:04 <boxscape> apparently :t uses a different namespace from >
23:05 <glguy> :t System.IO.Unsafe.unsafePerformIO
23:05 <jle`> @let import qualified GHC.List
23:05 <lambdabot> Defined.
23:05 <lambdabot> IO a -> a
23:05 <boxscape> > GHC.List.foldl' (flip (&&)) undefined (repeat False)
23:05 <lambdabot> *Exception: Prelude.undefined
23:05 <boxscape> neat, didn't know you could import like that
23:05 <kadoban> :t and > are really different namespaces? That sounds like something I would have noticed at some point
23:05 gugah joined
23:05 <jle`> kadoban: for the reason glguy just showed
23:05 <kadoban> Oh, huh.
23:06 <jle`> being able to ask for the type of unsafe things is fine but you probably don't want to allow them to be executed
23:06 <jle`> er, evaluated
23:06 <kadoban> I guess that makes sense ...
23:06 marsam joined
23:08 <boxscape> @let import qualified System.IO.Unsafe
23:08 <lambdabot> .L.hs:139:1: error:
23:08 <lambdabot> System.IO.Unsafe: Can't be safely imported!
23:08 <lambdabot> The module itself isn't safe.
23:08 <boxscape> :(
23:09 m0rphism joined
23:09 <boxscape> you don't usually see lambdabot errors with file locations, do you?
23:09 ChaiTRex joined
23:11 louispan joined
23:11 <Hi-Angel> jle`: okay, here's my version http://lpaste.net/353992 You told me to not make special assumptions about IO, so I end up with this, and, well, there's no multiple print statements :/
23:13 <jle`> Hi-Angel: how come your accumulator magically turned into ()?
23:13 <glguy> Hi-Angel: They're missing because you forgot to write them in the accumulator
23:14 fakenerd joined
23:14 <jle`> Hi-Angel: the result of (\acc i -> acc >>= print >> fmap (+1) acc) (return 0) 1 isn't ()
23:14 cyborg-one joined
23:14 <jle`> that ... isn't even the right type, heh
23:14 <Hi-Angel> jle`: you mean the "return 0"? Well, I just didn't know what to write in there, because accumulator moved into the argument, so I left a space
23:15 <jle`> i meant on line 6
23:15 <Hi-Angel> Yes
23:15 <jle`> okay, let's try to figure out what the accumulator is
23:15 <jle`> (\acc i -> acc >>= print >> fmap (+1) acc) (return 0) 1
23:15 <jle`> what is the result of that?
23:15 <jle`> remember, substitution
23:16 <jle`> if you see (\x y -> .. x ..) foo bar, it means to substitute 'foo' wherever you see x
23:16 <Hi-Angel> Here it is 0
23:16 <jle`> hm, how did you get zero
23:17 <jle`> because...it's not zero
23:17 <Hi-Angel> Well, if you mean after the function executed
23:17 <Hi-Angel> Then it's 1
23:17 <jle`> no, i mean the result
23:17 <jle`> the result of the function evaluation
23:17 <Hi-Angel> 1
23:17 <jle`> not quite
23:17 <jle`> let's do it step by step
23:17 <jle`> (\acc i -> acc >>= print >> fmap (+1) acc) (return 0) 1
23:17 nomicflux joined
23:17 <jle`> (\i -> (return 0) >>= print >> fmap (+i) (return 0)) 1
23:18 <jle`> `(return 0) >>= print >> fmap (+1) (return 0)`
23:18 <jle`> that's the resulting IO action
23:18 <jle`> it's `return 0 >>= print >> fmap (+1) (return 0)`
23:18 <jle`> that's your new accumulator
23:18 <jle`> its type is `IO Int`
23:19 <jle`> you can actually simplify this a bit using the monad laws
23:19 <Hi-Angel> I think I see. Let me think a bit.
23:19 <jle`> but it's not necessary
23:19 ozgura joined
23:19 <jle`> you can leave it in its full form and then simplify it using monad laws at the end
23:20 <jle`> did you see how i got this?
23:20 <Hi-Angel> Yes
23:20 <jle`> all i did was subsitute 'acc' with (return 0)
23:20 <jle`> becaus ethat's how function application works in Haskell
23:20 <jle`> and i substituted 'i' with 1
23:20 <jle`> the result isn't 0, or 1, or ()
23:21 <jle`> the result is an IO action -- an action that is equivalent to `return 0 >>= print >> fmap (+1) (return 0)`
23:21 <jle`> and whose type is IO Int
23:21 <jle`> if you didn't know this was IO, and you thought it was just normal values (like ints or bools or strings), this is what you would have done
23:21 dawehner joined
23:22 <jle`> this is the same thing that happens when you do (\acc i -> acc * foo + bar i)
23:22 <jle`> etc.
23:22 e14 joined
23:22 <Hi-Angel> Yeah, no I see, upon taking the next value from the list, I'd end up with the function being executed twice.
23:22 <Hi-Angel> *now
23:23 <jle`> yup, it's because IO is just a normal data structure. it's closely related to a tree, actually
23:23 zcourts joined
23:23 <jle`> semantically
23:23 markus1189 joined
23:23 <Hi-Angel> I think I see, it's just so unusual. I'm trying to figure out, in what way could I end up like that in another language upon doing foldl
23:23 markus1199 joined
23:24 <jle`> actually i think this is the more non-unusual way
23:24 <jle`> here, an IO action is just treated like a normal pure value
23:24 <jle`> if it were anything different, haskell would be inconsistent in how function application works
23:24 <jle`> it's just that we have been accustomed to thinking about IO as magical from other languages
23:25 <jle`> so seeing an IO action treated as a normal value is a bit jarring
23:25 <Sonolin> jle` how is IO "closely related to a tree"? From my understanding it more closely relates to the State monad, or maybe a list
23:25 <jle`> well, you can imagine `>>` as joining two trees
23:25 <boxscape> to be fair, IO is still a little bit special because you leave >>= and >> unevaluated, whereas regular functions, like foldr, you can replace by their definition
23:26 <jle`> boxscape: not necessarily, if your data type is abstract
23:26 <jle`> like IO is
23:26 <boxscape> yeah, that makes sense
23:26 theDon_ joined
23:27 <jle`> (abstract data types aren't special in haskell; Map, Set, etc. are other common ones)
23:27 <jle`> and what you probably mean is that we leave >>=/>> unsimplified
23:27 <jle`> but there is simplifcation you can do, from the API
23:27 <boxscape> I suppose that is what I mean
23:27 <jle`> for example, we could have simplified `return 0 >>= print >> fmap (+1) (return 0)` into an equivalent IO action, based on how the API behaves
23:27 <jle`> it's equivalent to `print 0 >> return 1`
23:28 <jle`> this would be the same as, say, applying 'fmap' to M.fromList [('a', 1), ('b', 2)]
23:28 zero_byte joined
23:28 <jle`> fmap negate (M.fromList [('a', 1), ('b', 2)]) is equivalent to M.fromList [('a', -1), ('b', -2)]
23:28 <jle`> but we just know this because we trust the API of Data.Map
23:28 <boxscape> ok, I see
23:29 <jle`> the actual data type is abstract, who knows what is going on under the hood?
23:29 <boxscape> or we could just replace it by this? bindIO (IO m) k = IO (\ s -> case m s of (# new_s, a #) -> unIO (k a) new_s) :P
23:29 <jle`> M.fromList [('a', -1), ('b', -2)] might have a completely different internal representation as fmap negate (M.fromList [('a', 1), ('b', 2)])
23:29 nakal_ joined
23:29 <boxscape> (the bindIO source)
23:29 Welkin joined
23:29 <jle`> but we treat them as the same because they are abstract data types that respect properties and laws
23:29 kirillow joined
23:30 <jle`> `return 1 >>= print` might be different internally from `print 1`, but we treat them as the same thing because that's how abstract data types work
23:31 <jle`> boxscape: i'm not sure if we can actually do that in every case, heh. we open ourseives to breaking the abstraction when we peak into the implementations of abstract data types
23:31 <jle`> s/peak/peek
23:31 IRCFrEAK joined
23:31 <boxscape> I can see why that might be the case, yeah
23:32 cyborg-one joined
23:32 <Hi-Angel> Okay, thanks everyone, I gotta go sleep, I have just 3.5 hours left to.
23:33 <jle`> have a nice night!
23:33 halogenandtoast joined
23:33 <Hi-Angel> Good night!
23:33 <jle`> ty
23:34 <boxscape> actually kind of weird to me that bindIO uses case instead of let for pattern matching on a single possible case
23:34 <glguy> The difference is let vs case isn't how any alternatives you get, but to do with strictness
23:34 <boxscape> ah, ok
23:35 oisdk joined
23:36 <glguy> which is why it's common to see tuples being used with case: case xy of (x,y) -> ....
23:36 <glguy> even though there's only one possibility
23:38 <monochrom> "case undefined of (_, _) -> 5" is going to bottom out. This shows the difference from let. You can use "case undefined of ~(_, _)" to regain the meaning of let.
23:38 <boxscape> what's the ~ here?
23:38 <boxscape> non-strictness?
23:38 <monochrom> And BangPatterns is the greatest invention ever because it completes the symmetry. You can use "let !(_,_) = undefined" to regain the meaning of case. :)
23:39 <glguy> boxscape: ~ creates an irrefutable pattern
23:39 <monochrom> It is both non-strictness and "assume this will match, look no further"
23:39 <boxscape> ok
23:40 <monochrom> > case [1,2] of ~[] -> 5; _ -> 6
23:40 <lambdabot> 5
23:40 <boxscape> ok, so it doesn't even complain if it doesn't work
23:40 <boxscape> > let [] = [1,2] in 5
23:40 <glguy> boxscape: You might want to search for irrefutable and ~ on this page to learn more https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-580003.17
23:40 <lambdabot> 5
23:40 <boxscape> thanks
23:41 <monochrom> It will complain when I have enough evaluation to expose the lie. But that will be during run time. Not statically checked.
23:41 <boxscape> right, that makes sense
23:41 <jle`> > case [] of ~[x,y] -> 5
23:42 <lambdabot> 5
23:42 <jle`> > case [] of ~[x,y] -> x
23:42 <lambdabot> *Exception: <interactive>:(3,1)-(4,22): Irrefutable pattern failed for patte...
23:42 <boxscape> it actually doesn't even surprise me that it doesn't complain in let, just not used to seeing it in case :)
23:43 <glguy> > case [1,2] of ~[x,3] -> x
23:43 <lambdabot> *Exception: <interactive>:(3,1)-(4,22): Irrefutable pattern failed for patte...
23:43 <glguy> Note that once you force evaluation of a name bound by the pattern, the whole pattern has to match
23:44 MindlessDrone joined
23:44 <glguy> > case [1,2] of ~[x,~3] -> x
23:44 <lambdabot> 1
23:44 <boxscape> > case (1,[]) of ~(a,[2]) -> a
23:44 <lambdabot> *Exception: <interactive>:(3,1)-(4,22): Irrefutable pattern failed for patte...
23:44 <boxscape> ok
23:44 <monochrom> Yeah, that one is a finer detail on how much to evaluate is enough to trigger real checking.
23:44 hololeap joined
23:45 <monochrom> My http://lpaste.net/100588 shows an extreme example where many intuitions think it shouldn't bottom.
23:45 <defanor> i'm looking for a library that would help with writing a very basic http service: it should only process a single request (authentication), with no html composition or anything like that -- so i won't need web framework features, and even snap would be an overkill. could even use it with nginx, and then something for CGI would suffice. what are the minimal (with minimal dependencies) and maintained ones?
23:46 <Welkin> defanor: servant
23:46 <defanor> Welkin: will check it, thanks
23:46 <Sonolin> yea servant is beautiful for API stuff
23:46 <Welkin> it is a library for writint web apis
23:46 <Welkin> if you want something low-level, use wai
23:47 <boxscape> monochrom: yeah, that's interesting
23:48 <jle`> scotty isn't too bad either; it's close in spirit to sinatra or flask if you've ever done web dev in ruby or python
23:48 cmsmcq joined
23:48 <jle`> but checkout servant if you want to feel the true power of the haskell type system
23:49 carlosdagos joined
23:49 <jle`> (and this isn't even its final form)
23:49 hybrid joined
23:49 <boxscape> i would've expected it to just go to WHNF wherever it can when it has to check a pattern
23:49 Hi-Angel joined
23:49 <boxscape> and not check past that
23:51 <Hi-Angel> That said, I still clueless: how would I print intermediate value in foldl, so that print wasn't executed twice for successive elements in the list?
23:52 <ChaiTRex> Hi-Angel: Try scanl
23:52 <ChaiTRex> Hi-Angel: It'll give you a list of intermediate results.
23:52 <glguy> boxscape: expressions are checked as much as needed, maybe WHNF, maybe more, maybe less
23:52 certainty joined
23:52 <glguy> (_ : _ : _) will go beyond WHNF, _ will do less
23:52 johnw joined
23:52 splanch joined
23:52 <Hi-Angel> But they'd take memory, whilst I just need to print them
23:53 augur joined
23:53 <Cale> Of course, at some point, case expressions are compiled down to case expressions in core, which always match on exactly one constructor at a time.
23:53 <jle`> scanl is a good consumer
23:53 <jle`> er, producer
23:53 <jle`> it won't allocate the intermediate list if you print things as they come i think
23:53 <boxscape> glguy: well, in case (1,[[],[]]) of ~(a,[[],[1]]) -> a, it wouldn't *need* to know the contents of the list, would it? and WHNF of the list would be [] : rest, in either case, I think?
23:54 <boxscape> you mentioned that it will go beyond WHNF in (_:_:_), but why?
23:54 splanch_ joined
23:54 deepfire` joined
23:54 <glguy> boxscape: WHNF of a list only determines if the list is built from a [] or a (:)
23:54 koserge joined
23:55 <boxscape> Oh, I think I misunderstood you earlier, ok
23:55 <Hi-Angel> Okay, thank you.
23:55 <boxscape> you're saying it will check the whole pattern, and if WHNF is enough to check the whole pattern, it won't go beyond that?
23:55 <boxscape> my point was that it doesn't actually *need* to check the whole pattern to get a
23:55 <glguy> [[],[1]] is already in NF, , [] : rest isn't the "WHNF" of that expression
23:55 <boxscape> ah, ok
23:56 <boxscape> that makes sense
23:57 YongJoon joined