<     May 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 orhan89 joined
00:00 jmcarthur joined
00:01 infinity0_ joined
00:01 infinity0_ joined
00:02 albel727 joined
00:02 tromp joined
00:04 infinity0 joined
00:05 Koterpillar joined
00:06 felixsch_ joined
00:06 infinity0 joined
00:09 <Squarism> saylu, what i do remember is that hoauth2 lagged quite a bit version wise / not using the latest endpoints (and transport objects) - that was the part i needed to fix.
00:09 infinity0 joined
00:09 cozachk joined
00:10 kritzcreek joined
00:10 orion joined
00:10 orion joined
00:11 mnoonan joined
00:11 MarioBranco joined
00:12 infinity0 joined
00:12 acyed joined
00:12 asivitz joined
00:17 pparkkin joined
00:17 felixsch1 joined
00:17 nighty-- joined
00:18 <* hackage> logsink 0.2.0 - A logging framework for Haskell https://hackage.haskell.org/package/logsink-0.2.0 (SimonHengel)
00:18 chrisdotcode joined
00:18 jgertm joined
00:20 plutoniix joined
00:20 takle joined
00:22 plutoniix joined
00:23 plutoniix joined
00:24 montagy joined
00:25 rblaze joined
00:25 prkc joined
00:29 montagy1 joined
00:31 juanpaucar joined
00:32 juanpaucar joined
00:35 lambda-11235 joined
00:35 saussure joined
00:36 <koala_man> how can I install the haskell platform on windows non-interactively?
00:38 fragamus joined
00:39 MrWoohoo joined
00:40 augur joined
00:42 jgertm joined
00:42 wroathe joined
00:43 Bardusbasium joined
00:44 jbiesnecker joined
00:46 augur joined
00:49 halogenandtoast joined
00:50 a3Dman joined
00:53 sanitypassing joined
00:53 darjeeling_ joined
00:53 wroathe joined
00:53 bigos joined
00:54 <bigos> hi, how do i zip over two ranges?
00:55 <lyxia> > zip [0 ..] [3 .. 7] -- bigos
00:55 <lambdabot> [(0,3),(1,4),(2,5),(3,6),(4,7)]
00:56 <bigos> thanks
00:56 <bigos> but why this zip [0..4] [4..0] doesn't work?
00:56 <lyxia> > [4..0]
00:56 <lambdabot> []
00:56 <lyxia> bigos: ranges go up
00:56 <lyxia> > [4,3..0]
00:56 <lambdabot> [4,3,2,1,0]
00:57 <nisstyre> > zip [0..4] (reverse [0..4])
00:57 <lambdabot> [(0,4),(1,3),(2,2),(3,1),(4,0)]
00:58 <bigos> I get it
00:58 <bigos> thank you very much
00:58 michi7x7 joined
00:58 <unknownln> Where does stack download its GHC binaries from?
00:58 paul0 joined
00:59 juanpaucar joined
00:59 a3Dman joined
00:59 drewbert joined
01:02 Koterpillar joined
01:03 wroathe joined
01:06 alveric3 joined
01:07 acertain joined
01:10 a3Dman joined
01:11 vaibhavsagar_ joined
01:11 ZuluKing joined
01:11 Rotaerk_ joined
01:11 <ZuluKing> Hello guys! Really quick question
01:11 indi_ joined
01:11 ubsan_ joined
01:11 mkoenig joined
01:12 <ZuluKing> How do you execute something after a forever statement? Does forever work like a while loop or a new thread?
01:12 wroathe joined
01:12 felixsch_ joined
01:14 primal_ joined
01:16 <lyxia> it's a while loop
01:16 felixsch1 joined
01:16 Rotaerk joined
01:17 dkj0208_ joined
01:18 louispan joined
01:18 <lyxia> "execute" is ill defined however, there are monads for which forever z >> y does not ignore y
01:18 <pacak> @src forever
01:18 <lambdabot> forever a = let a' = a >> a' in a'
01:18 <lyxia> > runIdentity $ forever (return 3) >> return 4
01:18 <lambdabot> 4
01:19 <lyxia> > forever Proxy
01:19 <lambdabot> Proxy
01:19 lambdamu_ joined
01:19 <ZuluKing> Hmm.. I guessed so.
01:20 <ZuluKing> I figured out I need to use forkIO if I need to run forever like an independent/separate thread
01:20 saussure joined
01:20 <ZuluKing> Is that correct?
01:21 Rotaerk_ joined
01:21 <lyxia> @check (forever (return ()) >> return True :: Gen Bool)
01:21 <lambdabot> +++ OK, passed 100 tests.
01:21 <lyxia> ZuluKing: yes
01:22 exferenceBot joined
01:23 a3Dman joined
01:23 <ZuluKing> lyxia ok, thanks :)
01:23 <lyxia> there could be some variant of IO which runs independent actions in parallel, but the standard one doesn't
01:23 HoierM joined
01:24 ludat joined
01:28 Welkin joined
01:29 {emptyset} joined
01:31 <glguy> http://hackage.haskell.org/package/async-
01:31 mizu_no_oto joined
01:32 beekill95 joined
01:32 Rotaerk joined
01:32 oisdk joined
01:33 <lyxia> how wrong would it be to make it a Monad with stm + unsafePerformIO
01:34 <bigos> how do i flatten a nested list of tuples so i can obtain a flat list of tuples?
01:34 mac10688 joined
01:34 <bigos> something like that: [[(0,-1),(1,0)],[(1,0),(0,1)],[(0,1),(-1,0)],[(-1,0),(0,-1)]]
01:34 <glguy> > concat [[(0,-1),(1,0)],[(1,0),(0,1)],[(0,1),(-1,0)],[(-1,0),(0,-1)]]
01:34 <lambdabot> [(0,-1),(1,0),(1,0),(0,1),(0,1),(-1,0),(-1,0),(0,-1)]
01:35 <Koterpillar> > join [[(0,-1),(1,0)],[(1,0),(0,1)],[(0,1),(-1,0)],[(-1,0),(0,-1)]]
01:35 <lambdabot> [(0,-1),(1,0),(1,0),(0,1),(0,1),(-1,0),(-1,0),(0,-1)]
01:35 <bigos> thanks
01:36 <mniip> lyxia, you mean like
01:36 <mniip> a race condition in 'print x >> print y' ?
01:36 <lyxia> mniip: that's what Concurrently does
01:37 <Lokathor> I've got some rather complex nested tuples
01:37 <Lokathor> and i need to be able to update them and get new values back
01:37 <Lokathor> unfortunately, this sounds like a job for lenses
01:37 Rotaerk joined
01:37 <mniip> :t _1 . _2 . _1 . _3
01:37 <lambdabot> (Field3 a1 b1 a3 b3, Field1 a b a1 b1, Field1 s t a2 b2, Field2 a2 b2 a b, Functor f) => (a3 -> f b3) -> s -> f t
01:38 <Lokathor> yeah something like that
01:38 <Lokathor> they're newtyped, so i guess i need to generate lenses for those newtypes and stuff as well
01:38 <mniip> you could always reinvent your own mini-lens if you wanted to
01:39 <mniip> writing lenses requires no dependency on lens
01:39 <glguy> Complicated nested tuples sound like a job for something other than tuples, too
01:39 <Lokathor> http://lpaste.net/355926 this is, unfortunately, the exactly correct code to build up one cell grid of info
01:40 <Lokathor> and i need the bg, fg, and that second v2 there to all be "editable"
01:40 <Lokathor> I've dug my own troubles this time
01:40 rblaze joined
01:41 Rotaerk_ joined
01:42 <mnoonan> so I have this case statement that implements a T -> Int function on a sum type T with 2000 cases; ghc is warning me “Pattern match checker exceeded (2000000) iterations in a case alternative”. Is this something I should be concerned about?
01:43 <mniip> woah
01:43 <Lokathor> 2000 cases you say
01:43 <mnoonan> I know :|
01:43 <mniip> Lokathor, the checker is probably quadratic
01:43 <Lokathor> can you like... merge any of them?
01:43 <Gurkenglas> Lokathor, the lenses for bg, fg and that second v2 there would look something like "_CellTriangle . each . _CellTriangle . each . _VertexEntry . _3", "_CellTriangle . each . _CellTriangle . each . _VertexEntry . _4" and "_CellTriangle . _1 . _CellTriangle . _1 . _VertexEntry . _2"
01:43 <mnoonan> Unsurprisingly, it’s autogenerated from a hacky swig module and a bunch of static constants
01:44 <mniip> mnoonan, have you considered dataToTag# ?
01:44 <mnoonan> Lokathor: maybe, they fall into various groups with a common prefix to the name
01:44 flatmap13 joined
01:44 <mnoonan> mniip: I don’t know about that, what’s the idea?
01:44 <Lokathor> mnoonan, but they're not like, ranges of nums where you can just have a catch all and then use guards or something?
01:44 <mniip> you probably want an Array of Ints
01:44 <mniip> which you can then index with
01:45 <mniip> :t GHC.Prim.dataToTag#
01:45 <lambdabot> a -> GHC.Prim.Int#
01:45 jbiesnecker joined
01:45 <mnoonan> Lokathor: no, they represent AST node classes in a foreign api
01:45 <mnoonan> mniip, interesting
01:47 <Lokathor> Gurkenglas, I'll keep that in mind
01:47 <Lokathor> I can't focus too well today it seems; jiggering callbacks into the system was harder than i thought
01:49 <Lokathor> in the end i opted to just stuff everything into mvar and run sub-layers of the monad during the callback
01:50 Destol joined
01:52 birdgg joined
01:56 thebardian joined
01:57 flatstuff joined
01:58 tromp joined
02:00 hucksy_ joined
02:02 eschnett joined
02:02 texasmynsted joined
02:03 juanpaucar joined
02:05 conal joined
02:09 montagy joined
02:10 Johan_L joined
02:11 hamishmack joined
02:12 conal joined
02:17 <* glguy> has been playing with layouts https://glguy.net/3a0120d51b.png
02:18 Scip joined
02:20 nbro joined
02:20 benjic joined
02:23 eminhi joined
02:25 mzf joined
02:26 juanpaucar joined
02:26 benl23 joined
02:26 <Lokathor> so if you run makeLenses on a newtype, it just makes a lense of the name of the newtype's constructor?
02:28 dni joined
02:33 radi joined
02:34 p0a joined
02:35 zuck05 joined
02:42 exferenceBot joined
02:42 vlatkoB joined
02:45 jbiesnecker joined
02:46 conal joined
02:46 hexagoxel joined
02:46 HallaSurvivor joined
02:49 boid joined
02:50 halogenandtoast joined
02:50 {emptyset} joined
02:54 <Lokathor> Gurkenglas, it works!
02:54 felixsch_ joined
02:54 rblaze joined
02:55 aarvar joined
03:00 Scip joined
03:00 Oracio joined
03:06 systadmin joined
03:07 davr0s joined
03:12 jbiesnecker joined
03:14 <qmm> putting the following into .ghci doesn't seem to prevent the prelude from being loaded: :m -Prelude
03:16 <qmm> :set -XNoImplicitPrelude did it
03:17 Sonderblade joined
03:17 <qmm> is there a way to start ghci with a module and all of its exposed functions without needing to qualify them?
03:18 <qmm> :m +Foo imports the module, but i don't seem to have access to its functions or types without first qualifying them
03:19 davr0s joined
03:19 <vaibhavsagar_> qmm: what about `import Foo`?
03:20 <qmm> ah
03:20 <qmm> i didn't realize you could use import in the .ghci file :)
03:21 piyush-k` joined
03:22 mzf joined
03:23 meba joined
03:23 kyle1320 joined
03:27 flatstuff joined
03:29 tripped joined
03:32 <NextHendrix> why isn't 3 `(+)` 3 allowed
03:32 <NextHendrix> :[
03:33 <c_wraith> backticks only work around an identifier, not an expression
03:33 <c_wraith> something to do with ambiguous nesting being possible if it worked for full identifiers. best to just dodge that.
03:33 <c_wraith> uh, if it worked for full expressions
03:34 <NextHendrix> (`isInfixOf`) "lol" "lolol" is also not allowed
03:35 <glguy> `isInfixOf` isn't an operator symbol, which is what the () syntax expects
03:35 <NextHendrix> heh
03:35 anodium joined
03:36 <NextHendrix> so much for referential transparency
03:36 <glguy> That's not related
03:37 svgDelux joined
03:38 <NextHendrix> > a `plus` b = a + b
03:38 <lambdabot> <hint>:1:12: error:
03:38 <lambdabot> parse error on input ‘=’
03:38 <lambdabot> Perhaps you need a 'let' in a 'do' block?
03:38 <NextHendrix> > let a `plus` b = a + b
03:38 <lambdabot> <no location info>: error:
03:38 <lambdabot> not an expression: ‘let a `plus` b = a + b’
03:38 segmond joined
03:38 DigitalKiwi joined
03:39 <MarcelineVQ> > let a `plus` b = a + b in plus 2 3
03:39 <lambdabot> 5
03:40 <NextHendrix> well if a = b then i should be able to swap any a for any b anywhere in the Code
03:40 <NextHendrix> `plus` = (+)
03:40 <c_wraith> by value. not necessarily by token.
03:41 <NextHendrix> uh
03:41 sleffy joined
03:41 eSVG joined
03:41 harfangk joined
03:41 <c_wraith> You can't just swap in 3 + 4 for 7 in the expression 7 * 8
03:41 <NextHendrix> good point
03:41 baldrick1 joined
03:42 <* NextHendrix> goes back to work
03:43 saussure joined
03:43 davr0s joined
03:43 felixsch1 joined
03:44 sellout- joined
03:47 SeMas joined
03:47 <Koterpillar> I want to test something that uses forkProcess, getExecutablePath and executeFile to make more copies of itself. Is there any chance of passing all this through hspec?
03:48 juanpaucar joined
03:48 tristanp joined
03:52 tjayanth_ joined
03:53 <vaibhavsagar_> Koterpillar: how would you test it without hspec?
03:53 noam__ joined
03:53 <vaibhavsagar_> I'm picturing a test program that creates/updates a file or a counter somewhere when it is started
03:54 otto_s_ joined
03:54 beerdrop joined
03:54 <vaibhavsagar_> and you count the number of files or the counter
03:54 <Koterpillar> Yes, that's what I'm going to do
03:54 <Koterpillar> But executeFile will start executing hspec again
03:55 seanparsons joined
03:55 <vaibhavsagar_> sounds like you might want to write a separate test program that tests your main program?
03:56 <vaibhavsagar_> and you can limit your hspec-ing to the test program
03:56 Silentd joined
03:56 vlatkoB joined
03:56 besenwesen joined
03:57 DustyDingo joined
03:57 prkc joined
03:58 Moyst joined
03:59 Goplat joined
03:59 flashmozzg joined
04:00 michalrus joined
04:00 cgfbee joined
04:00 <Koterpillar> If I could hook beforeAll over the whole thing, I'd be fine
04:01 filterfish joined
04:03 path[l] joined
04:04 ianclark joined
04:05 boid joined
04:07 Bardusbasium joined
04:07 MJ joined
04:07 castlelore joined
04:09 dfranke joined
04:10 MJ_ joined
04:11 MJ_ joined
04:11 tristanp joined
04:11 path[l]_ joined
04:12 tronical1 joined
04:12 fragamus joined
04:12 infinity0 joined
04:14 tromp joined
04:15 saussure joined
04:15 sp0rke joined
04:19 Costar joined
04:21 eklavya joined
04:22 <lpaste> saylu pasted “aeson advice” at http://lpaste.net/355927
04:23 <saylu> Hey folks! I've got an object I'm trying to decode with Aeson and I'm getting a bit of a headache
04:23 <saylu> It's an object with a ton of fields, one of which is "rows". Within that field is an array of arrays -- each containing a path and a number
04:24 <saylu> ie. [["path", 5], ["path2", 10]]
04:24 <saylu> I've got no idea how to pull a `Text` out of the first index and an Int out of the second one with an Aeson parser
04:24 <saylu> Any advice for this?
04:24 saussure joined
04:25 revtintin joined
04:27 nbro joined
04:28 <lpaste> saylu revised “aeson advice”: “aeson advice” at http://lpaste.net/355927
04:29 darjeeling_ joined
04:30 <p0a> I'm using emacs with haskell-mode but the out of the box indentation is funny, what gives?
04:30 <pacak> saylu: v on line 15 is a vector.
04:31 <pacak> To get first/second fields in x and y you simply v ! 0 and v ! 1
04:31 dni joined
04:32 <saylu> Oh, ok!
04:33 <saylu> Then I'd need to parse the primitive
04:33 <pacak> saylu: Try to remove lines 16-18 and put a single underscore there. ghc will tell you type it expects and types of things available.
04:33 <pacak> Combine it with ghcid for profit.
04:34 baldrick1 joined
04:38 <lpaste> saylu revised “aeson advice”: “aeson advice” at http://lpaste.net/355927
04:38 <saylu> thanks pacak
04:39 <saylu> This doesn't parse, but it typechecks :p
04:39 <saylu> so, progress
04:40 zero_byte joined
04:40 <pacak> saylu: At random places of parser monad try adding
04:40 <pacak> error $ "parsed " ++ show x -- add this between lines 17 and 18
04:41 <saylu> Never hits
04:41 <saylu> Interesting
04:42 <pacak> Add more errors
04:42 <saylu> on it!
04:42 saussure joined
04:45 mbuf joined
04:46 <thang1> sweet
04:46 <thang1> jesus
04:47 <lpaste> saylu revised “aeson advice”: “aeson advice” at http://lpaste.net/355927
04:47 <thang1> I'm finishig up chapter 13 of haskell from first principles and I finished the hangman game
04:47 <saylu> Oddly enough -- I get the error 'Expected 'rows', got String'
04:47 <saylu> which is among none of my numerous errors
04:47 <thang1> I refactored the code to only count incorrect guesses when considering the lose condition and it worked the first time, I didn't even have to compile twice ;-; <3
04:48 <saylu> and only if I use 'parse' instead of 'parseMaybe'
04:48 <saylu> with 'parseMaybe' I get no errors, it goes straight to 'Nothing'
04:48 <EvanR> makes sense
04:48 <EvanR> thats what parseMaybe does
04:48 <saylu> reasonable
04:48 <thang1> EvanR: does that fun in refactoring ever get old in Haskell? :p
04:49 <* EvanR> looks at "experiment 18"
04:49 <EvanR> :(
04:49 <thang1> What's experiment 18?
04:49 <EvanR> the experiment after 17
04:49 <thang1> What's experiment 17?
04:49 <EvanR> you know
04:49 <thang1> What's experiment []?
04:49 <EvanR> type error
04:49 <glguy> obviously experiment 17 is the one before 18
04:50 sherub1 joined
04:50 <thang1> What's experiment 0 then :p
04:50 <* EvanR> checks
04:50 <glguy> who said anything about an experiment 0?
04:51 <EvanR> i deleted it
04:51 <thang1> Well if we're recursing down to zero I might as well get the base case experiment and then I can unfold it to figure out what experiment 18 is
04:51 <glguy> nope, we aren't
04:51 <thang1> ಠ_ಠ well whatever
04:51 <thang1> What's experiment 18 then? :p
04:51 <EvanR> i get to the end of a refactoring and only then realize im wrong
04:51 halogenandtoast joined
04:51 <EvanR> its getting out of hand
04:52 <EvanR> i probably need to figure out how to make it fun
04:52 <thang1> Have you tried refactoring it so you don't have to worry about hands?
04:52 jgertm joined
04:52 juanpaucar joined
04:54 dfeuer joined
04:54 Johan_L joined
04:55 Mortomes|Train joined
04:55 <EvanR> experiment 18 is a new programming language
04:56 <EvanR> with a different syntax semantics and type system
04:56 <thang1> oooh
04:56 <EvanR> thats what this has come to
04:56 <thang1> What are the novel aspects of the syntax and type system?
04:57 <EvanR> mostly off topic
04:57 <EvanR> i do have a custom calculus though
04:57 <thang1> eh. I would love to chat about it but I have some massive stuff due in 2 hours that I decided to put off and do chapter 13 in the haskell book instead
04:58 <EvanR> haskell has that effect
04:58 <thang1> But, I'd love to chat with you about it sometime (or read some docs or whatever) because I love learning about esoteric or interesting/novel programming languages and paradigms :p
05:00 <pacak> thang1: Esoteric programming languages - like php or java?
05:00 saussure joined
05:01 <thang1> Nah, I mostly mean esoteric in the sense that it explores some niche concept or original idea in PL theory
05:02 jhrcek joined
05:02 Guest40 joined
05:05 <mac10688> Hi
05:05 <mac10688> http://www.yesodweb.com/blog/2012/05/keter-its-alive
05:05 <mac10688> I'm trying to deploy my yesod webapp with keter
05:05 <mac10688> it talks about a hostname
05:05 <mac10688> is that the url that my website is associated with or is the hostname of the server?
05:06 <mac10688> for example, I can ssh into the linux server and type hostname and it gives me back another name that is different than my url
05:06 <pacak> 2012....
05:08 <p0a> Hey everyone, trying to write a hangman game. Here's my code http://lpaste.net/355931 the issue is that win doesn't work
05:08 <p0a> What I want win to do is not(find '_' (check secret guess)) but I was trying to be slick with compositions & pointfree and that didn't work out
05:08 texasmynsted joined
05:08 <EvanR> :t find
05:08 anodium joined
05:08 <lambdabot> Foldable t => (a -> Bool) -> t a -> Maybe a
05:08 jbiesnecker joined
05:08 dec0n joined
05:09 <EvanR> '_' is a Char not a function
05:09 <EvanR> oh, you defined your own
05:09 <p0a> yeah actually that find is not available for some reason. that's why I defined my own anyhow
05:09 <EvanR> to get better error messages, put top level type signatures on your functions
05:09 <kadoban> mac10688: Sounds like it's the hostname at which your website can be visited.
05:09 <p0a> alright let me try
05:09 <mac10688> thank you kadoban
05:10 meandi_2 joined
05:11 <EvanR> and the compiler error message points out something i noticed from looking at the definition of check, it takes two args, but you give it zero (leaving off 1 for composition usually makes sense)
05:11 nshepperd joined
05:11 <EvanR> but without a type sig not sure what win is supposed to be
05:11 <p0a> http://lpaste.net/355932
05:12 <p0a> with type signatures ^
05:12 <p0a> I want to run 'win secret guess' ==> True/False
05:12 <EvanR> maybe you want win secret = not . find '_' . check secret ?
05:12 <p0a> but why can't it be pointfree for 2 arguments?
05:12 <EvanR> because of the type of .
05:13 <p0a> oh I think I get it
05:13 filterfish joined
05:13 <p0a> oh it's one of those instances where to be pointfree you need to get out of your way
05:13 <EvanR> (f . g . h) x y = f (g (h x)) y
05:13 <p0a> yeah now it makes sense. in a chain of -> -> -> basically it's a -> (rest) not (rest) -> last
05:13 mzf joined
05:14 <p0a> right. thanks
05:14 <EvanR> (f . g .: h) x y = f (g (h x y))
05:14 <EvanR> but dont do that
05:14 Johan_L joined
05:15 <p0a> that looks weird
05:15 <EvanR> it is
05:15 <p0a> I thought : is cons. So .: is a thing on its own
05:15 <p0a> not related to cons
05:15 <EvanR> .: is a different operator
05:15 tristanp joined
05:15 <EvanR> like + and ++
05:15 <p0a> yeah
05:15 <p0a> no I won't do it because I won't remember it
05:16 <p0a> anyhow, thanks. I'll get back to it now
05:16 <pacak> There's package called plumbers...
05:17 danvet joined
05:18 saussure joined
05:20 baldrick1 joined
05:20 <p0a> :t first
05:20 <lambdabot> Arrow a => a b c -> a (b, d) (c, d)
05:20 <p0a> huh that's not what I thought
05:21 <EvanR> :t head
05:21 <lambdabot> [a] -> a
05:21 <EvanR> :t fst
05:21 <lambdabot> (a, b) -> a
05:21 <p0a> aha, head it is
05:21 <EvanR> head is usually not right
05:21 <pacak> p0a: It's partial function. It might explode...
05:21 <pacak> > head []
05:21 <lambdabot> *Exception: Prelude.head: empty list
05:21 <pacak> like this
05:21 <p0a> Hm... that should be ok. I'm doing c <- getLine
05:22 <EvanR> since it may crash. you have to have evidence (in your mind) that the list is not empty
05:22 <p0a> If c is empty I end the program, if not I want to use only the first letter entered
05:22 <EvanR> then you should use a case expression to switch on whether its empty or not
05:22 <pacak> p0a: Soo... case
05:22 <p0a> or perhaps I should allow the user to enter multiple letters if they wish to guess the word fully
05:22 <p0a> I think that's better in fact
05:22 <EvanR> you have the evidence, but its better to let the compiler remember it
05:22 <p0a> well the case was going to be there anyhow to end the program
05:23 <p0a> oh there's such an issue with letting the compiler know that it is indeed the case I'm not supplying [] ?
05:23 patbecich joined
05:23 <pacak> p0a: It's better to end the program with "OK, see you later" than with "Prelude.head: empty list".
05:23 <EvanR> case line of { [] -> endProgram; (c:cs) -> now c is what head would have been }
05:23 <p0a> oh right yes
05:23 <p0a> well hold on everyone let me write it first and then criticize hehe
05:24 <p0a> :t unique
05:24 <lambdabot> error: Variable not in scope: unique
05:24 <EvanR> :t nub
05:24 <lambdabot> Eq a => [a] -> [a]
05:25 <p0a> ah don't worry I don't mind re-writing some parts of the language
05:25 <p0a> I was just making sure it's not defined. I guess I'll do that in my ghci
05:25 <EvanR> let unique = nub? :)
05:25 <p0a> nub isn't even available
05:25 <p0a> are you saying I'm a nub? :P
05:25 <cocreature> note that since "nub" only requires Eq it has to be O(n^2)
05:25 <EvanR> you mean you forgot to import it?
05:26 <cocreature> there is nubOrd in some package which is usually preferrable
05:26 shangxiao joined
05:26 <pacak> :t Set.toList . Set.fromList
05:26 <lambdabot> error:
05:26 <lambdabot> Not in scope: ‘Set.toList’
05:26 <lambdabot> Perhaps you meant one of these:
05:26 <pacak> :t Data.Set.toList . Data.Set.fromList
05:26 <lambdabot> Ord a => [a] -> [a]
05:27 <pacak> p0a: unique + sort
05:27 <EvanR> i wonder if sort then nub is better than set, both dont let you get any results until the whole list is traversed
05:28 <EvanR> man keeping a list sorted really solves a lot of issues
05:28 <pacak> Or just use Set...
05:28 <cocreature> nubOrd from "extra" also keeps the resulting elements ordered by their first occurence iirc
05:28 <kadoban> If you want results early, probably filterM with a Set
05:28 <c_wraith> sort then nub does nothing.
05:28 <EvanR> Set cant be infinite
05:28 saussure joined
05:28 <cocreature> sort then map head . group
05:29 <cocreature> EvanR: you can’t sort infinite lists either
05:29 svgDelux joined
05:29 <kadoban> EvanR: Well, if you have an infinite list with an infinite number of different values in it, nothing can save you.
05:29 <EvanR> if its already sorted infinite is fine
05:29 <EvanR> hehe
05:29 <cocreature> so "sort then map head . group" is better if you don’t need to sort :)
05:30 <EvanR> > map head . group $ [1, 1, 1, 2, 2, 3, 3, 3, 3] ++ (repeat 4)
05:30 <lambdabot> mueval-core: Time limit exceeded
05:30 <EvanR> > map head . group $ ([1, 1, 1, 2, 2, 3, 3, 3, 3] ++ (repeat 4))
05:30 <lambdabot> mueval-core: Time limit exceeded
05:30 <EvanR> Y U NO
05:30 brynedwardz joined
05:31 <cocreature> > (take 4 . map head . group) ([1,1,1,2,2,3,3,3,3] ++ repeat 4)
05:31 <lambdabot> [1,2,3,4]
05:31 <EvanR> shouldnt it output 1 anyway
05:31 <EvanR> oh the bot
05:32 <kadoban> It probably doesn't try printing until it has all the results?
05:32 <cocreature> > [1..]
05:32 <lambdabot> [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,...
05:32 <cocreature> hm
05:32 <kadoban> Or at least as much as will fit in output
05:32 <cocreature> weird
05:32 <MarcelineVQ> did you try it in ghci?
05:32 <pacak> > group $ [1, 1, 1, 2, 2, 3, 3, 3, 3] ++ (repeat 4)
05:32 <cocreature> ah yeah mabye it’s waiting for how much fits in output
05:32 <lambdabot> [[1,1,1],[2,2],[3,3,3,3],[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,...
05:32 <EvanR> works in ghci
05:32 dni joined
05:32 <p0a> IO is harder than I thought
05:33 <pacak> p0a: Nah, it's just a burrito in a category of endofunctors.
05:33 <EvanR> O_o
05:34 <MarcelineVQ> EvanR: works as in terminates, or prints as it runs?
05:34 <EvanR> gets to 4 and hangs
05:34 <EvanR> i would question my sanity if it terminated
05:35 <kadoban> It'd be funny if GHC were that brilliant. Hmm, is GHC allowed to do that, or would it be illegal?
05:35 <EvanR> is [1,2,3,4] even the right answer
05:35 Itkovian joined
05:36 <EvanR> maybe provable with markovs principle
05:36 <c_wraith> Technically, a haskell compiler is allowed to introduce transformations that make code more defined. But in this case, you're very sensitive to the num instance in use
05:37 sssilver joined
05:37 <c_wraith> Well, and the Enum instance.
05:38 <EvanR> its supposed to give 1:2:3:4:⟂. youres saying its allowed to do something to cause 1:2:3:4:5:⟂ ?
05:38 fotonzade joined
05:39 <EvanR> ignoring the Num issue
05:39 <c_wraith> Well, no. But 1:2:3:4:[] is reasonable for a lot of types a
05:40 sternmull joined
05:40 <p0a> well I made it work after all. I had forgotten the $ after putStrLn
05:40 <EvanR> isnt that kind of like last ([0..] ++ [-3]) = -3 ?
05:41 <c_wraith> > last ([0..] ++ [-3]) :: Int8
05:41 <lambdabot> -3
05:41 <EvanR> confound it all!
05:41 <c_wraith> the choice of instance really does matter.
05:42 <EvanR> last time i brought up that expression, i wish someone woulda have pointed that out ;)
05:43 xtreak joined
05:43 <c_wraith> you could imagine a rewrite system targeting the combination of (++) and last such that if the right-hand argument is non-empty, it never examines the left-hand argument at all
05:43 <EvanR> i could, but i got a lot of flak for it last time
05:44 <EvanR> as if it violated some kind of law
05:45 <c_wraith> well it's hard to work with in a rational way. list fusion is touchy enough.
05:45 halogenandtoast joined
05:45 <EvanR> in what sense is it really the last element
05:45 <c_wraith> can you imagine all those sorts of ad-hoc rules?
05:45 noraesae joined
05:45 <EvanR> conceptually there isnt a last element
05:45 <EvanR> its just a funny metaphor to say -3 is last
05:46 saussure joined
05:47 Rakkattakka joined
05:47 <c_wraith> depends on how you're counting. If you're using ordinal numbers.. sure there is. it's at index ω + 1
05:47 <EvanR> yet we have the long line and its path connected
05:48 Gurkenglas joined
05:48 <p0a> Hah! Did it: http://lpaste.net/355934
05:48 zaquest joined
05:48 <p0a> I present to you my Hangman text game
05:49 <EvanR> did you know you dont have to indent then and else
05:49 <EvanR> it can go below the if
05:49 <p0a> developed past curfew
05:49 <c_wraith> EvanR: that actually depends on the GHC version. Older versions - it did have to be indented.
05:49 <p0a> EvanR: I hate this indentation. I'm not sure what haskell-mode is doing but I have to do a lot of manual stuff
05:49 <LiaoTao> p0a: Now make it read a random word from a dictionary and you're set to make some dough
05:50 <EvanR> 10 25 33 too many parens
05:50 <EvanR> 16 eta reduce
05:50 <EvanR> c_wraith: ah so im not crazy. i do remember it being nec
05:50 <EvanR> 38 too many parens
05:51 <p0a> I know that I was using too many parens here and ther
05:51 <p0a> I just didn't want to accidentally use less than enough
05:51 takuan joined
05:51 <p0a> every compilation error costs much more than parentheses keystrokes at this time of the day
05:52 <EvanR> luckily this isnt lisp !
05:52 <p0a> lol
05:52 osa1 joined
05:53 eklavya_ joined
05:54 <EvanR> next exercise, make a higher order function which shows the prompt, puts the input through a function to get an output message and a new prompt, then implement hangman with it
05:54 <EvanR> bonus points for keeping state and exiting
05:55 <EvanR> when its perfect, copy it so you can use it later, and wish it was in prelude
05:56 eklavya joined
05:56 ThomasLocke joined
05:56 ThomasLocke joined
05:56 aarvar left
05:57 <halogenandtoast> p0a: for comparison here is my Hangman game in Haskell: https://github.com/halogenandtoast/hangman-haskell
05:57 juanpaucar joined
05:57 <halogenandtoast> everything in IO is in Main.hs everything else is in Game.hs so I could switch out the UI quite easily
05:58 <p0a> halogenandtoast: ah, this is interesting
05:58 <p0a> I see you used states too. I like that
05:58 jgertm joined
05:58 <p0a> it didn't occur to m
05:59 <p0a> EvanR: is this what you meant?
05:59 <p0a> basically what halogenandtoast did?
05:59 <p0a> I think I might study your code tomorrow as my "next exercise"
05:59 <EvanR> you dont really have any state
06:00 <p0a> well the two arguments to hangman are the state
06:00 <EvanR> oh yes, the accumulated guess
06:00 <EvanR> you dont change the secret so its not really stateful
06:00 <EvanR> but yeah
06:00 <p0a> I could've captured it with a helper function
06:01 <p0a> idk. in FP sometimes I feel awkward trying to unthink procedurally
06:01 <halogenandtoast> p0a: it takes time, eventually FP takes over and it becomes harder to this procedurally (imperatively?)
06:02 <halogenandtoast> s/this/think/
06:02 <EvanR> repl :: String -> s -> (String -> (String, s)) -> IO ()
06:03 <EvanR> hangman secret = repl "What do you guess? " blank (guts secret)
06:04 <p0a> what?
06:04 <EvanR> i guess that wouldnt really help, because you type the prompt message twice ;)
06:04 saussure joined
06:04 <p0a> did you hack my game?
06:04 <EvanR> just refactored to take the main loop apart
06:05 <EvanR> repeatedly asking for input with a message and getting a response + new state is common enough
06:05 <p0a> oh I see
06:05 <p0a> yeah no that code definitely can be refactored
06:06 <p0a> thanks for the help
06:08 zero_byte joined
06:08 {emptyset} joined
06:10 <saylu> by the way -- pacak: -- parsing an array already parses everything within it as a string, apparently, so doing `fmap read $ parseJSON (vector ! 0)` handles it fine. No errors.
06:10 <lpaste> saylu revised “aeson advice”: “aeson advice” at http://lpaste.net/355927
06:10 <saylu> thanks for your help pacak
06:11 <pacak> > read "not an int"
06:11 <lambdabot> *Exception: Prelude.read: no parse
06:11 <pacak> saylu: ^
06:11 <EvanR> > read () -- not an int
06:11 <lambdabot> error:
06:11 <lambdabot> • Couldn't match type ‘()’ with ‘[Char]’
06:11 <lambdabot> Expected type: String
06:11 <EvanR> > read "()" -- not an int
06:11 <lambdabot> ()
06:12 <pacak> > read "not an int" :: Int
06:12 <lambdabot> *Exception: Prelude.read: no parse
06:12 <pacak> EvanR: In his code he reads into Int.
06:13 osa1 joined
06:13 <pacak> > (reads :: ReadS Int) "1"
06:13 <lambdabot> [(1,"")]
06:13 <pacak> > (reads :: ReadS Int) "not an int"
06:13 <lambdabot> []
06:14 saussure joined
06:14 primal joined
06:14 tromp joined
06:15 Itkovian joined
06:17 quchen joined
06:19 <EvanR> is there a slick way to clamp an Integer to the bounds of Int
06:19 <EvanR> instead of
06:19 <EvanR> > fromInteger 100000000000000000
06:19 <lambdabot> 100000000000000000
06:19 <EvanR> > fromInteger 1000000000000000000000
06:19 <lambdabot> 1000000000000000000000
06:20 <EvanR> > fromInteger 1000000000000000000000 :: Int
06:20 <lambdabot> 3875820019684212736
06:23 <MarcelineVQ> why does that result in that particular number
06:23 <EvanR> wrapping
06:23 eklavya joined
06:23 <EvanR> > fromInteger 100000000000000000000 :: Int
06:23 <lambdabot> 7766279631452241920
06:24 <MarcelineVQ> ah hmm, did you want wrapping?
06:24 <EvanR> no, clamping
06:25 Mortomes|Work joined
06:25 <sternmull> if you only fear overflow when reading data then you could use an explicit clamp-function.
06:26 <EvanR> its a conversion from Integer to Int
06:26 <EvanR> rather than string to int
06:27 aarvar joined
06:27 FreeBirdLjj joined
06:28 <quchen> :t max (fromIntegral (minBound :: Int)) . min (fromIntegral (maxBound :: Int))
06:28 <lambdabot> (Num c, Ord c) => c -> c
06:28 <EvanR> ah
06:28 <quchen> > max (fromIntegral (minBound :: Int)) . min (fromIntegral (maxBound :: Int)) $ 1000
06:28 <lambdabot> 1000
06:28 <quchen> > max (fromIntegral (minBound :: Int)) . min (fromIntegral (maxBound :: Int)) $ 2^123
06:28 dejanr_ joined
06:28 <lambdabot> 9223372036854775807
06:28 <quchen> > max (fromIntegral (minBound :: Int)) . min (fromIntegral (maxBound :: Int)) $ 2^1234
06:28 <lambdabot> 9223372036854775807
06:28 <quchen> > max (fromIntegral (minBound :: Int)) . min (fromIntegral (maxBound :: Int)) $ - (2^1234)
06:29 <EvanR> :thumbsup:
06:29 <lambdabot> -9223372036854775808
06:31 saussure joined
06:32 <quchen> Turns out () is not Num!
06:32 <quchen> Strange.
06:33 <quchen> Otherwise you could clamp an Integer to () ;-)
06:33 <EvanR> not much of a number
06:33 <quchen> () is a good number!
06:33 alfredo joined
06:33 <EvanR> 1 ?
06:34 <quchen> Or π or whatever. There is only one number, so there’s not much to tell it apart from.
06:34 <quchen> () + () = ()
06:34 <quchen> () * () = ()
06:34 <EvanR> i guess you cant tell, since signum () = ()
06:34 <quchen> - () = ()
06:34 <quchen> > - (1 :: Word8)
06:34 <lambdabot> 255
06:34 yoneda joined
06:34 <EvanR> isnt a ring axiom that 0 and 1 are not the same
06:35 <mniip> not...really
06:35 <EvanR> ok
06:35 <quchen> I don’t think it’s an axiom, but if you have 0=1 you get the trivial ring
06:35 <mniip> but if 1=0 then evrything else is =0=1
06:35 <EvanR> its a field axiom
06:35 <mniip> not necessarily either
06:35 <mniip> but same
06:35 <opqdonut> https://en.wikipedia.org/wiki/Field_with_one_element
06:35 <opqdonut> :)
06:35 <mniip> if 0=1 then there's only one element
06:36 <EvanR> "all fields must contain at least 2 distinct elements"
06:36 bendo joined
06:36 ertes joined
06:37 <opqdonut> the report doesn't say Num needs to be a field
06:37 <EvanR> nor a ring
06:37 uniclown joined
06:37 <EvanR> but a number type where the "spirit" of the value may be 0 or 1 or pi....
06:37 <EvanR> and thats the only value
06:37 <quchen> opqdonut: That would be bad, since Double isn’t a field
06:38 <quchen> I’m not sure whether Double is anything from Algebra even
06:38 <EvanR> a commutative magma !
06:38 <quchen> Is it commutative? I don’t know.
06:38 <opqdonut> :)
06:38 <quchen> It’s certainly not associative, so even Monoid is out.
06:38 <mniip> I'm pretty sure it is commutative
06:38 connrs joined
06:38 <mniip> though
06:39 <mniip> that depends
06:39 eminhi joined
06:39 <mniip> before sse, double wasn't even a magma
06:39 <mniip> + wasn't an operation per se
06:39 <mniip> you could have a + b != a + b
06:40 <quchen> A magma allows that.
06:40 <mniip> does it
06:40 <quchen> Sure, a magma is just that (+) is there without any other laws
06:40 <EvanR> does any of these things pay any detail to the "setoid" equivalence
06:40 <quchen> Well, it should be total, but that’s implicit since (+) should be a function
06:40 <EvanR> doesnt seem so
06:40 <mniip> quchen, pretty sure it requires + to be a function
06:41 <quchen> What else would + be?
06:41 saussure joined
06:41 <mniip> x87 + doesn't distribute with equality
06:41 <EvanR> if + gives random results... its a probablistic function ;)
06:41 <quchen> s/a probabilistic/not/
06:42 <EvanR> a random variable
06:42 dni joined
06:43 <mniip> in the category of random distributions
06:43 <mniip> I could see 'a probabilistic function' be a good candidate for an exponential object
06:43 beekill95 joined
06:44 indi_ joined
06:44 dni joined
06:45 <mniip> not sure how to bind 'category of random distributions' to mathematics
06:45 <mniip> needs some kind of generic integral
06:46 indi__ joined
06:49 <EvanR> goofy.. forall r . in an instance head so i can scoped type vars later
06:49 govg joined
06:49 <EvanR> in the instance def
06:49 tsmish joined
06:49 <EvanR> is that how you normally have to do it to use proxies
06:50 fooflare joined
06:50 <johnw> proxies usually need the type var to be scoped over the definition, yes
06:50 im0nde joined
06:52 dni joined
06:52 fooflare left
06:53 halogena1dtoast joined
06:54 sherub1 joined
06:55 plutoniix joined
06:55 <nshepperd> + and * are commutative in IEEE 754
06:56 <nshepperd> up to "which NaN you get" anyway
06:56 angerman joined
06:56 evanpro joined
06:56 plutoniix joined
06:58 plutoniix joined
06:59 saussure joined
06:59 avn joined
06:59 eklavya joined
07:01 juanpaucar joined
07:01 xtreak joined
07:02 ccomb joined
07:04 montagy joined
07:04 slomo joined
07:04 slomo joined
07:04 ventonegro joined
07:06 Itkovian joined
07:07 guiben joined
07:09 <nshepperd> i guess the actual + in your program may be not commutative to the extent that it doesn't implement IEEE 754 due to "tricks" like 80 bit registers
07:09 <mniip> like I said, x87
07:10 btk joined
07:10 <nshepperd> but then, i dunno. if a + b != a + b because in one case a is an 80 bit register variable, is it really the same a?
07:11 vbCrLf joined
07:11 <mniip> the case that can be exhibited on a modern compiler is a + b = load(store(a + b))
07:12 <mniip> where store :: 80bit -> Word64; load :: Word64 -> 80bit
07:13 defstryker joined
07:13 <defstryker> hello people
07:13 <thang1> hello person
07:14 <defstryker> just starting out haskell for project euler :D
07:14 davr0s joined
07:14 <thang1> Neat! Any prior experience with Haskell?
07:14 <nshepperd> (a + b) - x != load(store(a + b)) - x, where x cancels most of the bits of a + b?
07:15 mou joined
07:15 <defstryker> Just a little. Going through real world haskell and lyah
07:15 romank joined
07:15 <defstryker> Might look at the writing a compiler using haskell
07:16 <mniip> nshepperd, without x even
07:16 <mniip> you can get != due to rounding induced by 'store'
07:16 <mniip> if you use 80-bit comparison
07:16 <nshepperd> != by 80 bits standards, sure
07:16 vlatkoB_ joined
07:16 <thang1> You might have a touch of trouble writing haskell Euler solutions concisely, but you should be able to get there hopefully!
07:17 saussure joined
07:17 <defstryker> have done the first five this morning, hopefully the rest goes well too.
07:17 uniclown joined
07:18 jgt joined
07:18 <thang1> What was your solution for problem 1? Just out of curiosity :p
07:19 <nshepperd> i guess you shouldn't be surprised if a random 80 bit format fails to obey any axioms after being mutilated by rounding it through float64
07:20 <defstryker> @thang1 this i believe: sum [x | x <- [1..999], mod x 3, mod x 5]
07:20 <lambdabot> you are welcome
07:20 <mniip> nshepperd, yes but it C it looks like a + b != a + b
07:21 tiny_test joined
07:21 <EvanR> laws shmaws
07:21 <mniip> int test(double a, double b, double ab) { return a + b == ab; }; test(x, y, x + y);
07:21 <EvanR> you dont want to be limited by laws do you, be more dynamic
07:21 <thang1> defstryker: that's a pretty good solution, actually.
07:21 whald joined
07:22 <defstryker> thanks
07:22 zariuq joined
07:22 <mniip> defstryker, you forgot == 0
07:22 ericsagnes joined
07:22 <mniip> defstryker, your nickname seems familiar...
07:23 <kadoban> It becomes a much more interesting problem when n is much much greater than 1000, heh.
07:24 jellie joined
07:24 JScully joined
07:24 <thang1> Then you want to do things like generating lazy wheels :p
07:24 jellie joined
07:24 stay_noided joined
07:24 jellie joined
07:24 meba joined
07:25 <kadoban> Naw, you can do better than that. There's a closed form solution, no looping at all.
07:25 <thang1> Oh right, because you're finding the sum
07:26 <kadoban> Yep
07:26 <nshepperd> if you're going to apply 80 bit standards, that is a + b != roundToFloat64(a + b)
07:26 <thang1> sum . takeWhile (<10000) $ filter (\n -> (n `mod` 3 == 0) && (n `mod` 5 == 0)) [1..] -- My super lazy and ugly solution without list comprehensions
07:26 <nshepperd> what C makes it looks like is C's problem :p
07:26 cur8or joined
07:26 raichoo joined
07:26 saussure joined
07:27 bvad joined
07:29 zuck05 joined
07:29 <thang1> damnit, kadoban, ya nerd sniped me
07:29 <thang1> Now I gotta know what this closed form is :p
07:30 <kadoban> ;)
07:30 systemfault joined
07:31 <kadoban> Want hints?
07:31 <thang1> Hmm... Divisible by 3 and 5 is equivalent to multiples of 15, yes?
07:32 <kadoban> I think the actual problem is the sum of the numbers divisible by 3 *or* by 5, but I could be wrong. But it's not much harder either way I don't think.
07:32 <thang1> oh whoops, it is 3 or 5
07:32 <pacak> That's 3 or 5, not and.
07:32 spinus joined
07:33 <thang1> In that case you can just do the individual closed form sum of numbers mod 3 and closed form sum of numbers mod 5 and add the two together, yes?
07:33 <pacak> thang1: No.
07:33 <* thang1> should stop ending sentences with 'yes'
07:33 Ephemera joined
07:33 <kadoban> Almost, need a correction
07:33 balor joined
07:33 thc202 joined
07:34 <thang1> Oh right, throw out duplicates first :p
07:34 albertus1 joined
07:34 lae_ joined
07:35 merijn joined
07:35 albertus1 joined
07:35 <\u> konhow to typeset the ArrowChoice law $left (f \ggg g) = left f \ggg left g$ in latex?
07:36 <* nshepperd> draws a venn diagram
07:36 <\u> Are there any Arrow papers using (+++ ||| &&& ...) available in latex...
07:36 cic joined
07:38 <thang1> kadoban: Is there a direct closed form that computes the answer in one summation? Or is it the two summations added together?
07:39 <kadoban> Mine would be based on "the sum of the multiples of k up to n" used 3 times. I assume there's other ones though.
07:39 raichoo joined
07:39 defstryker joined
07:40 <thang1> 3 times? So sum of multiples of 3, sum of multiples of 5, minus the sum of multiples of 15? That's a lot neater than what I was thinking of :p
07:40 <kadoban> Yeah
07:40 Cerise joined
07:41 <thang1> I was thinking of embedding the subtraction of the third sum inside the iteration condition of one of the other two somehow
07:41 justanotheruser joined
07:41 <pacak> You don't need iterations.
07:41 connrs joined
07:42 thunderrd__ joined
07:42 <kadoban> Ah. That's probably possible, but then you have to actually do iteration most likely. You only need a constant number of multiplications, divisions and additions totaly
07:44 <pacak> [3, 6 ... n] => 3 * [1, 2 ... n / 3] => 3 * [1 + n / 3, 2 + n/3 - 1, ...] => ....
07:44 primal__ joined
07:44 <thang1> I know I don't need iterations, which is why it was bugging me that I was only thinking of that solution :p
07:45 mekeor joined
07:45 <thang1> Well, my (sum []) + (sum []) - (sum []) takes up 1/6th the memory that my sum . takeWhile ... solution does
07:46 <thang1> seems to be a touch faster too
07:46 MarcelineVQ joined
07:46 <Guest13355> faster how? due to the number of computations?
07:47 <thang1> "touch faster" nvm it's waaaay faster
07:47 <thang1> sum . takeWhile (<100000) $ filter (\n -> (n `mod` 3 == 0) || (n `mod` 5 == 0)) [1..] -- This is my "original solution"
07:47 <kadoban> It should be way way faster, yeah. It's considering fewer numbers, and it's only doing additions
07:47 <pacak> Like O(n) vs O(1) faster.
07:47 twanvl joined
07:47 <kadoban> Well, and a subtraction, but w/e. It avoids `mod` anyway.
07:47 <thang1> You have 2 mod functions, 3 comparisons, a filter, a takeWhile comparison, and a sum
07:48 <kadoban> pacak: I think they're talking about just directly doing the iteration for each, though I'm not sure.
07:48 <thang1> (sum [3,6..100000]) + (sum [5,10..100000]) - (sum [15,30..100000]) -- This is the "closed form" solution
07:49 <thang1> Direct summations, no comparisons, nothing like that, just raw optimized assembly loops and plain integer arithmetic
07:49 <pacak> I think there's one more task on project euler with the same description but with something much bigger than 100k so it can't be calculated with loop in same time.
07:49 <pacak> *sane
07:49 root____ joined
07:49 <kadoban> Ah, is there? That's good. I couldn't remember if there was.
07:49 TheFuzzball joined
07:49 biglama joined
07:50 <thang1> Disappointed that ghci is only using one core...
07:50 <merijn> thang1: ghci is shit if you want speed anyway
07:50 saussure joined
07:50 <merijn> thang1: It's interpreting bytecode and doesn't do much optimisation
07:50 <merijn> thang1: Simply compiling is basically always significantly faster
07:51 <thang1> eh, fair
07:51 <Itkovian> shapr: next attempt at introducing some haskell at work https://hackage.haskell.org/package/hnormalise
07:51 jbiesnecker joined
07:52 <pacak> merijn: There's -fobject-code
07:53 <merijn> pacak: Right, but that's basically the same thing as compiling and then loading compiled code into ghci :p
07:53 <merijn> pacak: So you might as well compile
07:53 acidjnk22 joined
07:55 <thang1> interesting...
07:55 <* nshepperd> wonders what pacak is saying with [1 + n / 3, 2 + n/3 - 1, ...]
07:55 target_i joined
07:55 <nshepperd> can't you just apply the triangle formula already?
07:55 saussure joined
07:56 <pacak> nshepperd: You can if you know it. If you don't - from what I wrote it should be obvious what to do next.
07:56 <thang1> I think I'm using some compiled code in ghci
07:57 Yuras joined
07:57 <nshepperd> oh, you're doing the summing from both ends trick
07:58 <thang1> @let fibs = (1 :: Integer) : scanl (+) 1 fibs
07:58 <lambdabot> Defined.
07:58 <thang1> > sum . takeWhile (<4000000) $ filter (even) fibs -- Is this supposed to be stupidly fast and memory efficient?
07:58 <lambdabot> 4613732
07:59 <kadoban> Well, probably because there's not many fibs less than that and it's computing them quite efficiently.
07:59 <merijn> thang1: parens around even are redundant
07:59 <merijn> thang1: It's just "filter even fibs"
07:59 mattyw joined
08:00 bollu joined
08:00 <thang1> Thanks. It's a force of habit from doing things like filter (/= thing)
08:00 <merijn> thang1: I would expect that to be stupid fast, yes
08:00 <merijn> thang1: It's building the list fairly efficiently, and I think scanl, takeWhile and sum are all "well-behaved" producers/consumers (i.e. they can be fused)
08:00 <thang1> Okay, because to me it looks like it's optimizing away the list entirely and I wanted to make sure I wasn't thinking about it wrong :p
08:00 juanpaucar joined
08:00 <merijn> So I would expect GHC to fuse the entire thing and optimising the list generation away
08:01 <merijn> thang1: I would expect it to optimise the list away, yes
08:01 <nshepperd> (i bet there's a fancy O(log n) constant memory solution for that too)
08:01 <thang1> > sum . takeWhile (<40000000000000000000000) $ filter (even) fibs -- Yeah this takes like 0.01 seconds on my computer
08:01 <lambdabot> 21783388129427422369052
08:02 <merijn> thang1: I would expect GHC to turn that into a crazy optimised libgmp loop :)
08:02 <* thang1> is highly amused that he typed the exact same amount of zeros by holding down repeat and eyeballing it
08:02 <merijn> thang1: And GHC is pretty damn good at using GMP
08:02 <nshepperd> or maybe log (log n), what with fibs getting exponentially bigger
08:02 <thang1> To be fair, gmp is pretty great
08:02 eSVG joined
08:02 <merijn> thang1: Yeah, but have a look at how amazing GHC is at using it: http://www.wilfred.me.uk/blog/2014/10/20/the-fastest-bigint-in-the-west/
08:03 <nshepperd> the normal "linear" solution would be log n already, because of that
08:03 <thang1> nshepperd: Well, there is a closed form of the fibonacci sequence
08:04 <kadoban> Note that it barely matters if it gets rid of the list or not. A list of what, a couple of hundred items is nothing.
08:04 <thang1> True, that's a good point that I was missing
08:04 <merijn> kadoban: Also true
08:05 <merijn> > length . takeWhile (<40000000000000000000000) $ filter even fibs
08:05 <lambdabot> 36
08:05 radi joined
08:05 <merijn> oh...that's shorter than I expected
08:05 <thang1> hah, that surprised me too
08:05 <kadoban> Yeah, me too
08:05 <merijn> > length . takeWhile (<40000000000000000000000) $ filter odd fibs
08:05 <lambdabot> 73
08:05 <thang1> ahh there we go. Fibonacci just heavily favors odd numbers
08:06 <merijn> Even then, that's short :)
08:06 <merijn> So even just summing the entire thing will be quick
08:06 Beetny joined
08:06 Xion_ joined
08:06 <thang1> So apparently the closed form of the summation of the fibonacci numbers is F_(2n+2) - 1 if I'm reading this stack overflow exchange thing right
08:07 <kadoban> This is what amuses me about fibs, the comparative interest in really quick solutions to nth fib ... when if you actually go high enough for it to matter, you're well on your way to using all of physical memory. Unless you do them modulo some number or whatever.
08:07 <ventonegro> Doing `:sprint fibs` after the summation still prints `_`
08:07 <ventonegro> Is that due to fusion?
08:08 <thang1> kadoban: you should see people furiously computing busy beaver functions :p
08:08 <kadoban> :)
08:08 <thang1> "yeah so we can't even represent this number in ZFC... but isn't it totes cool?"
08:08 <MarcelineVQ> ventonegro: use a concrete type for your numbers, chances are the use of some typeclass is causing _
08:08 <merijn> ventonegro: Sounds like DMR to me :)
08:08 <merijn> Or rather
08:08 <ventonegro> oh
08:09 <merijn> The absence of monomorphism restriction in ghci
08:09 <nshepperd> kadoban: it's important to fill up your physical memory efficiently!
08:10 <kadoban> nshepperd: Haha, indeed
08:10 <ventonegro> Setting the type to [Integer] did it
08:10 saussure joined
08:10 <kadoban> It's also funny when the computational model breaks to hell, when you assume that addition is constant cost.
08:10 <thang1> Oh, whoops. Sum_{i = 1}^n F_i = F_{n + 2} - 1
08:11 <thang1> kadoban: you mean to say that constants matter in algorithmic complexity? Blasphemy. CS only cares about the numbers - inf, 0, 1, 2, inf /s
08:11 <thang1> (and -1 sometimes)
08:12 <merijn> ventonegro: Incidentally, this is why the monomorphism restriction is a good thing. In compiled files it prevents you from accidentally recomputing that list every time (since it either 1) specialises the type or 2) produces a compile error)
08:13 <kadoban> Well, more saying that it matters what your computational model is, and that it does something approximating sanity. But yes that too.
08:13 <nshepperd> thang1: is the story more complicated if the fibs are filtered for even?
08:13 <thang1> Vaguely so, but fibs are pretty nice in this regard
08:13 <kadoban> Every third one is even, right?
08:13 <kadoban> Which could help, but it still seems complicated.
08:13 <thang1> Sum of first odd fibs are F_(2n), sum of first even fibs is F_(2n + 1) - 1
08:14 toby1851 joined
08:14 <thang1> And the sum of the squares of the first n fibs is F_n * F_(n+1)
08:14 henriksod joined
08:15 saussure_ joined
08:15 <* hackage> prettyprinter 1, prettyprinter-compat-ansi-wl-pprint 1, prettyprinter-compat-annotated-wl-pprint 1, prettyprinter-ansi-terminal 1 (quchen): https://qbin.io/e5ao072
08:16 <nshepperd> convenient
08:17 <nshepperd> i think by default I would reach for... a six by six matrix, or something. to add up the sum of every third directly
08:18 <merijn> quchen: \o/
08:18 <quchen> merijn: :-)
08:18 castlelore joined
08:18 castlelore joined
08:18 <quchen> merijn: Ran out of reasons not to release it officially. Reddit etc. coming soon.
08:18 thebardian joined
08:18 path[l] joined
08:19 <merijn> quchen: Now to hassle edwardk into updating Trifecta so I can migrate my language's prettyprinter ;)
08:19 PotatoCommando joined
08:19 eatman joined
08:19 <quchen> Hehe
08:20 <thang1> Why Trifecta over megaparsec?
08:20 <merijn> thang1: Prettier error reporting
08:20 <thang1> Like, more useful or just prettier?
08:20 <merijn> Mostly just prettier :p
08:21 <nshepperd> huh. the matrix trick really works for any loop where the iteration step is a linear function
08:21 <thang1> Seems like a silly reason to yank in all of lens just for a parser :p but, more power to you
08:21 <merijn> thang1: Like, coloured/underlined output highlighting the parser error location (similar to what e.g. clang produces)
08:21 <thang1> Oooh, that's actually pretty neat tbh. I would've thought megaparsec did that
08:22 <merijn> thang1: trifecta/parsec are really for "library parsers" anyway, more userfacing/application parsers (i.e. compilers, in my case), so who cares about dependencies, only build them once anyway :)
08:24 saussure joined
08:24 <quchen> thang1: Prettier errors means a dramatically better parser lib.
08:25 <quchen> thang1: Try using Idris, and compare its errors to Haskell’s.
08:25 <merijn> quchen: GHC8 and later are improving *a lot*
08:25 <quchen> Idris uses Trifecta, and its errors are pretty awesome.
08:25 arpl joined
08:25 <quchen> Improving isn’t enough to compete here – Idris is *way* ahead of GHC.
08:26 <quchen> Not to bash on GHC, but to emphasize how useful good parser errors are.
08:26 darjeeling_ joined
08:27 netheranthem joined
08:29 <cocreature> quchen: yeah \o/
08:29 kuribas joined
08:29 <thang1> merijn: makes sense. I wouldn't have thought about the dependency issues that way
08:29 <cocreature> quchen: what kind of changes do you need in trifecta?
08:30 ub joined
08:30 <kuribas> What's a good image processing library? I looked at hackage, but I find a lot of fragmentation.
08:30 <merijn> cocreature: I think it's just replacing the dependency with the compat shim?
08:30 <Xion_> GHC aren't too bad tbh, and I'm comparing them with rustc which has *marvellous* error reporting.
08:30 <Xion_> One thing that would be useful was quoting the line instead of just giving a number.
08:30 <thang1> I wonder what rustc uses for their errors
08:30 mmn80 joined
08:30 <quchen> cocreature: Change the dependency mostly
08:31 <* nshepperd> finds that the best way to deal with libraries depending on lens is to already have lens built :p
08:31 <cocreature> oh right, I forgot that trifecta includes pretty printing
08:31 <thang1> And tbh the things I would like most with ghc's errors is just reducing the amount of data that's shown
08:31 <quchen> cocreature: The drop-in compatibility modules solve the migration problem, but it would need maybe 15 minutes of work to do the proper switch
08:31 <cocreature> Xion_: GHC’s compile errors aren’t so bad. GHC’s parse errors are terrible
08:31 <merijn> The One Prettyprinter, that binds them all ;)
08:31 <Xion_> Yeah, all these "in the second argument of" could be just shown visually with an ASCII art arrow
08:31 <thang1> Right, their parse errors make me want to shoot myself :p
08:32 <Xion_> cocreature: I've mostly seen them as "parse error at line X", and the X was correct more often than not :)
08:32 <thang1> like 4 lines of boilerplate before you even get to the error, then there's an entire pargraph describing where in the code in the error was, and the 5 words of relevant information are buried somewhere in the middle
08:32 mattyw joined
08:33 <thang1> repeat for /every/ single parse error, of which there will likely be at least 2-4 for every typo you make because haskell is very terse and if you mess one thing up you probaby messed up a few others too
08:33 <MarcelineVQ> the ghc team is always looking for a hand if you find the desire to improve the error messages
08:34 <thang1> Sure. My proposal got shot down for summer of haskell anyway.
08:34 <thang1> What does ghc use for error messages anyway? Parsec internally?
08:34 <cocreature> MarcelineVQ: well improving the parser errors would probably require moving away from alex/happy and that has quite a few downsides as well
08:34 <cocreature> thang1: alex/happy
08:34 ErinvanderVeen joined
08:34 <thang1> right... alex and happy.
08:35 <thang1> So, what are some of the downsides to not using alex and happy? They seem like huge projects in haskell lore yet I almost never see anyone talk about them
08:36 <merijn> thang1: alex/happy are basically "haskell lex & yacc"
08:36 <cocreature> thang1: you need to left factor your grammar
08:36 <merijn> So, parser generators. The advantage of those is: They generate efficient parsers. The downside, it's a pain
08:36 <merijn> cocreature: I think both happy and bison are GLR nowadays
08:37 <cocreature> merijn: I was talking about the downsides of _not_ using alex/happy, i.e., using parsec or something like that
08:37 <thang1> ah, right.
08:38 <merijn> Well, you don't have to left-factor your grammar, you could just write a REALLY slow parser :p
08:38 <thang1> Is there no way to use something like alex and happy and then just plug things into a pretty printing capable parser?
08:38 <cocreature> merijn: well your error messages also become crappy if you just use "try" everywhere so you loose one important benefit of using them over alex/happy
08:39 <merijn> cocreature: Well, that's why you should be careful with where you put try :p
08:39 <thang1> Because, generating efficient parsers is cool, but the pain definitely comes from error messaging and handling anything that's not super "generatable"
08:39 uniclown joined
08:39 <thang1> (If I'm thinking correctly on downsides/benefits of generating vs writing your own parser)
08:39 <cocreature> merijn: which means that you need to left-factor your grammar :P
08:41 <ventonegro> Is there a book or other comprehensive material about EDSLs in Haskell?
08:41 <* nshepperd_> . o O (write a total grammar and explicitly handle every possible parse error)
08:41 <ventonegro> I know there are plenty of papers lying around
08:42 saussure joined
08:42 leat joined
08:44 lep-delete joined
08:44 tomphp joined
08:44 <quchen> cocreature: The documentation on Hackage built faster than I could have locally. There was some magic involved
08:44 mheinzel joined
08:44 <merijn> ventonegro: What kinda material are you looking for?
08:44 Sigyn joined
08:45 <cocreature> quchen: sometimes it works pretty well. I’ve just gotten used to not trusting it :)
08:45 Rodenbach joined
08:47 dihuteno joined
08:47 <merijn> thang1: Well, if you need other usefull Haskell work that's less intimidating, I've got some suggestions ;)
08:48 <merijn> (less intimidating than GHC, that is)
08:48 <kuribas> Does anyone have experience with image processing?
08:48 <thang1> I'm definitely open to suggestions :p
08:49 <thang1> kuribas: programatically? Eh, not really. I can photoshop stuff pretty well but that's not really what you're looking for, I'm assuming?
08:49 <thang1> I know how to use feh to set my wallpaper, does that count? :p
08:49 <kuribas> thang1: I'd like to know what is a good library for haskell...
08:49 tomphp joined
08:50 <Xion_> I was messing with my meme generator code last weekend to optimize the captioning of animated GIFs; does that count? :)
08:50 <kuribas> Xion_: sure
08:50 defstryker joined
08:51 saussure joined
08:52 <ventonegro> merijn: Something that starts simple but builds up and deals with sharing, using the type systems for proving that no memory access is out of bounds, etc.
08:52 <ventonegro> I am thinking about generating C
08:52 baldrick1 joined
08:52 <merijn> thang1: I've been adding a bunch of stuff to criterion, including a (VERY!) basic tool that can produce HTML reports from JSON result files (so you don't have to rerun benchmarks to generate plots from them), but there's a bunch of stuff that I want to add to it and I have a hard time finding the time :p
08:53 defstryker joined
08:54 <thang1> oooh neat, HTML
08:54 <thang1> I've always wanted to use some of haskell's regex libraries
08:54 <merijn> thang1: Specifically, the ability to filter, combine, reorder, and group JSON output (i.e. sorta preprocessing the JSON results)
08:54 <cocreature> thang1: trust me you don’t want to use them
08:54 <merijn> thang1: afaict it shouldn't be all that hard to do implement
08:55 <thang1> cocreature: It was a joke about how everyone tries to process HTML with regex :p
08:55 jambon69 joined
08:55 halogena1dtoast joined
08:55 <cocreature> although chris dormamn seems to be working on making regex in haskell less horrible
08:56 <jambon69> hi o/
08:56 <thang1> merijn: so currently you run the benchmarks once to generate JSON result files and then run them again to generate plots from those files?
08:57 tomphp joined
08:57 <merijn> thang1: No, you can produce JSON and plots at the same time and I added a tool to basically plot the resulting JSON files (so you don't have to immediately plot them). What's lacking is the ability to filter, combine, reorder, and group reports from existing JSON file and plotting those
08:58 <hanna> I usually find it much easier and more long-term viable to use parsec combinators instead of regex
08:58 <thang1> hanna: the regex was definitely a tongue-in-cheek joke :p
08:58 <hanna> ah
08:59 <Xion_> Since Parsec et al. are pretty easy to use, I'm not sure not having a great regex library is such a problem.
08:59 oish joined
08:59 <merijn> But there's plenty of low hanging fruit like this in many libraries, I think. Just needs people to pick it up and be stubborn enough to get it merged :)
08:59 <hanna> Xion_: unless you want to accept user regex input
08:59 Bardusbasium joined
08:59 <hanna> like as a config option
08:59 <thang1> merijn: makes sense. So basically, doing all that in haskell is simply loading up the json and pre-processing it a bit and then running the output tool?
09:00 <Xion_> But yeah, a lib which works for all three of (1) string regexes (2) applicative style operators (3) TH-based in-language regex syntax would be great
09:01 FreeBirdLjj joined
09:01 <thang1> And I'm guessing an ideal workflow for the end user would be something like: Write up small 'config' file to group, filter, etc., the charts/graphs. Run the benchmarks and have the output give you the JSON and the html seamlessly, using the config file?
09:01 <merijn> thang1: I mean this https://github.com/merijn/criterion/blob/master/app/Report.hs already loads the reports and produces the report. Some things to do would be: 1) the ability to filter the loaded reports 2) load multiple files to read data from 3) output new "combined" JSON from loaded files, etc.
09:02 <merijn> thang1: I'm not even sure a config file would be necessary. If you can conveniently recombine/split/filter JSON files and output new JSON you can easily shell script that sorta thing :)
09:03 <thang1> I'm just thinking that the venn diagram of users who a) "can easily shell script stuff" and b) "want pretty graphs for benchmarking analysi" is kinda small :p
09:04 <merijn> thang1: Criterion isn't really aimed at naive users. It's for programmers who want to benchmark their code, so I'd assume 100% can shell script
09:04 <merijn> Also, who doesn't want pretty graphs? Have you seen criterion's output? It's awesome
09:04 <thang1> Besides, I'm not really sure how one would integrate a recombine/split/filter JSON file utility into the project (to be used with shell scripting) without ending up with a general JSON manipulating tool that's got a bunch of shortcut functions and helper functions defined
09:04 juanpaucar joined
09:04 <thang1> I have. The output is beautiful and your site/documentation is top notch too :p
09:05 m0rphism joined
09:06 <merijn> thang1: Well, the thing is it already has functions in the library to read/write them :)
09:06 <merijn> "readJSONReports :: FilePath -> IO (Either String ReportFileContents)"
09:06 <merijn> "writeJSONReports :: FilePath -> [Report] -> IO ()"
09:06 <merijn> So, really just fiddling/manipulating the resulting [Report] list to only contain what you want is all that needs to be done :)
09:07 twomix joined
09:07 <merijn> pandoc can probably also use additions
09:07 <merijn> Are you can badger people into migrating to quchen's prettyprinter :p
09:07 henriksod joined
09:07 <thang1> http://www.serpentine.com/criterion/fibber.html So for this example, the only kind of customization of output you're thinking of is choosing which of the fib/1 fib/5 fib/9 fib/11 graphs to show and what order to show them in?
09:09 <merijn> thang1: Well, for example, I currently have a set of 3.8k benchmarks, and I don't want to rerun all of them if one of them changes, so I want to basically manipulate things so I can just easily include the newly run benchmarks and generate the new plots I want
09:09 <merijn> Probably not all of those are useful, but I'm not sure which ones I wanna keep yet :p
09:09 Kreest__ joined
09:09 saussure joined
09:10 mattyw joined
09:10 <thang1> ahh, I gotcha
09:11 dalek__ joined
09:12 <thang1> So just looking at the fib html page, intuitively the kinds of things I would "do" to the graph page is I would like to be able to collapse all of one type of chart into a single chart. So for example, plotting 1, 5, 9, 11, ..., of the fib time densities on a single chart to easily compare them
09:13 <merijn> thang1: carter was doing some similar work, see: https://github.com/bos/criterion/issues/62
09:13 <thang1> Another thing that would be really useful is (idk the right term for it) showing commonalities among different benchmark sizing? The regression chart, for example, has a very similar distribution of dots for a lot of things
09:14 <merijn> thang1: i.e. instead of having one big group, create smaller subgroups
09:15 <thang1> right, that sort of customization is very useful
09:15 aarvar joined
09:15 <thang1> It seems separate to the issue of only compiling a subgroup of charts, but now that I think about it, I do think they're linked together a bit
09:16 <merijn> quchen: You had some stuff you didn't have time for, right?
09:16 davr0s joined
09:16 filterfish joined
09:16 augur joined
09:17 uniclown joined
09:17 Wizek_ joined
09:17 medicijnman joined
09:17 dawei joined
09:18 Mortomes|Work_ joined
09:19 <sternmull> what is the most elegant way to define a function that subtracts one? Is "\x -> x - 1" the best i can get?
09:20 <thang1> f x = x - 1 is exactly equivalent to \x -> x - 1
09:20 <cdornan_> cocreature: absolutely -- regex should be quite usable now -- continuing to work on it and suggestions always welcome
09:20 <Xion_> :t (- 1)
09:20 <lambdabot> Num a => a
09:20 <Xion_> ;/
09:20 <Xion_> :t ((-) 1)
09:20 <lambdabot> Num a => a -> a
09:21 <Xion_> Well too bad that's the other way around
09:21 <cdornan_> Fwiw I would suggest Haskellers give regex a try if it looks applicable
09:21 <sternmull> Xion_: yes, i tried that already :)
09:21 <Xion_> :t (`-` 1)
09:21 <lambdabot> error: parse error on input ‘-’
09:21 <Xion_> mkay
09:21 kritzcreek joined
09:21 <thang1> You have to wrap - in its own parenthesis because (-1) is syntactic sugar for (negate 1) aka "negative 1"
09:22 <thang1> :t ((-1) 1) -- this does what you want
09:22 <lambdabot> (Num (t -> t1), Num t) => t1
09:22 <Xion_> You'd have to define minus = (-) and then use (`minus` 1) I guess
09:22 <cdornan_> For a long time Haskellers have been avoiding it, which looks like a wrong turn
09:22 <yushyin> :t (subtract 1)
09:22 <lambdabot> Num a => a -> a
09:22 <Xion_> Ah
09:22 <thang1> > ((-)1) 1
09:22 <lambdabot> 0
09:23 <thang1> > (subtract 1) 1
09:23 <lambdabot> 0
09:23 ErinvanderVeen joined
09:23 <sternmull> yushyin: Thanks! Thats what i was looking for.
09:23 <thang1> It's a bit annoying, but in the grand scheme of things, I don't really know if it's worth the bike shedding...
09:24 <EggsHendrix> does anyone here write haskell professionally?
09:24 defstryker_ joined
09:24 <thang1> Now the thing that really messes with me is this
09:24 <thang1> > foldr (-) 0 [1..10]
09:24 <lambdabot> -5
09:24 <thang1> > foldr subtract 0 [1..10]
09:24 <lambdabot> -55
09:25 <Xion_> EggsHendrix: I kiiinda do (or at least will soon).
09:25 <thang1> Does anyone have a sane reason for why those two foldrs behave so differently?
09:26 anodium joined
09:26 <ventonegro> > foldr (flip subtract) 0 [1..10]
09:26 <lambdabot> -5
09:26 <thang1> Literally just as I figured that out :p okay, I'm not crazy, woo