Experimental IRC log haskell-2009-05-18

Available formats: content-negotiated html turtle (see SIOC for the vocabulary)

Back to channel and daily index: content-negotiated html turtle

These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.

00:00:04<Saizan>ah :)
00:01:07<QtPlaty[HireMe]>duaneb: Shouldn't the IO monad prevent that?
00:01:40<QtPlaty[HireMe]>Oh figurering out is pure?
00:01:47<duaneb>QtPlaty[HireMe]: yes :P
00:02:12<neoswish>is default keyword only for Num class?
00:02:14<duaneb>oh great
00:02:27<duaneb>haskell doesn't throw an exception on divide by zero!?
00:02:40<roconnor>> 1 `div` 0
00:02:41<lambdabot> * Exception: divide by zero
00:03:12<duaneb>yea, but > 1 / 0
00:03:13<copumpki>what do messages along the lines of "Warning: Data.Array.Vector: unsafeFreezeMU is exported separately but will be documented under UA. Consider exporting it together with its parent(s) for code clarity." mean?
00:03:14<duaneb>> 1 / 0
00:03:15<lambdabot> Infinity
00:03:26<vixey>have you noticed the people that like TCO call it TCO and the people against it call it TRE?
00:03:27<duaneb>plus, div is probably integral
00:03:32<duaneb>@type div
00:03:33<lambdabot>forall a. (Integral a) => a -> a -> a
00:03:36<duaneb>see?
00:03:38<duaneb>great.
00:03:42<roconnor>vixey: I have
00:03:58<roconnor>duaneb: what do you get when you do 1.0 / 0.0 in C?
00:03:59<duaneb>anyway, 1 / 0 should be NaN, not Infinity
00:04:05<duaneb>roconnor: I'll check
00:04:11<roconnor>duaneb: tell that to the IEEE
00:04:20<augustss_>duaneb: IEEE says it's infinity
00:04:34<augustss_>Which may or may not raise an exception.
00:04:54<dolio>vixey: Don't the people who like it call it 'proper tail recursion'? :)
00:04:57<duaneb>IEEE needs to take algebra again.
00:05:07<dolio>Or is that just Scheme bigwigs?
00:05:20<augustss_>IEEE floating point fails on most algebraic properties
00:05:35<augustss_>Like associativity
00:05:39<duaneb>dolio: no, those are the people who don't understand what TCO *is*
00:05:39<copumpki>dons: would it be bad to define andU/orU/allU/anyU in UArr in terms of foldr, so it can short-circuit and match List behavior more?
00:05:40<Gracenotes>it is a very extremely useful tool though
00:05:42<roconnor>dolio: I wonder if proper tail recursion is something different, something about how the "function call" is handled rather than about stack allocation?
00:05:52<Gracenotes>well. very. maybe not very extremely.
00:05:55<MyCatVerbs>duaneb: no, the IEEE 754 committee knew exactly that they were doing. It's designed for numerical simulation of physical processes, not algebra.
00:06:11<dolio>duaneb: The scheme standard calls it "proper tail recursion".
00:06:28<Gracenotes>IEEE has the most precision for lower numbers, where people are more apt to use it
00:06:37<copumpki>duaneb: there are a lot more painful things in IEEE than just that :) but it's still very useful for practical applications
00:07:12<Gracenotes>if you want something like computable reals, go ahead, but also be prepared to pay the price in performance... >_>
00:07:16<Gracenotes>*the IEEE mafia strikes again*
00:07:21<dolio>roconnor: Well, I read some newsgroup discussion where a guy was claiming that "proper tail recursion" is a stronger property than what you get with "tail call optimization", but I haven't gotten to his paper yet.
00:07:29<copumpki>:o
00:07:54<roconnor>dolio: I would guess that, but I'm only inferring that from the name and a bit of context.
00:07:58<dolio>roconnor: Something about proper tail recursion preventing you from doing stack allocation of variables at all, in some cases, or something.
00:08:09<copumpki>lol
00:08:44<roconnor>dolio: I could believe that. No need to free a stack and allocate it again, just reuse it.
00:09:14<Gracenotes>how I love cocoa with my pumpkin pie!
00:09:16<Gracenotes>ACTION bakes cocopumpkin
00:09:19<copumpki>:o
00:09:44<cocopumpkin> :O
00:10:20<cocopumpkin>A coCoconut is just a conut.
00:10:30<copumpki>I have quickcheck 2.1 installed in my user cabal dir, and 1.2 in the system
00:10:42<duaneb>@type or
00:10:42<Saizan>and a coconut is just a nut?
00:10:43<lambdabot>[Bool] -> Bool
00:10:44<kacper_>I write structural induction proof for reverse( reverse xs ) = xs and its good for finite list. I know that for infinite it should fail but i considering a case reverse( reverse _|_ ) => reverse( _|_ ) => _|_ and its look like good, who knows where induction for infinite lists fails?
00:10:45<copumpki>and it's complaining that 1.2 doesn't have what I need, when I want it to use 2.1
00:10:48<duaneb>wtf?
00:10:49<duaneb>ok
00:10:51<dolio>roconnor: I'm not exactly sure how doing tail call optimization would fail to get you proper tail recursion though. Perhaps you can construct pathological examples where you get linear stack growth by referring to the contents of old stacks while using CPS or something.
00:10:52<cocopumpkin>Saizan, yes. :O
00:10:59<dons>copumpki: hmm. you want to short circuit the non-fused version?
00:11:00<dons>-- |/O(n)/. 'andU' yields the conjunction of a boolean array.
00:11:00<dons>andU :: UArr Bool -> Bool
00:11:00<dons>{-# INLINE andU #-}
00:11:00<dons>andU = foldU (&&) True
00:11:10<Saizan>copumpki: --user ?
00:11:18<copumpki>dons: well, I added a foldrU
00:11:22<dolio>roconnor: So even if you popped off stack frames, and allocated new ones, they'd be storing linearly increasing ammounts of variables or something.
00:11:35<copumpki>dons: that builds on a stream foldr
00:11:45<kacper_>I write structural induction proof for reverse( reverse xs ) = xs and its good for finite list. I know that for infinite it should fail but i considering a case reverse( reverse _|_ ) => reverse( _|_ ) => _|_ and its look like good, who knows where induction for infinite lists fails?
00:11:59<dolio>Which isn't allowed under proper tail recursion, which has to have bounded stack use for the particular case.
00:12:03<roconnor>dolio: I'm not claiming any change in space usage by proper tail recursion over TCO.
00:12:05<dolio>Constant bounded, that is.
00:12:15<copumpki>Saizan: I'm not using cabal for the compilation in this case :/
00:12:18<vixey>kacper_: do you have proof rules for infinite structures?
00:12:20<copumpki>it's a plain makefile
00:12:20<roconnor>dolio: just a minor opitmization
00:12:29<roconnor>dolio: again, I'm sort of making all this up. I have no idea really
00:12:49<ajdhs>does anyone know how to use QuickCheck to get ahold of the value that caused a failure (I asked this earlier, but no answer.)
00:12:49<kacper_>vixey: no
00:12:51<Saizan>copumpki: are you running it as the same user?
00:13:02<copumpki>Saizan: yup, only got one user on this computer
00:13:15<copumpki>it seems to be looking at my system quickcheck
00:13:33<MyCatVerbs>dolio: IIRC one of the Schemes that does Cheney on the MTA just lets frames get allocated when you tail-call.
00:13:35<dolio>roconnor: He was claiming that TCO doesn't satisfy the space behavior of proper tail recursion, though.
00:13:49<vixey>kacper_: lets find some
00:13:56<augustss_>kacper_: Your particular case works, but what about, e.g., reverse (reverse (1:_|_))?
00:14:13<vixey>kacper_: for finite things you can do least fixed point induction, so on infinte things you get to do greatest fixed point induction
00:14:24<roconnor>dolio: okay, that's just crazy
00:14:28<copumpki>dons: I can leave it alone though, it isn't that important :)
00:14:29<MyCatVerbs>dolio: the allocated frames become garbage immediately on the next call, so that even though O(n) frames get allocated, only a constant number are ever live for the GC.
00:14:46<rzezeski>monadic_kid: You weren't lying, that's a great explanation of algebraic data types! It melted my mind a little though, I'm going to have to come back to it at a later date :)
00:14:59<copumpki>dons: I'm just cleaning up code in preparation to give you something for 0.2
00:15:13<MyCatVerbs>dolio: the author justifies this implementation by pointing out that the Scheme standard only requires *amortised* O(1) space usage for tail recursive functions, not hard O(1) space usage. :3
00:15:14<kacper_>vixey: could You give me any advice?
00:15:32<dolio>Anyhow, the paper is "Proper Tail Recursion and Space Efficiency" by Will Clinger.
00:15:40<dolio>I'm not sure if it goes into all that or not.
00:17:32<kacper_>augustss_: reverse( reverse (1:_|_) ) => _|_ /= (1:_|_) right?
00:18:16<vixey>kacper_: So the question is "what is induction for infinite objects"
00:18:20<adamvo>> reverse (reverse (1:undefined))
00:18:21<lambdabot> * Exception: Prelude.undefined
00:19:01<kacper_>adamvo: so it fails because /= 1:undefine ?
00:19:14<dons>copumpki: i think the code as it is is fine.
00:19:25<adamvo>> reverse (reverse (1:undefined:[]))
00:19:26<lambdabot> [1,* Exception: Prelude.undefined
00:19:30<dons>happy to get e.g. IO /bytestring patches
00:19:37<defun>hey, how does polyparse compare to parsec?
00:19:53<copumpki>dons: okay, I'll just add a note in the documentation that points out the difference in behavior from list, maybe?
00:20:08<Spreadsheet>I'm new to Haskell. how do you print a number in haskell?
00:20:34<copumpki>Spreadsheet: print 1
00:20:36<kacper_>vixey: i headr about coinduction, it is it?
00:20:41<Spreadsheet>copumpki: thanks
00:20:44<kacper_>*heard
00:20:50<defun>nobody?
00:21:04<blackh>Spreadsheet: 'putStrLn (show x)' is equivalent to 'print x'
00:21:11<roconnor>@src print
00:21:11<lambdabot>print x = putStrLn (show x)
00:22:06<Spreadsheet>thanks again
00:22:23<augustss_>kacper_: I think you can prove what you need by just fixpoint induction
00:22:27<vixey>kacper_: How do weapply coinduction to this example?
00:22:30<dons>copumpki: hmm. yes, it relies on fusion
00:22:35<augustss_>kacper_: but fixpoint induction is no fun
00:22:42<dons>copumpki: which is a bit weird
00:22:48<copumpki>hmm, how do you mean?
00:23:37<kacper_>vixey: I only heard that coinduction is for infinite structures
00:23:57<ajdhs>defun: I think polyparse is newer
00:25:08<dolio>Coinduction is for coinductively defined structures.
00:25:15<dolio>They aren't necessarily infinite.
00:25:35<defun>ajdhs: so, it is not neccessarily better or worse (than parsec). I assume that no one has tried using for a "real" project. Is there anything that would motivate me to use polyparse over parsec or vice versa?
00:25:47<augustss_>kacper_: http://www.utdallas.edu/~hamlen/cs6371fa08/lecture9.pdf
00:27:10<augustss_>kacper_: but that note doesn't mention the tedious part of showing that the predicate is admissable
00:27:56<kacper_>augustss_: it looks too hard for this exercice ;)
00:28:01<sooth>Is something wrong with code.haskell.org?
00:28:50<augustss_>kacper_: well, it's easy to show that reverse . reverse /= id since you can find a counter example. :)
00:28:53<ajdhs>defun: I believe it's used in HaXml
00:28:54<jeffz`>sooth: seems to be, I can't access trac
00:29:17<ajdhs>defun: Parsec is in the Haskell Platform and is probably more widespread
00:29:54<copumpki>bah
00:30:06<kacper_>yeah, as you wrote it is (1:undefine) but in my excercise i must show where induction's proof fails
00:30:15<ajdhs>defun: so it may be better supported
00:30:27<ajdhs>defun: I've never actually used PolyParse, so I can't give you a lot more detail than that.
00:31:22<augustss_>kacper_: but you can't use structural induction to prove things when _|_ is involved.
00:31:33<defun>thanks, mate.
00:32:14<augustss_>HaXml uses polyparse and can parse quite large files fast.
00:32:22<kacper_>so fixed-point induction ?
00:33:22<jeffz`>hm, I've installed the haskell platform, tried to use ghci with Hipmunk but ghci tries to load a nonexistent libm.dll
00:33:50<copumpki>ACTION screams at cabal
00:33:55<augustss_>kacper_: you can probably find where the induction fails pretty easily with fixed point induction
00:34:15<augustss_>copumpki: it can't hear you
00:35:11<kw317>hi
00:35:29<copumpki>:/
00:38:22<copumpki>Properties/Utils.hs:15:7:
00:38:22<copumpki> Could not find module `Test.QuickCheck.Batch':
00:38:22<copumpki> it is a member of the hidden package `QuickCheck-1.2.0.0'
00:38:52<SamB>copumpki: what quickcheck is cabal using?
00:38:53<SamB>any ?
00:39:00<copumpki>this is from a makefile
00:39:01<SamB>if not, add it to the .cabal file ...
00:39:06<SamB>oh
00:39:06<copumpki>just a regular ghc build
00:39:25<copumpki>how can I express constraints on the command line?
00:39:27<SamB>ask in #ghc ?
00:39:40<dons>--constraint='base<43'
00:45:19<coCoconut>pumpkin_: "In Cabal-space, no one can hear you scream." ;p
00:47:21<Rambling>In Python, I can use tuples and lists interchangeably with function like sum: sum((1,2)) and sum([1,2]) both work. How can I sum the elements of a tuple in Haskell?
00:47:41<vixey>Rambling: sumTuple (x,y) = x + y
00:47:44<pumpkin_>you can't work with tuples of arbitrary sizes
00:47:45<lambdabot>pumpkin_: You have 1 new message. '/msg lambdabot @messages' to read it.
00:47:47<pumpkin_>uncurry (+)
00:47:47<vixey>Rambling: sumTuple = uncurry (+)
00:48:17<vixey>Rambling: if you wanted to write a function that works on tuples as well as lists you could use typeclasses - it's not normal haskell though
00:49:01<Rambling>What about summing a 3-tuple?
00:49:04<Cale>Rambling: It's just very uncommon to use tuples for something you're going to want to sum. The elements of a tuple may be of various different types anyway.
00:49:22<Cale>Also, 3-tuples are uncommon and 4-tuples and higher are usually to be avoided.
00:49:43<Cale>When you start getting larger numbers of components, defining your own datatype is usually best.
00:50:02<MyCatVerbs>Cale: ...I have learned that last bit the hard way. :)
00:50:04<Cale>But, you can say (\(x,y,z) -> x+y+z)
00:50:05<Rambling>Okay. I'm actually working on Project Euler Problem #9.
00:50:37<Rambling>So I was working with lists of 3 tuples to represent possible Pythagorean Triplets.
00:50:50<jeffz`>hm, ok, I thought this might have worked earlier, but windows ghci 6.8.2 also tries to load libm
00:51:24<Cale>So in that case, you actually probably want to write a function like (\(x,y,z) -> x^2 + y^2 == z^2)
00:51:44<Cale>(depending on how you choose to solve the problem)
00:52:28<EvilTerran>ACTION found a cleverly-written list comprehension to be the clearest way of doing that one, iirc
00:53:15<Rambling>Cale: I made a list of triplets of numbers whose sum was 1000 and filtered it using a function identical to that.
00:53:22<Cale>I haven't bothered to look at what the problem actually is, but yeah, a list comprehension is a nice way to generate Pythagorean triples if speed doesn't matter too much.
00:53:51<pumpkin_>Rambling: that sounds inefficient :P
00:54:12<dolio>Filtering by isPythagoreanTriple (x,y,z) is probably unadvisable, too.
00:54:25<Cale>But that's really not so many triples to check.
00:54:46<dolio>Rather than generating x and y and testing if x^2 + y^2 is square.
00:54:55<solrize>> do {x<-[1..999];y<-[x..999];let z=1000-x-y; guard $ x^2+y^2==z^2; return z}
00:54:56<lambdabot> <no location info>: parse error on input `;'
00:54:59<cocopumpkin>> [(2*m*n,m^2-n^2,1000-(2*m*n)-(m^2-n^2)) | m <- [2..], n <- [1..m], 2*m*n<m^2-n^2,2*m*n+(m^2-n^2)+(m^2+n^2)==1000]
00:55:00<vixey>obv. you should implement CHR then CLP/FD in terms of CHR and write the program using that
00:55:11<solrize>> do {x<-[1..999];y <-[x..999]; let z=1000-x-y; guard $ x^2+y^2==z^2; return z}
00:55:13<lambdabot> <no location info>: parse error on input `;'
00:55:15<lambdabot> thread killed
00:55:18<cocopumpkin>> head [(2*m*n,m^2-n^2,1000-(2*m*n)-(m^2-n^2)) | m <- [2..], n <- [1..m], 2*m*n<m^2-n^2,2*m*n+(m^2-n^2)+(m^2+n^2)==1000]
00:55:20<lambdabot> (200,375,425)
00:55:21<solrize>hmm
00:55:41<cocopumpkin>I guess lambdabot likes to spit out random numbers. ;)
00:55:57<Cale>Write a function to construct rationals, and then do a stereographic projection onto rational points on the unit circle ;)
00:56:22<Rambling>cocopumpkin: I had forgotten that you could do filtering inside of the list comprehension rather than using filter.
00:57:14<roconnor>> let rats = 1:concat [[x+1, 1/(x+1)]|x<-rats] in rats
00:57:16<lambdabot> [1.0,2.0,0.5,3.0,0.3333333333333333,1.5,0.6666666666666666,4.0,0.25,1.33333...
00:57:20<pumpkin_>do I need to do something to export instances from a module?
00:57:29<roconnor>> let rats = 1:concat [[x+1, 1/(x+1)]|x<-rats] in rats :: [Rational]
00:57:30<lambdabot> [1%1,2%1,1%2,3%1,1%3,3%2,2%3,4%1,1%4,4%3,3%4,5%2,2%5,5%3,3%5,5%1,1%5,5%4,4%...
00:58:11<cocopumpkin>> let rats = 1:concat [[x+1,1/(x+1)]|x<-rats] in scanr (*) 1 rats
00:58:14<lambdabot> [* Exception: stack overflow
00:58:32<cocopumpkin>> let rats = 1:concat [[x+1,1/(x+1)]|x<-rats] in scanl (*) 1 rats
00:58:34<lambdabot> [1.0,1.0,2.0,1.0,3.0,1.0,1.5,1.0,4.0,1.0,1.3333333333333333,1.0,2.5,1.0,1.6...
00:59:32<cocopumpkin>> let rats = 1:concat [[x+1,1/(x+1)]|x<-rats] in elemIndices 1 $ scanl (*) 1 rats
00:59:36<lambdabot> [0,1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51...
00:59:43<cocopumpkin>Odd.
00:59:54<f1shb0t>> let rats = 1:concat [[x+1,1/(x+1)]|x<-rats] in scanl (*) 1 rats
00:59:56<lambdabot> [1.0,1.0,2.0,1.0,3.0,1.0,1.5,1.0,4.0,1.0,1.3333333333333333,1.0,2.5,1.0,1.6...
01:00:10<solrize>[(x,y,z) | x<-[1..999], y<-[x..999], et z=1000-x-y, x^2+y^2==z^2]
01:00:16<solrize>> [(x,y,z) | x<-[1..999], y<-[x..999], et z=1000-x-y, x^2+y^2==z^2]
01:00:17<lambdabot> <no location info>: parse error on input `='
01:00:24<f1shb0t>bonhoffer: It hooks directly to the kernel, bypassing anything else that might be messed up. The wiki link should explain it better though.
01:00:24<solrize>> [(x,y,z) | x<-[1..999], y<-[x..999], let z=1000-x-y, x^2+y^2==z^2]
01:00:30<lambdabot> [(200,375,425)]
01:00:54<cocopumpkin>lambdabot still likes to spit out random meaningless numbers. ;)
01:00:55<dons>Cale, roconnor seen mathlink (haskell lib)?
01:00:55<f1shb0t>> let rats = 1:concat [[x+1,1/(x+1)]|x<-rats] in scanl (*) 1 rats
01:00:57<lambdabot> [1.0,1.0,2.0,1.0,3.0,1.0,1.5,1.0,4.0,1.0,1.3333333333333333,1.0,2.5,1.0,1.6...
01:01:24<f1shb0t>hoohah: and after e.g. install gnome-desktop you can remove that specific package and run 'apt-get autoremove' so it removed all automatically installed packages related to an non-longer-installed package.
01:01:25<ajdhs>pumpkin_: no
01:01:54<f1shb0t>VERSION
01:02:24<f1shb0t>I get the following error when installing debian: Device /dev/hdc has multiple (0) logical sectors per physical sector. Any advice, info? I have no idea what this means.
01:03:11<MyCatVerbs>f1shb0t: it means you really, really need to be in #debian rather than #haskell.
01:05:26<roconnor>http://www.reddit.com/r/programming/comments/8kf9n/reply_to_randal_schwartz_on_dynamic_type_systems/c09n1qt
01:05:51<roconnor>Henry-Milner, why have you forsaken me?
01:06:01<MyCatVerbs>roconnor: Hindley.
01:06:10<roconnor>Hindley-Milner, why have you forsaken me?
01:07:05<MyCatVerbs>Because polymorphic recursion is actually a complete cow.
01:07:16<roconnor>cow?
01:07:28<MyCatVerbs>Pain in the neck. SML does not support it at all for very good reasons.
01:07:28<monochrom>Those who have learned from type system debates are bound to watch it repeat itself.
01:07:40<roconnor>very good reasons?
01:08:07<Cale>dons: I do remember hearing something about it. It looks neat, but I haven't tried it.
01:09:10<augustss_>Polymorphic recursion is a bit of a pain, but necessary for operating on the more interesting types.
01:10:18<dolio>Does SML allow nested types?
01:10:36<roconnor>dolio: I don't think so, but I'm not sure.
01:10:42<Raevel>what's a nested type?
01:11:09<dolio>Raevel: like 'data Foo a = Foo1 | Foo2 a (Foo (a,a))'
01:11:26<augustss_>dolio: yes, SML allows them
01:11:28<Raevel>you can do that in sml
01:11:33<roconnor>you can?
01:11:48<dolio>Wouldn't they be kind of a pain without polymorphic recursion?
01:11:56<augustss_>Very much so.
01:12:03<MyCatVerbs>dolio: why have Foo1 in there at all? Infinite doubling tuple streams!
01:12:17<dolio>:)
01:12:29<Raevel>datatype aexp = Add of aexp * aexp;
01:13:01<PetRat>Remind me what the record update syntax is? something like newRecord = oldRecord { field = newValue, field2 = newValue2 }
01:13:14<MyCatVerbs>PetRat: you have it exactly.
01:13:18<solrize>; instead of , ?
01:13:35<PetRat>Great.
01:13:37<MyCatVerbs>I should check, but IIRC it's commas.
01:13:44<solrize>k
01:13:59<kacper_>> reverse( reverse undefined )
01:14:01<lambdabot> * Exception: Prelude.undefined
01:14:29<kacper_>> reverse( reverse (1:2:undefined) )
01:14:31<lambdabot> * Exception: Prelude.undefined
01:14:47<kacper_>> id (1:2:undefined)
01:14:49<lambdabot> [1,2* Exception: Prelude.undefined
01:15:06<MyCatVerbs>Yep, it's commas.
01:16:16<PetRat>Record syntax for definitions is also commas. Imagine that! Consistency!
01:17:31<Cale>but with do/let/case...of/where, it's semicolons
01:17:59<PetRat>do-notation is semicolons. I read the section in RWH where they say that some people call monads "programmable semicolons". I.e. in C or Java, a semicolon is a break between actions but does nothing itself. In Haskell, semicolons can be sophisticated.
01:18:26<Baughn>That's.. one way of putting it
01:18:42<Cale>> do x <- [1,2,3]; y <- [4,5]; return (x,y)
01:18:44<lambdabot> [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
01:18:46<MyCatVerbs>I think that makes sense, really.
01:18:47<PetRat>Baughn: not a good way?
01:18:52<Baughn>I'd /prefer/ saying that Monads are join, but that requires understanding functor and applicative first. ;)
01:19:17<Cale>don't forget poor return!
01:19:21<MyCatVerbs>If record syntax were semicolons instead of commas, you'd be able to confuse yourself by accidentally doing stupid things to them with line breaks.
01:19:23<Baughn>PetRat: Well, it works for a provisional understanding for the simpler kinds of monads. Or as a soundbite of great evil.
01:19:26<PetRat>I shouldn't have said monads ARE ..., but USING monads IS LIKE
01:19:29<Baughn>Cale: pure!
01:19:43<Cale>Oh, a monad is an applicative functor with join? :)
01:19:51<PetRat>I'm encountering a lot of evil soundbites then.
01:19:53<Baughn>Right. :)
01:20:40<Baughn>PetRat: Functor has fmap (<$>). Applicative has ap (<*>) and pure/return. Monad subclasses both of those, and adds join
01:20:40<Cale>I kind of like the return/(<=<) definition too
01:20:59<MyCatVerbs>:t (<=<)
01:21:01<lambdabot>forall b (m :: * -> *) c a. (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c
01:21:04<Baughn>PetRat: ..um, I'd suggest reading the typeclassopedia if you want to /understand/ that sentence
01:21:14<Cale>A monad is a functor m with return and (<=<) such that:
01:21:20<Cale>1) return <=< f = f
01:21:25<Cale>1) f <=< return = f
01:21:30<Baughn>The monad laws, sure..
01:21:37<Cale>1) (f <=< g) <=< h = f <=< (g <=< h)
01:21:38<vixey>:S
01:21:42<Cale>er, 1,2,3 ;)
01:21:44<Baughn>But those are just what's needed to make the syntax come out halfway sane
01:21:49<MyCatVerbs>Cale: I like your number Scheme.
01:21:50<Cale>ACTION was editing lines ;)
01:21:53<vixey>lol
01:21:54<PetRat>Yes, typeclassopedia is on my reading list. At the moment I'm trying to get through chapter 15 of RWH but it's tough to understand. I think it needs about twice as much explanatory text. Ratio of code to explanation is too high.
01:21:55<Baughn>They're not something you need to explicitly think about. ;)
01:22:16<Baughn>PetRat: Right, skip over to typeclassopedia, rejoin RWH later. :)
01:22:50<PetRat>Baughn: okey-dokey.
01:23:12<amz>ok, functional design question... say that I want to have a list of objects (say, stuff to draw on screen). I assume that the correct way to have this is to have each "object" (sorry for the OO lingo) contain a function that details how it's drawn... but how to have each contain its own set of data, which might be completely different? Should I pass that along to each's function?
01:23:52<Cale>amz: If all you're going to do is to draw them, then they *are* the actions to draw themselves on screen.
01:24:11<PetRat>The ultimate goal is to UNDERSTAND, and then flexible USAGE of the language comes from that. However, one can start USING the language by imitating examples, and understanding can develop over time. Or, one can try to UNDERSTAND before writing any of one's own code. Or both simultaneously.
01:24:26<augustss_>amz: If you have a fixed set of object that can be drawn then use a data type to define them.
01:24:34<solrize>amz, we'd tend to use separate types for the different object classes (beware, haskell uses "class" to mean what java would call an interface)
01:24:42<Baughn>amz: If you want something more transparent, then random data statements with a class Drawable and instances might be good enough
01:24:43<amz>well, no, I was thinking more along the lines of a game... so you'd have a list of entities that can be drawn (they'll return a drawing action once invoked), but they can also update themselves to the next step
01:25:07<augustss_>amz: I'd start with a data type
01:25:07<amz>but their updating routines are completely different
01:25:07<solrize>i.e. we'd have a function like draw :: (Drawable t) => t -> IO ()
01:25:14<amz>and each has to keep its own different data
01:25:39<amz>and I don't want to have a different list for each different type of thing
01:25:42<augustss_>amz: You can also do it the OO way with existential types
01:25:46<Baughn>amz: Doesn't matter how different the implementation of draw is for each type, so long as its /interface/ (draw :: Drawable a => a -> IO ()) is the same
01:26:17<MyCatVerbs>amz: define a data type for them. You can use a sum data type that has an entry for every type of entity, or you can use existentials to imitate the OO way.
01:26:37<Baughn>..or you could use plain old typeclasses
01:27:19<solrize>baughn, i see the problem, amz wants to have a list of drawables which might not all be the same type
01:27:20<MyCatVerbs>Baughn: not if you want to pass around a [forall a. (Drawable a) => a]
01:27:39<Baughn>Oh, but I'd probably end up defining some svg-like primitive drawing language and have "draw" convert to /that/ structure, which could then be manipulated more universally
01:28:03<Baughn>solrize: Ah. Then existentials.. or see my last sentence
01:28:24<solrize>baughn, right, are you saying there's a way to do it with just typeclasses and no existentials?
01:28:31<amz>well, see, I want to be able to do something like... nextworld = map (dostep) currentworld, and later drawaction = map (draw) nextworld
01:28:34<Baughn>draw :: Drawable a => a -> [DrawCommands]
01:28:38<amz>ok
01:28:38<MyCatVerbs>amz: take Breakout. You'd have something like: data Thing = Brick Brickdata | Ball Balldata | Paddle Paddledata, where Brickdata, Balldata and Paddledata are three different data structures defined elsewhere for the components.
01:28:43<amz>I'll look into that existentials thing
01:28:50<Baughn>scale :: DrawCommand -> Double -> DrawCommand, etc. Whatever.
01:29:01<amz>MyCatVerbs: I'm not sure if I like having to declare all of them together
01:29:19<Baughn>solrize: Sure, by reworking your design to not need multiple /different/ types in one list
01:29:21<Cale>You can also do the existential thing by hand
01:29:25<Baughn>solrize: Eg. by doing what I just suggested
01:29:25<MyCatVerbs>amz: the only real downside of doing it that way is that it's not extensible.
01:29:34<Cale>In this case, it's not hard to come up with an appropriate type...
01:29:37<amz>yes, that's my worry
01:29:38<Cale>Specifically...
01:29:48<MyCatVerbs>i.e. you can't add extra things without altering the definition of Thing.
01:29:52<Baughn>solrize: If you do use existentials, and the only thing you can do with them is to draw them, it seems pointless to not just have a list of whatever draw returns instead
01:30:02<Baughn>Of course, Drawable might have more functions, but still..
01:30:07<MyCatVerbs>You could, on the other hand, come up with something more like:
01:31:00<Cale>(sorry, had to let cat out)
01:31:02<amz>I think drawing was a bad example... the "update" part is what I really worry about. For example, using Breakout... I have a list of Things containing the Paddle, the Ball, and a bunch of bricks
01:31:05<MyCatVerbs>class Entity e where { drawme :: e -> Shape, tickFunc :: e -> e, ... }
01:31:09<amz>then I map the "update" function over that list to get the next step
01:31:14<solrize>baughn, i don't get it, you've got a bunch of different stuff on the screen, why isn't it natural to put all that stuff in a list?
01:31:16<MyCatVerbs>And then data Paddle = ..., instance Entity Paddle where...
01:31:37<MyCatVerbs>Cale: I'm still here, :D
01:31:39<amz>but how will "update" access e.g. the velocity data that only the ball has?
01:31:46<solrize>and if you use an existential, how does the "draw" function know what it's drawing?
01:31:46<amz>(ok, paddle does too, but bricks don't)
01:31:51<Cale>data GameObject = GObj { next :: Stuff -> GameObject; draw :: IO () }
01:32:12<Baughn>solrize: Because most of the time, you want a /tree/ of drawables, not a list
01:32:12<Cale>Where Stuff is whatever appropriate parameters you want, maybe the World
01:32:26<Baughn>solrize: A window containing widgets containing..
01:32:27<Cale>actually, you probably need a little more than this
01:32:43<Cale>Because the game objects have to be able to interact with each other
01:32:44<Baughn>solrize: Okay, you probably want open implementation for the widgets, in which case existentials do make sense
01:32:50<solrize>baughn, same issue, the drawables in the tree can be of different types
01:32:52<solrize>yeah
01:33:03<Baughn>solrize: However, if your class Drawable has only one method, then there's no point in using them. So obviously it has to have more
01:33:06<amz>interaction could be handled by having them return a list of messages on update
01:33:08<solrize>but, once something is existentially quantified, the type system loses track of what it is, right?
01:33:13<Baughn>But the only thing amz has suggested wanting to do is draw them
01:33:13<amz>which would be fed to the proper objects on the next step
01:33:16<Baughn>solrize: Yes
01:33:26<MyCatVerbs>amz: the typeclass way to do it is to have update be a typeclass member. The Paddle has its own definition of update, the Ball has another, the Blocks have another again...
01:33:34<Cale>amz: But does that recursive thing make sense?
01:33:37<Baughn>solrize: ..well, you could always use Dynamic or some such..
01:33:48<solrize>ugh!!! :)
01:33:52<Cale>amz: Basically, the key is that records can contain functions which produce other records of the same type.
01:33:56<amz>MyCatVerbs: right, but then I couldn't map update over a list of those different types, right?
01:34:27<Cale>amz: Functions are extremely flexible in the data which they can involve in their definitions.
01:34:44<MyCatVerbs>amz: you could if you used an existential.
01:35:02<amz>something tells me that I'll really have to look into what are existentials :)
01:35:02<solrize>mycatverbs how does that work?? i think i am missing something
01:35:14<Cale>You don't necessarily need an existential
01:35:20<solrize>amz, existentials are a special case of gadt's so you may as well read about those instead
01:35:29<Cale>I think it's easier to grasp the normal functional programming solution.
01:35:43<solrize>i think the traditional way would be to use a sum type
01:35:50<Cale>Recursive types!
01:35:53<solrize>which means you have to declare all the sub-cases in one place
01:36:00<Cale>No, you shouldn't have to.
01:36:12<amz>well, Cale, for example... if I have a typeclass that defines "update :: a -> a", then I have a list of [myPaddle, myBall, brick1, brick2] :: [Things], and I "map (update) myList", I can't see how would update work
01:36:43<Cale>amz: Each game object consists of its own update function.
01:36:44<MyCatVerbs>solrize: map (update :: forall a. (Updateable a) => a -> a) $ (list :: [forall a. (Updateable a) => a] -- AFAIK actually works? ;P
01:36:51<Cale>amz: (along with whatever else you need)
01:37:41<Cale>amz: So to do the update, you just take each object, get out the update function and call it with whatever parameters are needed for it to generally do its work.
01:37:42<solrize>right, but the idea is you want a different update method for each type!!! you need something like generics
01:38:02<Cale>solrize: Yeah, but you can have functions which produce objects of a given type this way, just fine.
01:38:24<Cale>As far as the type system is concerned, it's all the same type.
01:38:28<amz>Cale: well, one of the "parameters" is the object in its true type... so each object's update function would have to have a (curried?) parameter pointing at itself so it knows what to work with?
01:38:33<Cale>The differences are in how the update function is written.
01:38:34<Baughn>solrize: The function that does the updates would have to have separate code for each type, then
01:38:44<Baughn>solrize: In which case you might as well use an ADT
01:38:54<amz>Baughn: well, that's fine, as long as I can declare them independent of each other
01:39:01<amz>*independently
01:39:07<Cale>amz: Actually, could you elaborate on what sort of game this is?
01:39:18<solrize>baughn, i mean the (update:: forall a. ...) scheme wouldn't be able to do something differently depending on a
01:39:24<Cale>amz: Just so I can be a little more concrete and complete about this.
01:39:28<Baughn>solrize: Exactly
01:39:41<amz>Cale: eh, it's not any game in particular (actually, I was thinking of doing a space invaders or something as a proof of concept)... I've been writing games in C++ for many years, trying to get my brain to work in Haskell now
01:39:44<Cale>There's no need for fancy type system features like existentials here, I think.
01:39:49<solrize>and if you use an ADT, then you have to have a single definition for it that enumerates all the cases
01:40:08<solrize>and if you do what cale says, it's sort of like writing in lisp :)
01:40:22<Baughn>Sure, but if you have a single update function for every type, then that function has to have a mention of each type anyway
01:40:22<Cale>Okay, let's try space invaders then. Each object needs: A way to draw it, a way to update it physically, and a way to determine if it intersects a given region of space.
01:40:33<amz>forget the collision stuff
01:40:37<amz>I'd rather handle that outside it
01:40:48<amz>let's just focus on individual objects with no concept of each other
01:40:48<Cale>Well, I'll leave it in for now, but very abstractly.
01:40:56<Cale>I'm not going to write the collision code ;)
01:41:01<amz>right ;)
01:41:07<Cale>So...
01:41:24<amz>so, what I WANTED to do is have a function that takes all objects in the world and returns a tuple of two lists
01:41:31<amz>the first list is what the world looks after the update
01:41:40<amz>and the second tuple is a list of messages that objects are sending to each other
01:41:45<amz>that will be processed before the next update
01:41:48<Cale>data Object = Obj { draw :: IO (); update :: Object; intersects :: Region -> Bool }
01:41:58<Cale>How does that look to you?
01:42:22<amz>sure, that looks right, if it works ;)
01:42:26<Cale>Possibly, we will want the update to take a list of the other objects.
01:42:54<Cale>So, let's write one of these...
01:43:02<solrize>interesects doesn't care where the object is?
01:43:02<amz>possibly, yes, but most of the need for that is for collision handling (at least, on this sort of game)
01:43:08<amz>which I'd handle outside the main update
01:43:14<amz>and send appropriate messages
01:44:22<Cale>rocket pos vel acc = Obj { draw = do ... ; update = rocket (pos + vel) (vel + acc) acc; intersects = \region -> ... }
01:45:19<Cale>that should probably be ^+^ ;)
01:45:22<amz>hrmm
01:45:23<amz>I see
01:45:27<Cale>(vector addition)
01:45:36<Cale>and inside draw and intersects, we have access to pos
01:45:53<Cale>(and vel, if we want)
01:45:55<amz>I didn't even know that syntax existed
01:45:58<korpios>(new to haskell here) If anyone is familiar with Network.Socket, why would I be getting an error "setSocketOption: invalid argument (Invalid argument)" from "setSocketOption someSocket NoDelay 1"?
01:46:14<Cale>amz: it's just the usual record syntax
01:46:31<Cale>amz: It's like normal algebraic datatypes, but with named fields
01:46:34<amz>I mean, I didn't know that functions declared inside the record could form a closure with the object's constructor's parameters
01:46:38<amz>[am I even using the right terms?]
01:46:50<Lemonator>is there an equivalent to mapM_ for Data.Map ?
01:46:56<Cale>Well, functions always capture the values of variables in the place that they're defined
01:46:59<amz>years of OOP have hardened my brain
01:47:09<Baughn>korpios: What OS would that be on?
01:47:14<Baughn>korpios: And a TCP or UDP socket?
01:47:15<korpios>Baughn: OS X
01:47:18<Cale>(as do all sorts of other data)
01:47:20<sooth>Anyone familiar with Language.C?
01:47:21<solrize>(mapM_ . Data.toList) ?
01:47:33<Cale>(like the IO action here, and other datastructures)
01:47:48<solrize>lemonator, (mapM_ . Data.Map.toList) i mean?
01:47:56<Baughn>korpios: TCP, UDP, what?
01:48:00<Lemonator>well, I'm using that right now,
01:48:05<Lemonator>but it seems inefficient.
01:48:35<solrize>inefficient? you have to traverse the map no matter what you do...
01:48:38<korpios>Baughn: I think it's TCP; trying to debug this: http://hackage.haskell.org/packages/archive/haskell-tyrant/0.2/doc/html/src/Database-TokyoTyrant.html#openConnection
01:48:59<Lemonator>but with that, I'm traversing it twice.
01:49:10<Lemonator>once to construct the list, and then again to map the function
01:49:27<korpios>tracked it down to that function, but not making much headway past that
01:49:54<Cale>Existentials would do a very similar thing here, but they extend to somewhat more complicated situations perhaps a bit more smoothly, and give you a more concrete way to represent the extra bunch of data which the methods are using. I can show you how that would look if you want. I don't think it's really much better than this way for any of the situations which would occur in a game.
01:49:58<amz>would this work? makerocket pos = let a = Obj { draw = drawrocket a; update = updaterocket a; } in a
01:50:27<vixey>amz: makeRocket, drawRocket etc
01:50:28<Cale>let a = x in a is always the same as x
01:50:42<amz>I thought Haskell didn't use camel case? o_o
01:50:53<Cale>It does, by convention
01:50:55<amz>Cale: yes, but I'm passing that same "a" to the functions
01:50:56<Cale>:t putStrLn
01:50:57<lambdabot>String -> IO ()
01:50:59<amz>is that valid?
01:51:00<Cale>amz: oh, right.
01:51:00<amz>oh
01:51:00<amz>right
01:51:01<amz>duh
01:51:03<Cale>amz: Yes, it works.
01:51:04<vixey>amz: anyway that can't work because you didn't use pos
01:51:26<amz>er, yes, hrm
01:51:32<Cale>amz: But yeah, you need to pass the initial parameters in :)
01:51:38<Baughn>korpios: Well, try sticking a trace on it. The only way that should fail like that is if it's actually asking for a non-tcp socket.
01:51:47<Cale>amz: Basically, you can separate the working bits into a where clause nicely.
01:52:02<Baughn>korpios: Or, given that it's in IO already, just print the family, etc.
01:52:15<korpios>Baughn: I should've just pasted exactly what I'm trying: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4975
01:52:30<Cale>rocket pos vel acc = Obj { draw = drawRocket; update = updateRocket }
01:52:37<Cale> where drawRocket = do ...
01:52:51<Cale> updateRocket = ...
01:53:14<Cale>That way, you'll have access to the parameters which rocket was called with, so you can make the recursive call easily.
01:53:22<amz>hrm
01:53:25<amz>I see, that makes sense
01:53:50<Cale>But for testing, it possibly makes sense to add parameters to those things, and separate them from the where.
01:54:02<Cale>I'm not sure which I'd like better :)
01:54:35<Baughn>korpios: Nope, can't say I get it. strace'd probably be useful, but..
01:54:39<Baughn>ACTION goes to sleep
01:54:44<amz>well
01:54:46<amz>thanks everyone
01:54:49<amz>I'll give this a try later
01:54:53<Cale>great :)
01:54:58<Cale>Let us know how it goes
01:55:30<amz>If I can't get my brain around how to make a game in Haskell elegantly, I'll grow up to be a depressed old man
01:55:36<amz>because after tasting Haskell, C++ looks so... ugly
01:55:42<amz>and so does Java
01:55:46<Cale>The nice thing about this way is you get basically all the usual convenience of objects, as long as you can decide what your interface looks like.
01:56:52<Cale>However, it does make adding new operations into a chore, because you have to update each of these object-creating functions.
01:57:01<Cale>(but that's the same as in OO)
01:58:30<solrize>well, in OO you'd make subclasses
01:59:10<solrize>amz someone wrote a first person shooter in haskell...
01:59:22<Saizan>yeah, but if you have a bunch of subclasses and you add a method to the main class you need to modify all of them to add it
01:59:48<Saizan>in constrast, if you have an ADT and you want to add a function you just write it
01:59:54<amz>solrize: yes, I've heard, but I haven't looked at the source to see if it was done in a sane way :)
02:00:04<amz>no point in using Haskell if it were to make the job harder
02:00:37<solrize>saizan, you only have to modify the subclasses when they can't inherit
02:03:04<Cale>Oh, another suggestion, for a 2D game, complex numbers are the way to go for coordinates.
02:04:00<Cale>You get the vector operations trivially (addition, scalar multiply), and then by multiplying by exp(0:+theta), you get rotation for free as well.
02:04:46<Cale>> exp (0:+pi/4)
02:04:47<lambdabot> 0.7071067811865476 :+ 0.7071067811865475
02:04:52<monochrom>"expression problem"
02:05:01<Cale>> exp (0:+pi/4) * (3 :+ 4)
02:05:02<solrize>for 3D you can use quaternions the same way
02:05:02<lambdabot> (-0.707106781186547) :+ 4.949747468305833
02:05:26<Cale>solrize: yeah :)
02:05:49<Cale>(more or less -- it's not quite as beautiful, but nearly so)
02:08:10<amz>Cale: in my experience, you almost never need real rotation in 2D games, anyway
02:08:31<amz>what I usually do is just rotate a normalized vector, and scale that by the force I'm applying
02:08:40<amz>and, from that point on, no more rotations are involved
02:08:51<amz>[except graphically, which is handled by gl/d3d]
02:10:14<Cale>amz: Yeah, but the exp function is so convenient :)
02:11:12<Cale>amz: For an asteroids-style game I'd expect it's pretty important to rotate things easily too...
02:11:47<amz>well, if the asteroids are represented as actual polygons, logics-wise, yes
02:11:48<Cale>(if left/right keys turn the player's ship, and you have lots of spinning asteroid objects :)
02:12:04<amz>but the player's ship falls under the case I mentioned
02:12:09<amz>you just thrust in the direction you're facing
02:12:16<amz>after that, you don't need to worry about rotations anymore
02:12:20<Cale>What about the geometry for the player's ship though?
02:12:29<amz>I'd represent it as a circle ;)
02:12:33<Cale>ah, hehe
02:12:55<amz>one thing that I learned from japanese "maniac shooters" is that having a small collision area on player's "ship" is a good idea
02:13:06<amz>it's usually a small circle on its center
02:13:25<amz>it lets you have more bullets on the screen without making the game impossibly hard
02:14:00<amz>extreme example: http://upload.wikimedia.org/wikipedia/en/2/24/PCByukari140.jpg
02:14:16<Cale>But if the controls are such that you have keys to turn and then a thruster, like the original asteroids, you'd definitely want to draw something which isn't rotationally symmetric
02:14:27<mauke>not nearly enough objects :-)
02:14:51<amz>Cale: ah, yes, but I'd just draw it facing right and use glRotate() to take care of the rest ;)
02:15:55<Cale>I suppose that is quite doable.
02:17:04<amz>heh, funny... now that I linked to that pic, I was looking the attack pattern on youtube, and noticed that several of the other attack patterns would be constructed with quite a lot of rotation
02:17:06<amz>so I stand corrected
02:18:38<Cale>rRootage is a good free game of that sort :)
02:19:14<amz>what sort?
02:23:33<Cale>Japanese style shooter
02:23:42<Cale>With lots of objects :)
02:23:46<amz>:D
02:23:48<amz>ACTION looks into it
02:24:39<amz>hah, they invented a language to describe the bullet patterns
02:25:10<ajdhs>is there a way to generate the tested values based on the failure value of a QuickCheck test?
02:25:27<ajdhs>(besides copying and pasting the printed value?)
02:26:14<roconnor>@check \x -> x == 0
02:26:15<lambdabot> "Falsifiable, after 0 tests:\n1\n"
02:26:33<roconnor>1
02:26:52<roconnor>ACTION cut and paste
02:26:52<Asztal>@check \x y -> x == y
02:26:53<lambdabot> "OK, passed 500 tests."
02:27:00<ajdhs>yeah
02:27:10<Cale>amz: And a genetic programming tool for creating patterns
02:27:33<ajdhs>but suppose it was a more complicated expression
02:27:52<ajdhs>and it was infeasible to cut and past it
02:27:56<Saizan>ajdhs: use QuickCheck-2
02:28:00<ajdhs>I have that
02:28:21<ajdhs>but I can't figure out how to get the failed values out of it
02:29:13<ajdhs>for example
02:29:15<ajdhs>if I have
02:29:37<ajdhs>@check \x y -> sum x > 100000
02:29:38<lambdabot> "Falsifiable, after 0 tests:\n[]\n()\n"
02:29:45<ajdhs>@check \x y -> sum x < 100000
02:29:47<lambdabot> "OK, passed 500 tests."
02:29:51<ajdhs>@check \x y -> sum x < 100
02:29:52<lambdabot> "Falsifiable, after 76 tests:\n[-22,6,6,34,17,18,16,26,25,10,10,-16,14,-29,...
02:29:55<ajdhs>@check \x y -> sum x < 1000
02:29:57<lambdabot> "Falsifiable, after 298 tests:\n[124,27,-27,-27,100,-128,-97,72,-115,92,-45...
02:30:04<ajdhs>then that's a really long list to copy back in
02:30:11<ajdhs>also, in my case, it's really a Data.Map.Map
02:30:18<ajdhs>with lots of quotation marks and stuff
02:30:23<ajdhs>so it's a pain to copy and paste...
02:31:46<Saizan>you can put it in a file and use read
02:33:16<ajdhs>hm
02:33:17<ajdhs>yeah
02:33:24<ajdhs>I guess that's what I'll have to do
02:34:46<Gracenotes>hm. I have a monad that's like the state monad, but is actually a ReaderT IO that use an MVar for get and put. Is there a good way to start a thread that needs the MVar immediately, but also somehow put its ID into the MVar?
02:35:04<Gracenotes>using a (Maybe ThreadId) would take care of this, but it seems a bit hacky
02:35:26<Gracenotes>hm... mdo perhaps would be a good way. Seems a bit much though.
02:35:41<hydo>What is the general method for uninstalling a cabal package? I can't believe that everyone deletes ~/.ghc and ~/.cabal when things get really borked up.
02:35:55<bd_>Gracenotes: You could just put the threadid in the mvar after it starts. If it tries to take the mvar it'll just block.
02:36:32<roconnor>mdo is always a good way. :)
02:36:35<mauke>hydo: unregister it, then rm the library files
02:36:50<hydo>unregister with ghc-pkg, correct?
02:36:54<Gracenotes>oh, hm, that's right. The issue is that the MVar access is not direct, but through get and put.
02:37:25<Gracenotes>(get using readMVar)
02:38:16<Saizan>Gracenotes: forkR action = do var <- ask; id <- forkIO (runReaderT action var); put id
02:38:39<Gracenotes>Saizan: I already have a function that does that
02:39:03<Saizan>what's the problem with it?
02:39:06<Gracenotes>in fact, it's a typeclass, MonadFork, with fork :: m () -> m ThreadId
02:39:37<Saizan>then, \m -> id <- fork m; put id
02:39:47<Gracenotes>the issue is not starting the new thread, but rather putting the ThreadId into the MVar, when the ThreadId is not the only member of the MVar
02:40:12<Gracenotes>and other members of the MVar are needed immediately by the new threade
02:40:13<Gracenotes>-e
02:40:29<Saizan>oh, that's different
02:40:43<Saizan>i'd use a tuple of MVars probably
02:40:46<Gracenotes>I suppose I could have a half-second pause in the new thread. A bit suspect, though.
02:41:29<Gracenotes>hm. Or, having an MVar in the MVar
02:42:00<Gracenotes>or, as I said, a Maybe ThreadId.
02:42:58<Saizan>or mdo and pass the id as an argument
02:43:07<Gracenotes>argh. When you design something to be extensible, the lack of extensibility reveals itself to you the quickest
02:43:57<roconnor>mfix (\id -> newMVar id >>= \var -> forkIO (runReaderT action var))
02:43:57<Saizan>heh, maybe you want to use something like lenses
02:44:47<Gracenotes>roconnor: I'd use mdo. In fact I've already written something up using mdo. But there should be a better way...
02:44:57<roconnor>why should there be a better way?
02:45:38<Gracenotes>well, it's an IRC framework I've been working on-and-off about. If the user needs mdo to make it work... well... that's not a good start.
02:46:51<Gracenotes>then again it is also a general problem, of having all the data related to a game include the thread id, which is necessary for externally shutting it down
02:47:02<roconnor>Gracenotes: mfix plays a central roll in Oleg's object oriented framework
02:47:11<roconnor>you shouldn't fear it
02:48:29<Elly>hm, oleg has an OO framework?
02:48:42<Gracenotes>then... there's central role vs. hack to get around flaws in design. I'll play around with it a bit more.
02:48:51<roconnor>forkIO (myThreadId >>= newMVar >>= (runReaderT action)
02:48:55<roconnor>)
02:51:38<Gracenotes>in Java, it would be possible for the game to extend the Thread object. here it exists as a separate data object. Things couple differently in different languages, of course :)
02:52:57<roconnor>Gracenotes: what's wrong with using myTreadId to get the ThreadId at the beginning when the MVar is initiated?
02:55:48<Gracenotes>the thread id is not the only thing in the MVar. But, myThreadId would at least work, and I don't think any race conditions would result (although certainly possible). Keeping in mind that this isn't in IO, but a MonadIO, so just lifting would be needed.
02:56:15<Gracenotes>at least the race condition wouldn't happen in the game thread
02:57:47<roconnor>hmm, I guess I don't understand what you are doing.
02:59:33<Gracenotes>monad transformer stacks can do that to people
03:01:46<Gracenotes>the idea of the startGame function is, given some information available to configure a game, do the configuration (reading from files and sucih), store that in the Game data object (which includes score-keeping maps and game data) and start the thread that does the game
03:02:27<Gracenotes>the issue is that the function calling startGame will need access to the thread id, in order to kill it if requested (i.e. !stop)
03:03:27<Gracenotes>hm... I suppose I don't have to store the thread ID in the Game object... but keeping track of it is its own issue
03:04:07<Elly>is oleg just like... a professional bad person?
03:04:20<Gracenotes>>_>
03:05:24<monochrom>oleg is a professional good person
03:06:19<SamB>Elly: http://arcanux.org/lambdacats_3.html#entry4 <- you mean this oleg ?
03:06:45<Elly>monochrom: Oleg is the mirror that shows a normal person that they are stupid :P
03:06:53<Elly>SamB: probably :P
03:07:06<Gracenotes>ooh. there is a third lambdacats page?
03:07:30<SamB>Gracenotes: the new cats will be on the first one
03:07:36<Gracenotes>yes
03:07:58<Gracenotes>oh, and there are yet older ones
03:08:25<SamB>I do wish that site had permalinks, though :-(
03:11:44<jinjing>@seen snoyman
03:11:44<lambdabot>I haven't seen snoyman.
03:14:28<Elly>hmm
03:14:37<Elly>I need a big project to do this summer in either haskell or scheme
03:14:43<Elly>I don't know either of those languages well enough
03:15:17<SamB>Elly: why do you need a big project ?
03:15:26<hatds>(obvious comment about the "write yourself a scheme implementation" haskell tutorial)
03:15:38<Elly>SamB: I don't have time for them during the school year
03:15:57<SamB>ACTION wonders how Elly manages not to get tons of chores in the summer
03:16:09<Elly>I have a job :P
03:16:31<Elly>I don't live with my parents, so there's nobody to hand me chores
03:17:33<hydo>Ugh, I know I've read about it probably 10 times, but I can't remember and I'm not finding much on google.... what does the ! signify in "data DeliciousState = DeliciousState ![D.Post] !UTCTime"
03:18:13<monochrom>http://www.vex.net/~trebla/haskell/strict-field.xhtml
03:18:36<hydo>monochrom: awesome, thank you!
03:18:50<hydo>bookmarked for the next time my brain takes a vacation on me. ;)
03:21:53<Elly>hm
03:21:58<Elly>I could do the write-yourself-a-scheme one
03:22:01<Elly>that might be fun :)
03:23:43<monochrom>write yourself a résumé that says you know haskell and you are done with all the profitable languages and tools and paradigms and agile whatever.
03:24:56<Elly>the only language I feel comfortable saying I understand deeply is C :\
03:25:38<monochrom>You mean you know how to evalute 2["heya"] ?
03:28:15<Elly>I do, in fact, know what that does
03:28:19<Elly>it's 'y'
03:28:33<SamB>or that it's okay to say sizeof (struct { int foo; int bar; }) ?
03:28:50<Elly>I know that sizeof does not necessarily evaluate any part of its argument, yes
03:29:04<Elly>I also know about sizeof(*(int*)NULL)
03:29:12<SamB>ACTION tried to look it up when someone asked that in ##c the other day ...
03:29:39<Elly>that sizeof you gave has to work, since 'struct { ... }' is a valid type specifier
03:30:08<Elly>in any case
03:30:16<Elly>C is the only language I feel like I understand to that extent
03:30:21<Elly>I want to understand a better language that well :P
03:30:33<hatds>learn Haskell
03:30:47<Elly>that's why I was asking for something big to do in haskell before
03:30:55<monochrom>Whatever method you used to know C so well, use the same method on the better language.
03:31:12<Elly>the method I used to learn C was having to write a lot of stuff in C for classes and for work
03:32:28<monochrom>Hmm how did you know 2["heya"]? I imagine not from any project you did. Few people write it, and you wouldn't conceive it yourself --- I mean very unlikely.
03:32:44<Elly>oh, that I think I know from K&R
03:32:49<Elly>which I basically inhaled at one point
03:32:54<solrize>i think it is well known and obvious from the definition of []
03:33:04<Elly>it's straightforward when you know that a[b] is a + b
03:33:31<hatds>you should be inhaling everything out there about haskell
03:33:45<hatds>that's what I did 24/7 for like a month in the fall
03:33:45<monochrom>OK, then that means to duplicate the same level of knowing Haskell, you should inhale the Haskell98 Report too.
03:33:48<Elly>hm
03:34:12<rzezeski>ACTION is slowly nibbling on RWH, taking copious amounts of notes
03:34:31<hatds>the haskell report is a breeze compared to C gotchas imho
03:34:44<monochrom>Indeed I inhaled some part of it, and so I can tell you with 100% certainty what "newtype" means and what it doesn't mean.
03:34:58<hatds>but you can't just learn the gotchas for haskell to really be feel like you understand it
03:36:09<monochrom>I also inhaled some of Bird's "introduction to functional programming using haskell, 2ed" and so I know the foldl vs foldl' business.
03:36:32<Elly>hm
03:36:37<Elly>so Haskell 98, it seems
03:36:47<hatds>there so many papers to read too if you are into type system stuff
03:36:48<monochrom>(P.S. If you what to know, kfish's 東京 means Tokyo.)
03:36:59<Elly>I am, in fact, into type system stuff :)
03:37:13<Elly>I learned intuitionistic logic a little while ago and I rather like it
03:37:57<hatds>how much do you feel you know about haskell?
03:38:23<Elly>not a lot
03:38:29<Elly>I know SML far better than I know Haskell
03:39:47<hatds>are you past the tutorial stage or not yet?
03:40:19<Elly>well
03:40:40<Elly>I understand recursion and things like fold quite well, I think
03:40:50<Elly>I have never seriously tried to grasp monads
03:41:08<hatds>do you grasp IO?
03:41:37<Elly>I understand monads as sequencers for explicit effects
03:41:50<Elly>(we had that presented as an application of lax modalities in intuitionistic logic)
03:42:16<solrize>do you understand how the State monad works?
03:42:19<hatds>can you write a simple haskell program asking for input in the form of text and numbers and outputing back some strings?
03:42:39<Elly>I could if I looked at the reference manual, I think
03:42:51<hatds>you need to do it I think
03:43:01<Elly>solrize: I understand the concept of passing a "heap" object and of the monad concealing that from you
03:43:09<Elly>solrize: but that is the extent of my understanding of State
03:43:27<pao>what's the preferred way to provide Word8 literals?
03:43:46<dolio>> 15 :: Word8
03:43:48<lambdabot> 15
03:44:04<pao>> fromEnum '\n' :: Word8
03:44:05<lambdabot> Couldn't match expected type `Word8' against inferred type `Int'
03:44:15<solrize>elly the idea of State is that the actions in it are just a bunch of nested function calls
03:44:29<Elly>yeah; I think I understand the monads-as-CPS-transformers concept
03:44:30<pao>dolio: what if I wanted to "convert" a Char?
03:44:51<monochrom>> fromIntegral (fromEnum '\n') :: Word8
03:44:52<lambdabot> 10
03:45:00<hatds>well my opinion is this: you need to do basic "write this" tutorials that get you down and dirty with the syntax and type system.
03:45:01<pao>monochrom: thanks
03:45:06<Elly>hatds: alright
03:45:11<monochrom>fromIntegral is your all-purpose number converter.
03:45:20<Elly>ACTION goes off to write a program to take a string and print its length
03:45:26<solrize>> fromEnum '\n'
03:45:27<lambdabot> 10
03:45:35<solrize>> :t fromEnum '\n'
03:45:36<lambdabot> <no location info>: parse error on input `:'
03:45:40<monochrom>fromEnum gives you Int
03:45:58<pao>monochrom: ... and with realToFract the toolbox is ready ... :-)
03:46:04<mauke>main = interact (unlines . map (show . length) . lines)
03:49:28<soiamso>Char in ghc is a unicode char? Word8 safe?
03:51:03<monochrom>unicode. 8 bits are not enough.
03:52:06<Gracenotes>however, Word8 does equal C's unsigned char, at least on my machine >_>
03:52:15<Gracenotes>(32-bit)
03:53:13<mauke>you have 32-bit chars?
03:54:04<Gracenotes>I mean, 32-bit x86
03:54:07<monochrom>No, he means he has 8-bit chars. The "(32-bit)" is about the computer not C.
03:54:39<SamB>x86_32, I think they call it these days ...
03:54:55<SamB>(in Linux sources, if nowhere else!)
03:55:33<Gracenotes>perhaps only to distinguish between it and x86-64, I guess
03:56:08<SamB>well, they used to call it i386, I think
03:56:21<Saizan>Word8 is a pointer to a closure, anyhow
03:56:23<SamB>but then they merged it with the x86_64 code into one x86/ tree
03:57:06<Elly>that was surprisingly difficult to get right
03:57:12<Elly>and it is not as short as it ought to be
03:57:19<SamB>I know this because I'm in the process of documenting vm86(2)
03:57:29<Elly>SamB: my sympathies
03:57:47<Elly>that syscall and modify_ldt(2) both worry me deeply :P
03:57:47<SamB>you know something about vm86(2) ?
03:58:28<Elly>not in particular, but you're documenting a part of the linux kernel that touches something x86-specific
03:58:44<SamB>modify_ldt seems to be documented in much closer to the appropriate depth, as far as I can see
03:58:54<SamB>I mean, it's a much simpler call
03:59:06<Elly>they document two of the four legal values for func, at least :)
04:00:24<SamB>modify_ldt can work on x86_64 without crazy hacks, too, right?
04:00:51<Elly>um... I don't think it's necessary on x86_64, since most of the segments no longer exist
04:00:57<Elly>maybe it still is though
04:01:17<Elly>I know what modify_ldt does, but not the reason why it does it :P
04:02:55<jesmon>I'm trying to build package containers-0.2.0.1 (which is a dependency of yi-0.6) and it's failing because it can't find the module Data.Data
04:03:07<jesmon>but that module does seem to be on my system
04:03:33<Elly>is there a shorter way to write the following:
04:03:34<Saizan>jesmon: you need a more recent ghc
04:03:43<Elly>main = do x <- getLine; y <- return $ length x; putStrLn $ show y
04:04:01<jesmon>more recent than 6.10.1?
04:04:45<monochrom>main = do x<-getLine; let {y=length x}; putStrLn (show y)
04:04:51<monochrom>err
04:04:56<monochrom>main = do x<-getLine; let {y=length x}; print y
04:05:07<Elly>what's the let { ... } syntax?
04:05:09<Saizan>jesmon: ah, no
04:05:22<monochrom>If you use indentation, you will not need { }
04:05:23<Saizan>jesmon: then you've to pass --constraint="base >= 4"
04:05:37<Saizan>ACTION sighs
04:05:42<Elly>monochrom: why does the let make the return unnecessary?
04:05:43<jesmon>Saizan: I'll give it a try
04:05:54<Saizan>the core packages are the ones with more buggy .cabal files out there
04:06:14<SamB>Elly: last I got was: <Elly> maybe it still is though
04:06:43<SamB>then my mobo zonked out or something and the computer was rebooting ...
04:06:50<SamB>ACTION really needs to get that fixed :-(
04:07:02<Elly>SamB: I just said "I know what modify_ldt does but not why it exists"
04:07:02<hatds>Elly: you've heard of the explanation that IO (a) behaves like World -> (World,a) ?
04:07:15<monochrom>The do-notation supports "let".
04:07:15<Elly>hatds: yes, I am familiar with that idea
04:07:19<jesmon>Saizan: I got the same error, which is:
04:07:42<SamB>Elly: oh, DOSEMU uses it to emulate protected mode, and WINE to run 16-bit programs
04:07:45<jesmon>"Could not find module `Data.Data': it is a member of package base, which is hidden"
04:07:49<hatds>Elly: then the answer you want is essentially how do notation desugars into >>= and return
04:07:51<SamB>(also in protected mode)
04:08:05<Elly>hatds: sure, that would be good to know :)
04:08:27<SamB>Elly: well, truly it doesn't emulate protected mode, but just implements DPMI in a somewhat-unfriendly environment
04:08:48<Elly>x86 is by definition an unfriendly environment :)
04:09:04<SamB>I meant that it doesn't get to *touch* the IDT
04:09:16<Elly>ACTION nods
04:09:23<Saizan>jesmon: ok, unpack the package with cabal unpack, edit the .cabal file putting "base >= 4" in build-depends, and then run "cabal install" from there
04:09:29<hatds>Elly: http://www.haskell.org/tutorial/index.html under monads explains the desugar
04:10:41<SamB>Elly: and I think they can both do that on an x86_64 kernel just as well as on an x86_32 kernel -- not sure about either of them in a 64-bit userspace ...
04:11:14<Elly>thanks, hatds
04:13:31<jesmon>thanks, Saizan, the build succeeded :)
04:16:09<Saizan>jesmon: the reason is that cabal defaults to base-3 because many packages don't have an upper bound
04:16:23<Saizan>on base, in their build-depends
04:16:43<Saizan>but that works only if packages requiring base-4 have a lower bound
04:16:56<Saizan>ACTION badly wants a typechecker for packages
04:17:24<jesmon>hmm.. I'm having another problem, this time with building unix-2.3.2.0
04:17:43<Saizan>unix-2.3.2 requires base-4.1 iirc
04:17:47<Saizan>and that comes with 6.10.2
04:18:10<jesmon>looks like I need to upgrade then
04:18:25<jesmon>the error is: Module `GHC.Conc' does not export `Signal'
04:18:31<Saizan>yup
04:18:53<Saizan>yi explicitly depends on 2.3.2?
04:19:16<jesmon>looks like it to me...
04:19:47<Saizan>the cabal file doesn't specify a version
04:20:15<Saizan>btw, unix usually comes with ghc
04:20:52<Saizan>it doesn't have a version for containers either
04:20:57<Saizan>how are you isntalling yi?
04:21:04<jesmon>with cabal
04:21:19<Saizan>"cabal install yi"?
04:21:43<jesmon>cabal upgrade yi (from 0.5.2)
04:22:20<Saizan>ah! that's your problem
04:22:25<Saizan>use install
04:22:42<Saizan>upgrade tries to install the latest version of all the dependencies too
04:23:03<Saizan>which would work in a perfect world.. (discarding the ones you can't install on your system)
04:23:16<Saizan>but not in this one yet :)
04:24:32<Asztal>upgrade :: PerfectWorld -> (a, PerfectWorld)?
04:24:54<SamB_XP>Asztal: well, it would also sometimes work in imperfect worlds
04:25:51<deech>Hi all, I am trying to install the latest version of Haxml using cabal. cabal list the latest version as 1.19.7, but when I do a cabal install it downloads 1.13.3. I unregistered the HaXml package and deleted the cached package with the same results.
04:26:32<tennin>anyone familiar with staged type inference?
04:26:58<SamB_XP>tennin: do they use that in that meta-ML thingy ?
04:27:09<tennin>I think so
04:27:35<tennin>I'm trying to read the paper "dynamic typing as staged type inference" from 1999, but I can't seem to get a PS viewer installed on this windows computer
04:28:07<SamB_XP>tennin: try running ps2pdf over it ?
04:30:07<jesmon>Saizan: Bingo! "cabal install yi" successfully built and installed it. but I have this strange thing in ~/.yi/yi-x86_64-linux which is getting executed and which is still 0.5.2
04:30:12<monochrom>install a virtual machine such as vmware or virtualbox. install linux inside it. install a PS viewer inside that.
04:30:29<tennin>=)
04:30:33<jeffz`>I've never had a problem with gs + gsview on Windows
04:30:43<jesmon>yi --version
04:30:43<jesmon>Launching custom yi: "/home/jesse/.yi/yi-x86_64-linux"
04:30:43<jesmon>yi 0.5.2
04:30:43<jesmon>
04:30:53<jesmon>pardon
04:33:15<Saizan>jesmon: touch yi.hs , it should recompile yi-x86_64-linux on restart that way
04:33:23<jesmon>ok, just moving removing the "custom yi" worked
04:33:53<tennin>anyway, what I'm looking for is a better solution to the problem where I am dealing with some data that is a type that is only known at runtime, but is a definite type that will remain fixed after it's determined in some preliminary stage of processing
04:33:53<jesmon>yi --version then said "Recompiling custom yi" and reported the correct version
04:34:15<tennin>e.g. database schema, or even CSV header
04:34:59<Saizan>deech: 1.13.3 is the preferred version, if you want 1.19.x you've to ask for "HaXml >= 1.19"
04:35:03<jesmon>anyhoo, cabal is quite confusing to me so far :|
04:35:14<tennin>it seems to me that rather than foregoing all type safety because I don't know the type at compile-time, I should be able to use the typechecking machinery at runtime
04:35:18<jesmon>Saizan: thanks for all your help
04:35:24<Saizan>jesmon: np
04:35:30<Saizan>jesmon: there's a Cabal faq
04:36:13<tennin>thanks for the ps2pdf recommendation
04:36:15<Saizan>http://www.haskell.org/cabal/FAQ.html <- needs more entries, probably
04:37:17<Saizan>tennin: uhm, you can use gadts and/or existentials for that
04:46:27<solrize>ghc 6.10 introduces memory leaks into programs that didn't leak under 6.8.3??!
04:48:28<jackdempsey>hey guys, pretty basic q but feel like i'm missing something key
04:48:34<tennin>hmm, ok
04:48:34<jackdempsey>was looking at the definition of read
04:48:46<jackdempsey>and didn't get why 'a' was ambiguous
04:48:50<jackdempsey>then saw some other examples like
04:48:53<jackdempsey>rInt :: String -> Int
04:48:53<jackdempsey>rInt = read
04:49:04<jackdempsey>and i see whats going on, but maybe not why....
04:49:20<jackdempsey>i mean, it looks like you're basically saying, read, i need back an int, go do your thing
04:49:50<tennin>Saizan: yeah, I think I can see the GADT approach
04:50:02<jackdempsey>so if you have a function foo :: String -> a
04:50:16<jackdempsey>you can then do things like bFoo :: String -> Bool
04:50:21<jackdempsey>bFoo = foo
04:50:47<Jebdm>jackdempsey: you can also use an inline type annotation
04:50:49<jackdempsey>not even sure how to google on this, hence me asking here :-)
04:50:56<jackdempsey>ok
04:51:16<Jebdm>ex. (read something :: Int)
04:51:31<jackdempsey>i see
04:51:32<mauke>the read thing works because we have return-type-based overloading
04:51:37<jackdempsey>ahh
04:51:45<jackdempsey>i think thats what i'm trying to grasp at
04:52:08<jackdempsey>i also didn't see how i was supposed to know from read :: String -> a that to call it i needed read "12"::Int
04:52:16<jackdempsey>but maybe thats not really important
04:52:29<jackdempsey>return-type-based overloading.....definitely haven't heard of that before
04:52:32<Saizan>it's read :: Read a => String -> a
04:52:34<jackdempsey>is that common in functional languages?
04:52:40<mauke>not really
04:52:59<mauke>I think most languages don't have typeclasses
04:53:03<jackdempsey>Saizan: yes definitely, thx for clarification. that should be enough to tell me about the ::Int part?
04:53:06<hatds>I love SPJ's spiel on return type overloading
04:53:16<jackdempsey>interesting
04:53:52<Saizan>jackdempsey: well, when a type variable has a typeclass constraint on it you need to choose a concrete type for it somehow
04:54:07<Saizan>jackdempsey: often just using the result in the rest of the code is enough
04:54:15<jackdempsey>ok
04:56:57<jackdempsey>k, possibly foot -> mouth here....but why is "Read a" in that definition capitalized?
04:57:14<jackdempsey>i'm used to some things capped because they're monads
04:57:19<mauke>heh
04:57:24<jackdempsey>modules
04:57:24<jackdempsey>hehe
04:57:32<mauke>in general, variables are lowercase and constants are uppercase
04:57:44<mauke>Int is a concrete type, a is a type variable
04:58:00<mauke>Read is the name of a class. I don't think we have class variables
04:58:04<jackdempsey>k, my terminology is sorely lacking, but i think i'm getting the ideas a little more each time i approach it
04:58:07<hatds>er not "constants" in the sense of values though
04:58:09<jackdempsey>ahh ok
04:58:39<Gracenotes>mmm. hot chocolate. ... in the summer. :\
04:58:50<jackdempsey>mmm, bourbon :-D
04:58:53<Gracenotes>yum though
04:59:00<mauke>> let true = False in true
04:59:02<lambdabot> False
05:09:47<deech>Hi all, using Haxml, once a string is parsed into Haskell's XML representation, is there a way to lookup the attributes and content by tag
05:41:11<Gracenotes>mm. now it is time to see whether these wasabi peas are too hot for me or not. I suspect not.
06:03:22<halberd>has anybody tried to draw a link between types and statistical inference?
06:04:50<halberd>e.g., you give the line of best fit a type that says "this is the line of best fit for the data set D"
06:05:25<halberd>and how would that play out when your fit is only approximate, not exactly the best
06:22:14<Lemonator>I got a huge function,
06:22:30<Lemonator>but no segment of code inside is used twice.
06:22:37<Lemonator>Is it still worth it to break it up?
06:25:20<cads>hey, can reversible computing be implemented with conventional electronics?
06:26:03<QtPlaty[HireMe]>I've seen reversible computing implemented mechanitcally.
06:27:05<cads>what did it do?
06:27:36<Saizan_>Lemonator: yes, there are many reasons 1) you can test the subparts separately 2) with good names the overall logic becomes easier to read 3) you never know if/when you'd reuse something in the future
06:28:17<Lemonator>It seems like a pain in the ass to do, though.
06:28:22<Lemonator>behold:
06:28:30<Saizan_>don't paste here!
06:28:33<copumpkin>lol
06:28:34<Saizan_>@hpaste
06:28:34<lambdabot>Haskell pastebin: http://hpaste.org/new
06:29:24<Lemonator>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4978#a4978
06:29:28<Lemonator>what?
06:31:50<copumpkin>how would you test a function like that?
06:31:52<Saizan_>Lemonator: that looks like it could be written with less code, actually
06:32:39<Lemonator>oh?
06:33:19<copumpkin>a 5-tuple :o
06:33:41<Saizan_>instead of calling parse multiple times you could define a datatype like data Result = Ping .. | NewTopic .. | Message ..
06:33:44<Twey>Ew, a pentuple
06:34:08<copumpkin>using a record-based type instead of those n-tuples might make updating specific parts of them easier
06:34:56<Lemonator>what kind of record-based type?
06:35:04<copumpkin>respond (s, n, i, r, t)
06:35:09<Saizan_>then result = Ping `fmap` ping <|> NewTopic `fmap` newTopic <|> Message `fmap` message
06:35:18<copumpkin>it looks like your parse function returns a pentuple
06:35:24<Lemonator>yeah
06:35:34<copumpkin>which could probably be a nice type with record accessors
06:35:43<Saizan_>and case parse result of Right r -> case r of Ping .. -> ..; NewTopic .. -> ..; ..
06:35:54<Saizan_>parse result s, i meant
06:36:36<Saizan_>yeah, you could stick those in the Message constructor
06:36:48<copumpkin>it seems like you're using Right/Left as a kind of Maybe
06:37:02<copumpkin>you always ignore the Left
06:37:05<copumpkin>value
06:37:15<copumpkin>oh, I guess it's an error value?
06:37:20<Lemonator>well, parse returns an error value with Left,
06:37:25<Lemonator>and I really don't need it.
06:37:48<copumpkin>but yeah, doing it as Saizan said would get rid of a lot of that stuff
06:37:54<Lemonator>hm
06:37:59<copumpkin>since it's parser logic you're writing out by hand
06:38:26<Saizan_>if you're using parsec you might need to add "try" there
06:41:42<SubStack>blarg, updating a tree with multiple entrypoints into that tree is especially tricky
06:42:36<SubStack>since regular zippers are all about singlular active nodes
06:42:43<SubStack>from what I can tell
06:42:54<copumpkin>you could easily give it a constant number more
06:43:45<SubStack>and have the updates and insertions reflected in all of them?
06:44:04<copumpkin>oh, no
06:44:07<copumpkin>how do you mean?
06:45:31<Saizan_>oleg has "concurrent" zippers implemented with delimited continuations on its site
06:46:33<SubStack>I've come accross that page but I'll read it again
06:47:51<SubStack>hmmm I missed the push/pull idea before
06:49:42<SubStack>especially since the cursors will only sometimes actually need the updates
07:21:58<_vikrant_>sum
07:22:07<juhp>is http://code.haskell.org down?
07:23:00<_vikrant_>looks like
07:23:14<_vikrant_>me too... unable to open
07:23:37<_vikrant_>map
07:23:55<_vikrant_>:t map
07:23:56<lambdabot>forall a b. (a -> b) -> [a] -> [b]
07:26:15<mathijs>small question: I'm playing around with the FFI with help of RWH. this describes how to use c library functions from haskell. Is there some tutorial/info available on doing it the other way around? (using a haskell library from C)?
07:26:37<mathijs>or is this problematic because of the RTS needing to be loaded?
07:27:10<Gracenotes>iirc, two-way communication is possible
07:27:48<mathijs>ok, I hoped so, but I couldn't find a nice example of it.
07:27:48<Gracenotes>as far as I know Haskell "initiates" the communication with ccall declarations, though.
07:28:29<Gracenotes>I think the guide might be most useful: http://www.cse.unsw.edu.au/~chak/haskell/ffi/
07:28:36<Gracenotes>or other guides, if any exist. hm...
07:29:05<Gracenotes>these are some blog articles, anyway. http://www.haskell.org/haskellwiki/Blog_articles/FFI
07:29:11<Gracenotes>not sure if they contain this info.
07:29:16<mathijs>ok, so if haskell initiates everything, it has to be the main binary right? I would like to just have some header file and .o object file to link against
07:30:56<Gracenotes>the first guide is, rather, the spec
07:31:35<mathijs>yeah I figured :) I'm not good at specs, ofcourse I can read them and find the info I need in the end, but I prefer a more basic example :)
07:32:12<Gracenotes>.nod.
07:32:31<mathijs>anyway, thanks for helping. I'll dig through it :)
07:52:43<copumpkin>Heffalump: I managed to get a free account with ARM :D
07:56:41<myname>exit
08:15:40<hydo>Looking at http://snurl.com/i922z , that's just crazypants use of . and not some sort of objective haskell mutant syntax, right?
08:17:20<copumpkin>> let f = \n m -> length . concat . (replicateM n >=> replicateM m) $ [undefined] in f 5 6
08:17:22<lambdabot> 93750
08:17:24<opqdonut>hydo: well the first . is looking up a name from the S namespace
08:17:26<copumpkin>> let f = \n m -> length . concat . (replicateM n >=> replicateM m) $ [undefined] in f 6 6
08:17:28<lambdabot> 279936
08:17:31<opqdonut>the second is just normal composition
08:17:42<copumpkin>> let f = \n m -> length . concat . (replicateM n >=> replicateM m) $ [undefined] in f 6 7
08:17:44<lambdabot> 1959552
08:17:57<copumpkin>that's pretty fast growth
08:18:36<hydo>copumpkin: right... it's just the same old . that I've come to know and love... just making sure. I've had to work with ruby lately so it was a bit of a shock to see it used that way at first. Just making sure that the world is still round, the sky is up, etc.
08:18:46<copumpkin>?
08:18:54<hydo>oops
08:19:02<copumpkin>oh :)
08:19:17<hydo>s/ copumpkin / opqdonut / :)
08:19:29<opqdonut>:)
08:19:47<Apocalisp>irc is hard
08:19:49<opqdonut>the letters are like right nexto to eachother
08:20:03<opqdonut>-o
08:50:45<fasta>Why can't cabal simply work? Or, please give me a reason to still use cabal install... http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4980#a4980
08:53:14<opqdonut>hehe
08:53:58<wjt>what notation for versioned dependencies does the cabal that shipped with ghc 6.8 support? i want to explicitly depend on base 3, but apparently the bundled cabal in ghc 6.8 chokes on 'base == 3.* '
08:56:15<Axman6>hmm, so i'm reading http://www.cs.umd.edu/~avik/projects/cmllch/... does anyone understand what Concurrent ML does that's so special? i can't seem to understand what's actually happening, or why you would do it/want to
08:59:02<quicksilver>wjt: try base < 4 ?
08:59:16<fasta>Axman6: Didn't they have rendez-vous concurrency?
08:59:23<pejo>Axman6, Concurrent ML is rather old, and as you've figured out based on ML.
08:59:37<fasta>Axman6: I never used it, but Scheme 48 copied it, AFAIK.
09:00:09<wjt>quicksilver: lessee...
09:00:28<Axman6>either of you have a (hopefully not too long) explanation of what it's supposed to do? like how you'd use/what it does when used?
09:00:50<wjt>ACTION roundtrips to the bug reporter...
09:05:04<pejo>Axman6, CML extends SML with synchronous message passing (typed channels). CML has been around since atleast 1991, so it's probably older than any message passing toolkits for Haskell.
09:05:27<xenoblitz>Hi people, some a simple question: Does anyone know of a document which compares Phantom types and GADTs?
09:05:35<xenoblitz>* remove some
09:05:46<ejt>does anyone have an alternative link for Simons 'Fun with Type Functions' paper, microsofts seem to be having trouble with their webserver ?
09:06:50<xenoblitz>ejt: I managed to download hit here :/
09:06:56<xenoblitz>*it
09:07:16<ejt>xenoblitz: I've been trying for the last hour, no luck
09:07:39<ejt>and there's a comment on reddit from a couple of days ago saying the website is donw
09:07:45<ejt>s/donw/down/
09:08:09<xenoblitz>ejt: this one right? http://haskell.org/haskellwiki/Simonpj/Talk:FunWithTypeFuns
09:08:20<ejt>y
09:08:56<xenoblitz>weird I clicked the link and it downloaded :S
09:09:00<quicksilver>xenoblitz: it would be strange to compare them.
09:09:01<ejt>oh
09:09:03<quicksilver>xenoblitz: they are isomorphic.
09:09:08<quicksilver>xenoblitz: erm. wrong word.
09:09:11<quicksilver>xenoblitz: they are orthogonal!
09:09:23<quicksilver>xenoblitz: you can use phantom types and gadts separately, you can use them together
09:09:34<quicksilver>they're not alternatives.
09:09:40<xenoblitz>quicksilver: so you are basically saying they are used for different things?
09:10:04<xenoblitz>quicksilver: unfortunately I don't know what orthogonal means :(
09:10:19<xenoblitz>ejt: want me to email it to you somehow?
09:10:26<ray>at right angles
09:11:03<xenoblitz>ray: so different areas of applications?
09:11:53<quicksilver>xenoblitz: it means more or less what I followed up by saying.
09:12:00<quicksilver>They are independent - you can use one or the other or both.
09:12:13<quicksilver>I'm not sure how you'd compare & contrast them
09:12:56<quicksilver>a phantom type is a type you use "only" for type checking, but don't expect to have real members.
09:13:12<quicksilver>a GADT is an extension to an ADT which lets your constructors be less than fully polymorphic.
09:14:44<Workybob>I hate object oriented programming
09:14:58<Workybob>to define this data type I need more Objective-C files than I need lines in Haskell >.<
09:15:18<quicksilver>haha.
09:16:49<quicksilver>Workybob: I'm contributing to a C++ project where the author splits his class hierarchy into class CFoo : class IFoo, where IFoo is a pure virtual interface class. It's quite a sensible way to get real abstraction into C++ but OMG! the boilerplate
09:17:09<Workybob>hehe
09:18:06<ivanm>quicksilver: lol
09:18:41<quicksilver>three files for each new data type - interface/foo.h, foo/foo.h and foo/foo.c++
09:18:51<quicksilver>makes me want an IDE :)
09:19:23<ivanm>ACTION assumes the .c++ file actually contains the code
09:19:35<xenoblitz>quicksilver: thanks for your pointers :) somehow they clarified things a bit
09:20:02<quicksilver>xenoblitz: good :)
09:27:33<ivanm>http://downforeveryoneorjustme.com/code.haskell.org :(
09:28:38<thoughtpolice>ivanm: yeah, it's really annoying
09:29:38<ivanm>who runs that server?
09:30:39<thoughtpolice>i think it's run out of galois or something
09:30:51<thoughtpolice>couldn't be sure though
09:32:21<ivanm>http://haskell.org/haskellwiki/Haskell.org_domain
09:32:31<ivanm>doesn't say who runs it...
09:33:24<ivanm>"hosted commercially"
09:33:29<ivanm>http://www.haskell.org/pipermail/haskell-cafe/2008-January/038759.html
09:33:40<ivanm>methinks a new host is needed...
09:34:58<ivanm>IIRC, planet.h wasn't loading about 8 hours ago...
09:35:02<ivanm>and still isn't :(
10:13:47<Xen0x>Can someone explain the need for all the # signs in the GHC Prim.hs (libraries/GHC-prim/GHC/Prim.hs)?
10:14:08<quicksilver>"need" ?
10:14:10<fasta>Is there anyone here with inside knowledge on the xml package? There seems to be some weird choices in it.
10:14:16<quicksilver>they're a convenitoin, that's all, xenoblitz
10:14:21<fasta>Xen0x: it's for extra 1337 points.
10:14:22<quicksilver>Xen0, sorry.
10:14:34<quicksilver>they conventionally denote compiler internals or compiler primitives
10:14:44<quicksilver>which should not, for example, appear in public APis.
10:14:48<fasta>Xen0x: ____INTERNAL___ is old, # is the new thing.
10:15:15<fasta>Xen0x: or you know what quicksilver says, but I think by explanation is more fun.
10:15:15<Xen0x>Ahh ok. I thought it was some kind of compiler optimization or something :)
10:15:22<Baughn>Xen0x: Of course, some of them end up exported anyway, but if you see # you know it's too low-level to use
10:16:16<Xen0x>Ok. I just bummed into it, because i'm looking into the whole foreign pointer thing and especially the stablePointer
10:28:42<fasta>What should this do according to you? takeUntil isNothing [Nothing]
10:29:28<Baughn> I'd say.. return nothing.
10:29:36<Peaker>> takeUntil isNothing [Nothing]
10:29:37<Baughn>> takeUntil isNothing [Nothing]
10:29:38<lambdabot> Not in scope: `takeUntil'
10:29:38<lambdabot> Not in scope: `takeUntil'
10:29:52<fasta>Baughn: if by that you mean [], then I agree.
10:29:53<Baughn>> takeWhile (not.isNothing) [Nothing]
10:29:53<lambdabot> []
10:30:15<fasta>Baughn: unfortunately, that's not what the people writing Gofer thought...
10:30:23<Baughn>fasta: Eh?
10:30:33<fasta>Baughn: http://hackage.haskell.org/packages/archive/gofer-prelude/2.30.2/doc/html/src/Prelude-Gofer.html#takeUntil
10:30:46<Baughn>Oh dear
10:31:23<fasta>They managed to define takeUntil as takeUntilAndIncludeTheElementForWhichTestTestSucceeds
10:31:34<fasta>The*
10:31:46<fasta>Most people think until means <
10:31:49<fasta>Not <=
10:32:20<yitz>Why do "magic hashes" parse at all? It seems according to the Report that the hash should begin a new lexeme.
10:32:35<quicksilver>yitz: it would.
10:32:44<quicksilver>yitz: that's why there is a MagicHash extension.
10:32:53<doserj>take n xs ++ drop n xs == xs, so I would suggest takeUntil p xs ++ dropWhile p xs == xs
10:33:01<yitz>kind of ugly actually
10:33:12<quicksilver>yitz: (this makes it impossible for haskell98 code to 'accidentally' use a foo# identifier, so they are safe)
10:33:25<quicksilver>I would compare it to the why LaTex uses illegal @-identifiers internally
10:33:39<quicksilver>and redefines the catcode of @ for internal files.
10:33:40<doserj>erm,
10:33:51<doserj>ignore me
10:35:14<doserj>takeUntil p = takeWhile (not.p) and takeWhile p xs ++ dropWhile p xs == xs
10:38:21<povman>Who here actually uses list comprehension syntax?
10:38:49<horms>i do sometimes - though i don't code that much haskell
10:39:09<Baughn>I just list /monad/ syntax on occasion; anything small enough to be a comprehension tends to end up not being one
10:40:11<povman>It seems a bit useless to me.
10:40:51<Baughn>It's convenient if you're coming to haskell from other languages with list comprehensions
10:41:07<Baughn>And it's just a simplified version of monad syntax anyway. It doesn't get in the way.
10:41:08<yitz>povman: I use them all the time and I love them.
10:41:52<quicksilver>I find it occasionally convenient
10:41:56<povman>yitz: That's good to hear :D I feel bad about not using them (silly huh)
10:42:02<yitz>heheh
10:42:11<quicksilver>especially for what would in C be two nested looks
10:42:20<Ferdirand>sometimes I wish it would work on any MonadPlus, not just on lists
10:42:35<quicksilver>sequence_ [ drawPrettyThing a b | a <- [1..10], b <- [5,10..100] ]
10:43:03<yitz>They are really just a kind of specialized do notation that often (but not always) makes list monad expressions more human readable.
10:43:17<yitz>I like human readable code.
10:44:57<quicksilver>Ferdirand: I don't believe the desugaring of list comps ever uses (++) or mplus - no MonadPlus required?
10:45:16<Ferdirand>quicksilver: for conditions ?
10:45:38<quicksilver>oh, guard.
10:45:46<quicksilver>guard shouldn't be in MonadPlus, but it is, you're right.
10:45:55<Saizan_>MonadZero :)
10:52:57<opqdonut>hrmm, i do :back and get Exception: Prelude.undefined
10:53:19<opqdonut>the break was triggered by an undefined, and i can do one :back but the second fails
10:54:43<opqdonut>when i change the undefined into an error, :back works
10:56:02<fasta>dons: I am not sure whether loch was intended as a toy or not, but rewrite :: (TokenType,String) -> (TokenType,String) is too simplistic to work on real Haskell code. For toy examples it works fine, however. An example of something which does not work: export lists.
10:57:39<Peaker>fasta: well, if takeUntil includes that last element, it is more useful than if it is just takeUntil = takeWhile . not
10:58:22<fasta>Peaker: it might be more useful, but it's not what the name says.
10:58:46<Peaker>fasta: what name would say that?
10:58:51<fasta>Peaker: I.e. "take" something _until_ some condition. Not until and also include that element.
10:58:53<Peaker>(reasonable name :-)
10:59:17<fasta>Peaker: it would probably be a horrible name, but that's besides the point.
11:00:13<Peaker>fasta: I agree the name kind-of-implies that the last element is not included, but it does not equivocally say so
11:00:29<Peaker>unequivocally, that is
11:01:00<Peaker>@unpl takeUntil = takeWhile . not
11:01:00<lambdabot>takeUntil c = takeWhile (not c)
11:02:47<int-e>@unpl ap const id
11:02:48<lambdabot>((\ a _ -> a) >>= \ d -> (\ b -> b) >>= \ c -> return (d c))
11:09:14<jelly12gen>@info show
11:09:14<lambdabot>show
11:09:24<jelly12gen>@show
11:09:24<lambdabot>""
11:12:52<mgsloan>some #math people are dicks. I suppose it'd be bad to ask a totally unhaskell question here, even though there are some awesome math people here?
11:14:02<quicksilver>mgsloan: well, depends what it is. If it's a part of maths which is related to haskell like CPOs or categories, then they are sometimes discussed here
11:14:14<quicksilver>mgsloan: otherwise there is always #haskell-blah
11:14:47<mgsloan>yeah, true. Ah, good idea. I'm afraid it's related to number theory rather than modern algebra
11:15:21<Peaker>#haskell has 590 people, and #-blah has 64, though
11:15:30<burp_>@users
11:15:31<lambdabot>Maximum users seen in #haskell: 658, currently: 591 (89.8%), active: 14 (2.4%)
11:15:33<Peaker>mgsloan: are you talking about that TRWBN or what's his name? :)
11:15:54<Peaker>mgsloan: a friend told me that #mathematics (I think that was the name) is better than #math
11:16:18<poucet>alias
11:16:56<mgsloan>Peaker - Jafet, actually, but #math certainly has its collection of oddities
11:17:07<Twey>12:16:56 *** #mathematics 40 This channel is for seminars. Go to #math for math help.
11:20:41<ivanm>mgsloan: IIRC, roconnor or Cale have given seminars in #mathematics before...
11:20:53<ivanm>s/mgsloan/Twey/
11:21:00<mgsloan>yeah, I know Cale is a math guru
11:21:12<mgsloan>read his treatsie on the whole nullity thing haha
11:21:28<Twey>ivanm: Hmn, might be worth hanging around in there, then
11:21:29<Peaker>fasta: inspired by the last discussion, I wrote a little something that lets you: main = print . take (more 1 $ listPred (<3)) $ [1..10] -- results in [1,2,3]
11:21:49<Peaker>fasta: no need for the "more useful" takeUntil that way
11:22:11<Peaker>list split predicates: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4985#a4985
11:28:58<Peaker>What interesting class instances can this have? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4985#a4987
11:29:40<Peaker>hmm.. ListPred is probably a bad name, because it specifically splits lists, not filters them, etc
11:34:02<Peaker>Maybe the Data.Split module should have something like this? Its nice to be able to apply transformations to a split (such as take-some-more, etc)
11:34:48<Peaker>it does mean that building the thing by which you split is separate from applying it (an extra function application to use splitters) but it allows for more interesting combinations of splitting
11:36:06<Axman6>Tip: Excel absolutely sucks for statistical analysis, even for basic things like linear regression
11:36:22<Axman6>resist the urge!
11:36:49<Peaker>Excel is nice for being a "live" functional language, even if a weak one with really bad numeric types
11:37:34<Botje>can Excel have bottom?
11:37:45<Axman6>it is bottom
11:37:47<Axman6>rock bottom
11:37:51<Botje>:)
11:37:53<thomastc>it can kiss mine
11:38:04<yitz>Peaker: ghci is also live. The advantage of Excel is that it gives you typesetting much more conveniently than, say Cairo, at the moment.
11:38:08<Axman6>as much as MATLAB is a pain, it does shit right!
11:38:58<yitz>Botje: as in Haskell, Excel has several forms of bottom. For example, there is this blue screen...
11:39:10<thomastc>there is also the flight simulator
11:39:11<Peaker>yitz: maybe "live" was the wrong word. Excel is nice for allowing you to update the code and automatically get all of the data-dependencies updated automatically
11:39:15<thomastc>which is its best feature
11:39:32<thomastc>and it also has a bottom
11:40:00<Botje>:]
11:40:02<yitz>Peaker, yeah, but you can do that in ghci also.
11:40:35<Peaker>yitz: how?
11:43:00<yitz>Peaker: you define functions in terms of other variables using let. if you redefine a variable, you then up arrow to the function you want the current value of and hit enter.
11:45:16<Peaker>yitz: that means you manually update the dependencies
11:45:56<Peaker>yitz: the interesting thing in Excel is that it finds all the dependencies automatically, updates them, and dependencies can be interesting charts too
11:46:21<Peaker>Ok, now I have: (take . more 1 . splitBy $ (<"haha")) ["arc", "hello", "world"] == ["arc","hello"]
11:48:52<povman>I have nested 'withXXXX'. This is not the first time that has happened. The code looks remarkably like do notation.
11:49:43<povman>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2440#a2440
11:50:03<quicksilver>yup.
11:50:07<quicksilver>common pattern.
11:50:24<povman>I keep getting a hunch that it's a monad of some sort but I don't think it is
11:51:05<lilac>povman: looks like a simple form of a continuation monad?
11:51:32<lilac>although i'd be concerned about the associativity of bind
11:52:49<quicksilver>@hoogle withArgs
11:52:49<lambdabot>System.Environment withArgs :: [String] -> IO a -> IO a
11:53:06<MyCatVerbs>lilac: bind's right-associative, and monad laws mean that the associativity of it doesn't actually matter, no?
11:53:14<quicksilver>it's like a delimited bind.
11:53:29<quicksilver>I'm not sure if it relates to a monad
11:53:32<quicksilver>except by analogy
11:53:35<lilac>MyCatVerbs: i meant, i'm not sure that the bind of this "monad" is associative
11:54:14<povman>also, return is hard to define (if not impossible)
11:55:53<MyCatVerbs>lilac: oh, I thought you meant (>>=). My bad.
11:56:13<povman>I once read that if I have something that is like a monad but isn't, then it might be an Arrow
11:57:38<Peaker>povman: I think its better to try to come up with your own combinators and then later see if they match some existing type-class
11:57:55<povman>ah, good idea
11:59:02<Peaker>povman: where's withArgs from?
11:59:12<povman>System.Environment
11:59:25<povman>@src withArgs
11:59:26<lambdabot>Source not found. You speak an infinite deal of nothing
11:59:41<Peaker>withArgs :: [String] -> IO a -> IO a ?
11:59:51<Peaker>@type System.IO.withArgs
11:59:53<lambdabot>Not in scope: `System.IO.withArgs'
11:59:59<Peaker>@type System.Environment.withArgs
11:59:59<povman>ah yeah, my paste totally doesn't compile
12:00:01<lambdabot>forall a. [String] -> IO a -> IO a
12:03:01<povman>and i completely didn't read the type of 'withArgs' before i used it
12:06:20<Saizan_>povman: for with* functions nested like that you can use the ContT IO monad to get do-notation
12:06:21<lilac>povman: withArgs temporarily /sets/ the args
12:06:47<povman>lilac: I realise this now :D
12:06:57<lilac>povman: you probably just want do { args <- getArgs; ... }
12:07:16<povman>lilac: I was getting carried away with the nesting
12:07:28<povman>lilac: and turned my getArgs into a withArgs
12:07:31<Saizan_>?type ContT withFile "foo" ReadMode
12:07:31<lambdabot>Not in scope: `withFile'
12:07:32<lambdabot>Not in scope: data constructor `ReadMode'
12:07:47<povman>Saizan_: That's very interesting. I'll investigate
12:08:26<Saizan_>you then wrap the whole thing in "runContT return"
12:08:41<povman>oh of course!!!
12:15:01<lilac>@type do ss <- ContT (Foreign.withMany Foreign.C.withCString ["hello", "world"]); (n, xs) <- ContT $ Foreign.withArrayLen ss . curry; return $ ?c_main (toEnum n :: Foreign.C.CInt) xs
12:15:02<lambdabot>forall r a. (?c_main::Foreign.C.Types.CInt -> GHC.Ptr.Ptr Foreign.C.String.CString -> a) => ContT r IO a
12:15:12<Peaker>povman: I also tried creating a newtype to describe those "with"s and I get:
12:15:13<Peaker>newtype Bracket m i o = Bracket { unBracket :: (i -> m o) -> m o }
12:15:13<Peaker>combine :: Monad m => Bracket m i1 o1 -> Bracket m i2 o2 -> Bracket m (i1, i2) (o1, o2)
12:15:36<Peaker>povman: so it might also be seen as a kind of arrow, maybe
12:16:48<lilac>@type flip runContT return $ do ss <- ContT (Foreign.withMany Foreign.C.withCString ["hello", "world"]); (n, xs) <- ContT $ Foreign.withArrayLen ss . curry; return $ ?c_main (toEnum n :: Foreign.C.CInt) xs
12:16:50<lambdabot>forall a. (?c_main::Foreign.C.Types.CInt -> GHC.Ptr.Ptr Foreign.C.String.CString -> a) => IO a
12:17:11<lilac>that look about right?
12:18:50<povman>All those ContT make my eyes fall out
12:20:01<povman>what the
12:20:13<Peaker>@type map ?f
12:20:15<lambdabot>forall a b. (?f::a -> b) => [a] -> [b]
12:20:17<povman>@t (+1) >>> (*2)
12:20:18<lambdabot>Maybe you meant: tell thank you thanks thx ticker time todo todo-add todo-delete topic-cons topic-init topic-null topic-snoc topic-tail topic-tell type . ? @ ft v
12:20:33<povman>@type (+1) >>> (*2)
12:20:35<lambdabot>forall b. (Num b) => b -> b
12:20:50<povman>((+1) >>> (*2)) 3
12:20:57<povman>> ((+1) >>> (*2)) 3
12:20:59<lambdabot> 8
12:21:03<povman><3
12:22:00<Peaker>how do implicit args work? how do you give them to functions? Don't they essentially add multi-arg functions to Haskell and ruin composability of functions?
12:22:59<quicksilver>they ruin everything.
12:23:16<quicksilver>let ?foo = 5 in {- expression including functions with implicit foo arg -}
12:23:21<quicksilver>is how you use them.
12:28:30<Peaker>@type filter isNull . map ?f
12:28:32<lambdabot>Not in scope: `isNull'
12:28:35<Peaker>@type filter null . map ?f
12:28:37<lambdabot>forall a a1. (?f::a1 -> [a]) => [a1] -> [[a]]
12:28:47<Peaker>quicksilver: seems like they're still composable
12:29:28<Peaker>@type (.)
12:29:29<lambdabot>forall b c a. (b -> c) -> (a -> b) -> a -> c
12:29:33<qaz>I've realized
12:30:04<quicksilver>Peaker: yes, you can still (.) compose them
12:30:05<qaz>it is dynamic languages that are restrictive, not static ones
12:30:09<quicksilver>Peaker: they don't ruin *everything*
12:30:12<Peaker>quicksilver: what compositions are destroyed?
12:30:12<quicksilver>Peaker: just, most things.
12:30:37<quicksilver>various natural code restructurings
12:31:47<fasta>How can I disable recursive expand for whatever is interpreting CPP? I thought the default was not to do recursively expand.
12:32:12<Peaker>quicksilver: sounds like they might be nice in the sense of having "keyword args"?
12:32:37<Peaker>though propagating them up automatically into random contexts where their names are meaningless is probably a bad idea
12:34:51<Twey>Peaker: There are better ways to get keyword arguments
12:35:02<augustss_>qaz: yes! :)
12:35:08<Twey>Oleg has a nice implementation
12:35:46<fasta>Twey: did you ever use his implementation?
12:37:31<lilac>Peaker: implicit args basically implicitly thread a reader monad through code which uses them
12:38:00<povman>qaz: I don't really understand that. Remember, there is no spoon!
12:38:35<Peaker>are they so much easier to implement than class aliases?
12:38:37<lilac>Peaker: viewing them as syntactic sugar for reader monads certainly helped me...
12:39:11<boegel>ACTION presses send on his large message to haskell-cafe, and wonders what will result from it
12:39:15<lilac>also, they're pretty similar to type class passing, in a vague way
12:39:31<Peaker>lilac: restriction accumulation on the type
12:39:33<lilac>(except more powerful since you can have multiple distinct and distinguishable instances)
12:40:25<fasta>boegel: maximum message size reached ;)
12:40:29<lilac>Peaker: i've failed to extract any semantics from that :-(
12:41:48<Peaker>lilac: composing two types that have restrictions results in a type that has the restrictions of both, but maybe that's not entirely accurate
12:41:51<boegel>fasta: eh?
12:42:06<boegel>fasta: oh
12:42:09<fasta>boegel: :)
12:42:11<boegel>fasta: well, might be close
12:42:23<boegel>fasta: has 9.7KB in attachments, and quite a bit of text
12:42:57<boegel>I hope some will take the time to read it
12:45:15<povman>Can I use cabal to generate and use the *_stub.? files used by FFI?
12:45:40<povman>cabal seems to like C being called from Haskell, but not the other way around :(
13:02:16<kacper_>how to proof reverse = rev ----- rev = aux [] where aux xs [] = xs aux xs (y:ys) = aux (y:xs) ys
13:04:20<lilac>@type let a = length ?foo; b = return 'x' `asTypeOf` ?foo in (let ?foo = mempty in ?foo, let ?foo = mempty in a `seq` ?foo, let ?foo = mempty in b `seq` ?foo, let ?foo = mempty in a `seq` b `seq` ?foo)
13:04:20<EvilTerran>kacper_, well, that depends on the definition of "reverse"
13:04:21<lambdabot>forall a a1 (m :: * -> *). (Monoid (m Char), Monoid a, Monad m) => (a, [a1], m Char, [Char])
13:04:41<lilac>@src reverse
13:04:42<lambdabot>reverse = foldl (flip (:)) []
13:04:46<lilac>kacper_: ^^ that reverse?
13:05:05<EvilTerran>kacper_, unless you mean "how to prove {rev = aux [] where aux xs [] = xs aux xs (y:ys) = aux (y:xs) ys} has the property {rev . rev = id}"?
13:05:25<EvilTerran>or whatever
13:05:36<EvilTerran>(insert other suitable properties as appropriate)
13:05:50<EvilTerran>(and note that one only works for finite lists)
13:08:10<ivanm>EvilTerran: only because if you want to reverse an infinite list, you'll be waiting for quite a while? :p
13:09:10<EvilTerran>ACTION supposes "rev . rev \refinesTo id" might be a better way of writing it
13:09:28<EvilTerran>although you'd probably want some kind of upper bound on the refinement, too
13:11:53<ivanm>with reads, why does it return a list? as a substitute for Maybe?
13:12:37<EvilTerran>ivanm, in case the parse is ambiguous, i believe
13:12:52<ivanm>EvilTerran: so it returns multiple possible parses?
13:13:03<EvilTerran>in theory, it can, yeah
13:13:04<ivanm>> reads "112" :: [(Int,String)]
13:13:05<lambdabot> [(112,"")]
13:13:08<ivanm>hmmm...
13:13:09<EvilTerran>although derived instances will never do that
13:13:12<EvilTerran>AFAIK
13:13:14<ivanm>can you think of an example?
13:13:18<ivanm>@src reads
13:13:18<lambdabot>reads = readsPrec minPrec
13:13:25<ivanm>@src readsPrec
13:13:25<lambdabot>Source not found. Where did you learn to type?
13:13:30<ivanm>@hoogle readsPrec
13:13:30<lambdabot>Prelude readsPrec :: Read a => Int -> ReadS a
13:13:30<lambdabot>Text.Read readsPrec :: Read a => Int -> ReadS a
13:14:00<ivanm>@src minPrec
13:14:00<lambdabot>Source not found. That's something I cannot allow to happen.
13:14:02<EvilTerran>because of the maximum munch meta-rule in the haskell grammar, derived instances will always be unambiguous
13:14:23<ivanm>derived as in "make one up"? or "deriving (Read)" ?
13:14:28<Saizan>but you can use `mplus`
13:14:56<EvilTerran>as in "deriving"
13:14:57<ivanm>Saizan: surely that came about after reads was implemented?
13:15:01<ivanm>EvilTerran: *nod*
13:15:12<ivanm>so it might be for custom types return multiple instances?
13:15:42<Saizan>ivanm: not sure, but i think the idea of using StateT [s] [] a as the simplest type for parsers is quite old
13:15:48<EvilTerran>for hand-written instances, the ambiguty might be useful, i guess.
13:15:58<ivanm>Saizan: *nod*
13:16:30<EvilTerran>?unmtl StateT [s] [] a
13:16:31<lambdabot>[s] -> [(a, [s])]
13:16:42<EvilTerran>?type reads
13:16:43<lambdabot>forall a. (Read a) => String -> [(a, String)]
13:16:51<Peaker>@src ReadS
13:16:52<lambdabot>Source not found. I've seen penguins that can type better than that.
13:16:54<Peaker>@info ReadS
13:16:55<lambdabot>ReadS
13:17:07<ivanm>heh
13:17:11<EvilTerran>@info \is -> "@undo"
13:17:11<lambdabot>\ is -> "@undo"
13:17:23<Peaker>@info sucks
13:17:23<lambdabot>sucks
13:17:24<ivanm>what a remarkably useful plugin...
13:17:37<EvilTerran>@info do x <- foo; y <- bar; return (x,y)
13:17:38<lambdabot>foo >>= \ x -> bar >>= \ y -> return (x, y)
13:17:46<EvilTerran>it's lambdabot's spelling correction at work :)
13:18:25<EvilTerran>,src ''ReadS
13:18:32<lunabot> type ReadS a = String -> [(a, String)]
13:18:51<Peaker>Why '' ?
13:18:53<ivanm>so how is reads any different from applying ReadS?
13:19:05<ivanm>Peaker: that is the required magic voodoo incantation?
13:19:08<ivanm>*shrug*
13:19:17<EvilTerran>Peaker, ' quotes a value-level name, and '' a type-level name
13:19:25<EvilTerran>because that's how TH works
13:19:25<ivanm>EvilTerran: so what is @info turning into? @undo?
13:19:38<EvilTerran>ivanm, yeah, exactly
13:19:40<Peaker>EvilTerran: what do names without either ' or '' refer to?
13:19:49<kacper_>I found http://209.85.229.132/search?q=cache:JueXExHs2gEJ:www.haskell.org/soe/PPTSlides/Ch14.ppt+infinite+lists+haskell+induction&cd=6&hl=pl&ct=clnk&client=opera
13:19:56<EvilTerran>Peaker, er, the usual haskell meaning of the name?
13:20:11<kacper_>at the bootm is way to proof for infinite lists
13:20:18<Peaker>EvilTerran: meaning either value or type depending on context?
13:20:55<EvilTerran>Peaker, map is a function; 'map is its name
13:22:00<ivanm>EvilTerran: is that quoting in the same way lisps quote lists, etc.?
13:22:13<EvilTerran>, [$ty| map |]
13:22:15<lunabot> forall a b . (b -> a) -> [] b -> [] a
13:22:18<EvilTerran>, [$ty| 'map |]
13:22:20<lunabot> Name
13:23:10<EvilTerran>ivanm, it's related, yeah
13:23:16<Peaker>I hate TH syntax
13:23:20<EvilTerran>although it only applies to names, not arbitrary expressions
13:23:33<EvilTerran>ivanm, a closer analogy to (quote ...) would be [|...|] and friends
13:23:53<ivanm>and I (thankfully, methinks) have no idea what they do ;-)
13:24:03<EvilTerran>, [| 1 + 2 |]
13:24:05<lunabot> InfixE (Just (LitE (IntegerL 1))) (VarE +) (Just (LitE (IntegerL 2)))
13:24:16<ivanm>gah!
13:24:34<ivanm>is that expanding it out into it's behind-the-scenes representation?
13:24:50<EvilTerran>well, its TH-datatypes representation
13:24:59<ivanm>I take it the Maybe values are because you might not have values on either side of an operator?
13:25:08<ivanm>> [| (+2) |]
13:25:08<lambdabot> <no location info>: parse error on input `|'
13:25:12<ivanm>heh
13:25:17<ivanm>, [| (+2) |]
13:25:19<lunabot> InfixE Nothing (VarE +) (Just (LitE (IntegerL 2)))
13:25:22<EvilTerran>[|...|] is the syntax tree of (...)
13:25:53<ivanm>*nod*
13:27:02<kacper_>is filter f (xs++ys) = filter f xs ++ filter f ys for infinite lists?
13:27:18<ivanm>I would think so...
13:27:25<ivanm>why wouldn't it be?
13:27:38<kacper_>its only question
13:28:08<mreh>i've just been shown the hamming list in haskell
13:28:26<kacper_>and reverse xs = foldl ( flip(:) ) [] xs ?
13:28:27<ivanm>kacper_: I'm not trying to accuse your or anything
13:28:35<ivanm>@src reverse
13:28:35<lambdabot>reverse = foldl (flip (:)) []
13:28:48<mreh>is the derivation of things such as circular definitions optimised
13:29:02<mreh>i've just answered my own question
13:29:52<Peaker>Will this be a circular structure: map id (cycle "hello") ?
13:30:07<ivanm>Peaker: internally you mean?
13:30:09<mreh>> let reverse xs = foldl (flip (:)) [] xs in reverse [1..10]
13:30:10<Peaker>yeah
13:30:11<lambdabot> [10,9,8,7,6,5,4,3,2,1]
13:30:26<ivanm>AFAIK, cycle doesn't have to return an infinite list, ghc just returns it that way...
13:30:28<mreh>@src reverse
13:30:28<lambdabot>reverse = foldl (flip (:)) []
13:30:38<Peaker>ivanm: O(1) space
13:30:45<ivanm>Peaker: yeah
13:30:47<Peaker>or O(N) (N=cycle length)
13:30:56<mreh>:t flip
13:30:57<lambdabot>forall a b c. (a -> b -> c) -> b -> a -> c
13:30:58<ivanm>s/cycle/list/
13:31:21<ivanm>Peaker: but IIRC, there's no haskellian reason for it to be circular
13:31:36<Peaker>ivanm: I guess I'm asking about ghc specifically
13:31:44<mreh>isn't cycle "hello" also a circular structure?
13:31:49<Peaker>I wonder if there's a good way to retain the nice space properties of cycle for functions of cycle too
13:31:51<ivanm>mreh: it is in ghc
13:32:14<ivanm>Peaker: is asking if map f . cycle also represented internally by ghc as a circular structure
13:32:29<mreh>let cycle x = x : cycle x in cycle "lo"
13:32:35<mreh>> let cycle x = x : cycle x in cycle "lo"
13:32:37<lambdabot> ["lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo"...
13:32:54<Peaker>that's repeat
13:32:58<Peaker>> repeat "lo"
13:33:00<lambdabot> ["lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo","lo"...
13:33:11<mreh>> let cycle x = concat ( x : cycle x in cycle "lo" )
13:33:12<lambdabot> <no location info>: parse error on input `in'
13:33:30<mreh>> let cycle x = concat ( x : cycle "lo" ) in cycle "lo"
13:33:31<lambdabot> Couldn't match expected type `[Char]' against inferred type `Char'
13:33:34<Peaker>> let cycle xs = xs' ; xs' = xs ++ xs' in cycle "lo"
13:33:35<lambdabot> Not in scope: `xs'
13:33:42<Peaker>> let cycle xs = xs' where xs' = xs ++ xs' in cycle "lo"
13:33:44<lambdabot> "lololololololololololololololololololololololololololololololololololololo...
13:33:47<mreh>> let cycle x = concat ( x : cycle x ) in cycle "lo"
13:33:48<lambdabot> Occurs check: cannot construct the infinite type: a = [a]
13:33:48<lambdabot> Expect...
13:33:55<yowgi>@src cycle
13:33:56<lambdabot>cycle [] = undefined
13:33:56<lambdabot>cycle xs = xs' where xs' = xs ++ xs'
13:34:17<mreh>i didnt know there was an undefined keyword
13:34:22<Peaker>@src undefined
13:34:23<lambdabot>undefined = error "Prelude.undefined"
13:34:23<mreh>isn't error used for partial functions?
13:34:27<mreh>:D
13:35:33<mreh>my definition of cycle required an infinite list to be calculated
13:35:38<mreh>it wouldn't terminate
13:35:56<mreh>in fact, it's just plain wrong
13:36:30<mreh>i just did hamming lists, :(, my brane hurt
13:36:44<mreh>does anyone know the definition?
13:37:15<Peaker>mreh: its allowed to not terminate if it can generate some data constructors in finite time
13:37:28<Jedai>mreh: The definition of what ?
13:37:42<mreh>i take it that the circular defintion of the hamming list makes it a linear algorithm
13:38:01<mreh>if it were really recursive, it would take infinite time
13:38:14<yairchu>Jedai: Peaker gave the defintion you can guess the question now :)
13:38:25<Peaker>yairchu: hey!
13:38:59<yairchu>Peaker: Yoyo
13:39:09<Peaker>yairchu: you abandoned bigorilla?
13:39:16<mreh>@src merge
13:39:16<lambdabot>Source not found. I've seen penguins that can type better than that.
13:39:20<mreh>@src mer
13:39:20<lambdabot>Source not found. Where did you learn to type?
13:39:38<yairchu>Peaker: No I use it to sign lolcats
13:39:41<Jedai>@hoogle merge
13:39:41<lambdabot>Distribution.Simple.PackageIndex merge :: Package pkg => PackageIndex pkg -> PackageIndex pkg -> PackageIndex pkg
13:39:41<lambdabot>Text.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError
13:39:41<lambdabot>Text.ParserCombinators.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError
13:39:55<mreh>thanks
13:40:02<Jedai>mreh: If I remember correctly, merge was defined locally anyway
13:40:18<Jedai>mreh: You're talking about Hamming list, no ?
13:40:20<mreh>i'll paste some code in a sec, and you can explain to me how it works
13:40:27<mreh>Jedai: yes
13:41:00<mreh>i'm a little confused about how it works in linear time, but i am under the impression that it does work because it is represented as a circular structure
13:41:36<Jedai>mreh: it works the same way than "fibs = 0 : 1 : zipWith (+) fibs (tail fibs)", and no it's not circular at all
13:41:54<Berengal>The definition is circular...
13:41:59<Berengal>But that's not too unusual
13:42:07<Jedai>mreh: It's lazy
13:42:09<mreh>it doesn't recalculate the whole fibs
13:42:20<mreh>it just uses what it has already worked out in that definition above
13:42:42<Jedai>Berengal: circular in this sense right, but not in the same sense as the result of cycle is circular
13:43:00<Berengal>Jedai: No, indeed not
13:43:02<mreh>is that right? what I have just said?
13:43:24<Jedai>mreh: Right
13:43:51<wli>> let merge3 ~(x:xs) ~(y:ys) ~(z:zs) | x < y && x < z = x : merge3 xs (y:ys) (z:zs) | y < x && y < z = y : merge3 (x:xs) ys (z:zs) | z < x && z < y = z : merge3 (x:xs) (y:ys) zs | x == y && x < z = x : merge3 xs ys (z:zs) | x == z && x < y = x : merge3 xs (y:ys) zs | y == z && y < x = y : merge3 (x:xs) ys zs | otherwise = x : merge3 xs ys zs ; hams = 1 : merge3 (map (2*) hams) (map (3*) hams) (map (5*) hams) in take 10 $ drop 10 hams
13:43:53<mreh>so as it goes about it's evaluation, it saves alot of time
13:43:53<lambdabot> [15,16,18,20,24,25,27,30,32,36]
13:44:31<mreh>wli has got it
13:44:55<mreh>:t merge3
13:44:56<lambdabot>Not in scope: `merge3'
13:45:04<Jedai>mreh: So hams is the same as fibs
13:45:06<mreh>does lambdabot not remember things
13:45:20<wli>@type let merge3 ~(x:xs) ~(y:ys) ~(z:zs) | x < y && x < z = x : merge3 xs (y:ys) (z:zs) | y < x && y < z = y : merge3 (x:xs) ys (z:zs) | z < x && z < y = z : merge3 (x:xs) (y:ys) zs | x == y && x < z = x : merge3 xs ys (z:zs) | x == z && x < y = x : merge3 xs (y:ys) zs | y == z && y < x = y : merge3 (x:xs) ys zs | otherwise = x : merge3 xs ys zs in merge3
13:45:21<lambdabot>forall t. (Ord t) => [t] -> [t] -> [t] -> [t]
13:45:31<mreh>she's clever isnt h
13:45:31<Peaker>I dislike your function, wli :(
13:45:32<mreh>she
13:45:37<Jedai>mreh: merge3 was defined locally, it's not destined to be remembered
13:45:39<wli>Peaker: Why?
13:45:48<mreh>wli: just nest two merges
13:45:54<Peaker>wli: its repetative, there's probably a nicer way
13:45:57<mreh>merge one (merge two three)
13:46:03<Jedai>mreh: You can add a function to lambdabot with @let so that it will remember it
13:46:15<Berengal>mergeMany = foldl merge [] ?
13:46:24<kacper_>> reverse [1..]
13:47:10<kacper_>> reverse [1..]
13:47:15<mreh>what Berengal said
13:47:32<Jedai>kacper_: Could you stop asking impossible thing from lambdabot ?
13:47:42<mreh>haha
13:47:59<mreh>@faq Can Haskell reverse infinite lists?
13:48:06<mreh>she's thinking...
13:48:08<lambdabot>The answer is: Yes! Haskell can do that.
13:48:35<Jedai>mreh: Of course it takes infinite time and infinite memory but still... ^^
13:48:44<kacper_>;)
13:49:33<Berengal>> let merge [] ys = ys; merge xs [] = xs; merge (x:xs) (y:ys) = if x < y then x:merge xs (y:ys) else if x == y then x:merge xs ys else y:merge (x:xs) ys in foldl' merge [] [sort [1,5,4,6,7,4,5,6,7], sort [3,5,6,8,9,54,4,23,4,6,76,4,5,6,6], sort [5,6,3,4,6,78,8,6,4,5,6,6,78]]
13:49:42<lambdabot> [1,3,4,4,4,5,5,6,6,6,6,6,7,7,8,9,23,54,76,78,78]
13:49:59<mreh>if they are equal Berengal, you need to discard one
13:50:10<mreh>it's a speshul merge
13:50:29<Berengal>I thought I did...
13:50:34<mreh>yeah...
13:50:35<mreh>funny
13:50:47<Berengal>Ah,
13:50:56<Berengal>> let merge [] ys = ys; merge xs [] = xs; merge (x:xs) (y:ys) = if x < y then x:merge xs (y:ys) else if x == y then x:merge xs ys else y:merge (x:xs) ys in foldl' merge [] $ map nub [sort [1,5,4,6,7,4,5,6,7], sort [3,5,6,8,9,54,4,23,4,6,76,4,5,6,6], sort [5,6,3,4,6,78,8,6,4,5,6,6,78]]
13:50:58<lambdabot> [1,3,4,5,6,7,8,9,23,54,76,78]
13:51:12<Berengal>merge doesn't handle repeats in the same list well
13:51:28<Berengal>It requires sorted sets
13:51:48<mreh>why foldl'
13:51:53<Berengal>Why not?
13:52:19<ahamay42>To category experts: What is the difference between Haskell arrows and the morphisms of a category with Haskell types as Obejcts?
13:52:42<ahamay42>I always thought it's the same, but now I read it's something else
13:57:09<hellige>ahamay42: you mean haskell functions, or haskell arrows?
13:57:42<mreh>how can a brother make some dough fast with Haskell?
13:58:03<lilac>> let merge xs@(x:xt) ys@(y:yt) = case x `compare` y of { LT -> x:merge xt ys; EQ -> x:merge xt yt; GT -> y:merge xs yt }; merge xs ys = xs ++ ys in foldl' merge [] $ map (nub . sort) [[1,5,4,6,7,4,5,6,7],[3,5,6,8,9,54,4,23,4,6,76,4,5,6,6],[5,6,3,4,6,78,8,6,4,5,6,6,78]]
13:58:04<lambdabot> [1,3,4,5,6,7,8,9,23,54,76,78]
13:58:46<lilac>mreh: start with flour, butter, milk and yeast
13:59:29<mreh>Curry flavoured?
13:59:49<ahamay42>@hellige I mean arrows
13:59:49<lambdabot>Unknown command, try @list
14:00:13<mreh>any haskell game devs on?
14:00:15<Elly>we do not believe in your twitterisms here
14:00:22<mreh>i'm looking to get some experience
14:00:42<hydo>@Elly what's a twitterism?
14:00:42<lambdabot>Unknown command, try @list
14:00:45<hydo>(lawl)
14:01:32<fasta>mreh: you probably have more luck if you ask an actual question.
14:02:10<mreh>doesn anyone need any help on their haskell? :D
14:02:24<hydo>Why is it that you never realize that you aren't going to be funny until -after- you hit enter?
14:02:56<mreh>double negative
14:03:07<hydo>yep
14:03:19<Twey>I don't
14:03:21<Twey>:-P
14:03:28<Berengal>How is that a double negative?
14:03:36<Elly>sometimes double negatives are meaningfully distinct from positives, like in that case :P
14:03:36<Twey>Berengal: Never + aren't
14:03:41<Twey>Yeah
14:03:42<hydo>never ... aren't? or am I really more tired than I thought?
14:03:48<Berengal>Twey: They apply to two different things...
14:03:52<opqdonut>yeah
14:03:53<Twey>There's nothing logically wrong with that
14:03:56<opqdonut>never realize and are not
14:04:02<Twey>ACTION nods.
14:04:03<povman>Elly: non-negative is a prime example
14:04:24<Elly>povman: indeed :)
14:04:35<Elly>(if your definition of "negative" is "not positive or zero")
14:04:37<mreh>but if you un-negate (!) both of the negatives, you get a sentance that means something else
14:04:45<hydo>sentence
14:04:46<hydo>haw haw!
14:04:50<hydo>:)
14:05:17<ahamay42>I just stumbled across http://chris.chris-lotte.net/publications/2006/arrows/arrows.pdf and was wondering why Arrows should be such a complicated thing instead of just Morphisms
14:05:55<mreh>damn
14:05:59<ahamay42>and as I'm using Arrows in my master thesis, the answer is quite important to me :)
14:07:19<opqdonut>what do you mean by "such a complicated thing instead of just Morphism"
14:08:31<mreh>Does not compute
14:10:04<mreh>I can't stand half educated half wits like stephen fry and douglas adams whittering on about apple macs
14:10:08<ahamay42>opqdonut: well, they state "Hughes' arrow" corresponds to to monoids in a suitable subcategory etc."
14:10:54<ahamay42>but I always thought haskell arrows are just corresponding to the morphisms of a category
14:11:08<ahamay42>even it's a special one
14:11:43<Saizan>it's true that the class Arrow doesn't have a very good name
14:12:01<Saizan>it's a bit like taking only the first 100 primes and calling them Primes
14:12:25<quicksilver>they're something like morphisms in a CCC which admits a functor from Hask, aren't they?
14:12:33<quicksilver>(a CC-functor)
14:13:04<ahamay42>quicksilver: I'd agree
14:13:24<lilac>mreh: i think it's unfair to call stephen fry a half educated half wit, just because you disagree with his opinion...
14:13:44<Saizan>you should be able to write curry if that's true, right?
14:14:03<Saizan>and uncurry
14:14:18<povman>@seen Lemmih
14:14:18<lambdabot>Lemmih is in #haskell. I don't know when Lemmih last spoke.
14:14:41<Saizan>but a ~> (b ~> c) -> (a,b) ~> c needs ArrowApply i think
14:14:59<quicksilver>hmm, not CC-functors, then
14:15:04<quicksilver>just C-functors.
14:15:13<quicksilver>that is, they are required to preserve product but not apply
14:15:23<quicksilver>not sure why that particular setup was chosen as the default
14:15:32<ahamay42>so that means they are just the morphisms, but of a somewhat haskell-specific category?
14:16:12<ahamay42>I could live with that, I was just feeling bad to sell something to people as category which isn't, in fact :)
14:16:25<Saizan>each instance of Arrow creates a subcategory of Hask, i guess
14:17:01<Saizan>(and by "i guess" i mean, afaiu CT, which is not that much)
14:17:34<hatds>does every arrow instance have an identity?
14:17:48<hatds>arr id I guess :)
14:17:56<Saizan>where Hask is the category with types as objects and monomorphic functions as morphisms
14:18:57<ahamay42>why do they need to be monomorphic?
14:19:52<hatds>well, polymorphic functions are handled by treating them as natural transformations
14:19:56<ahamay42>hatds: exactly, but you have to give id explicitly when defining an Arrow instance as Arrow is a subclass of Category
14:21:08<ahamay42>ah you mean monomorphic in a sence that it's not polymorphic - I was thinking of injective functions
14:21:35<hatds>heh, no relationship between the two in this case
14:21:56<ahamay42>:)
14:22:51<codebliss>Does anyone see an error in my code? http://haskell.pastebin.com/mf33b59b
14:23:04<codebliss>I have the failed output in the pastebin, it's one I've never seen
14:23:15<hatds>then b -> then [b]
14:23:25<codebliss>Hm?
14:23:41<hatds>codebliss: line 3
14:23:43<ahamay42>-> = replace by
14:23:54<codebliss>I'm expecting the following. clean [1,3,3,5,6,4,6,6,7] = [1,3,5,6,4,6,7]
14:23:57<codebliss>Alright
14:24:10<codebliss>Not nub, just two consecutive
14:24:25<mreh>easy
14:24:26<hatds>if the typechecker complains about constructing an infinite type with lists, then it is probably just a "single element list versus single element" mix up
14:24:30<mreh>oh... hang on
14:24:32<mreh>not easy
14:24:41<codebliss>Ah, alright
14:25:12<TonyTheTiger>hi guys, for one of my exercise tasks it asks us to write a function which combines a list of lists into a single list, concat' :: [[a]] -> [a]
14:25:34<TonyTheTiger>mreh: is that to me?
14:25:46<mreh>nup
14:26:00<mreh>that's an easy one
14:26:03<Berengal>concat' = concat :P
14:26:12<mreh>heehee
14:26:13<Ferdirand>concat' = join
14:26:17<codebliss>I gotta go to class in 5, anyone got any ideas? I'm missing something basic I assume
14:26:21<TonyTheTiger>Berengal: that defies the point of learning to do it myself
14:26:27<Berengal>Ferdirand: join = concat already
14:26:36<mreh>@src concat
14:26:36<lambdabot>concat = foldr (++) []
14:26:40<hatds>boo
14:26:48<ahamay42>I guess you're supposed to write a recursive one
14:26:51<Ferdirand>Berengal: i know :)
14:26:56<codebliss>Points-Free = life
14:26:57<TonyTheTiger>yeah its a recursive task
14:27:06<TonyTheTiger>i tried a few things and its just error galore
14:27:15<ahamay42>then paste your attempts
14:27:29<Saizan>codebliss: use group
14:27:43<Saizan>> group [1,3,3,5,6,4,6,6,7]
14:27:44<lambdabot> [[1],[3,3],[5],[6],[4],[6,6],[7]]
14:27:45<doserj>codebliss, hint: the error is in the "then" branch here: clean (a:b:[]) = if a == b then b else a:b:[]
14:27:54<codebliss>I see, i already hoogled
14:27:55<TonyTheTiger>i tried concat' (x:xs) = concat' x ++ concat' xs but realised thats sooo wrong
14:28:08<mreh>just decompose a fold
14:28:23<mreh>fold is a generalisation of a recursive function application
14:28:29<hatds>the subexpression "concat' x" won't typecheck
14:28:37<Berengal>TonyTheTiger: concat' (x:xs) = x ++ concat' xs works
14:28:39<Ferdirand>but it's almost correct !
14:28:40<TonyTheTiger>ahamay42: Although you can believe im lieying I work in one file which i kept deleting code, trial and error basis
14:29:02<TonyTheTiger>Berengal: I tried that but that gives an error
14:29:08<mreh>trial error gets you nowhere
14:29:24<TonyTheTiger>because x might be a list itself
14:29:26<hatds>trial error is good if you are thinking about your mistakes
14:29:37<Berengal>> let concat' [] = []; concat' (x:xs) = x ++ concat' xs in concat [[1..10],[11..20],[21..30]]
14:29:38<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...
14:29:39<TonyTheTiger>and the idea is to flatten the list from a [[a]] to [a]
14:30:00<TonyTheTiger>what the heck why does that work here
14:30:07<TonyTheTiger>gonna go test that again brb
14:30:18<Berengal>TonyTheTiger: x _is_ a list. You want to prepend it to the result of concating the rest of the list
14:30:30<Berengal>Remember, the input is of type [[a]]
14:30:32<TonyTheTiger>ahh but what if x isnt a list?
14:30:34<TonyTheTiger>then what?
14:30:51<Berengal>x has to be a list, because the input is of type [[a]] :P
14:30:52<hatds>ask yourself what's the type of concat'
14:31:03<hatds>^^ that
14:31:03<ahamay42>the first element of a list of lists is a list :)
14:31:09<Jedai>TonyTheTiger: x is a elem of [[a]], it _has_ to be a list
14:31:16<TonyTheTiger>ooh ok thats where i screwed up
14:31:22<codebliss>let clean xs = map head $ group xs
14:31:26<codebliss>Thanks guys =)
14:31:30<Berengal>Yeah, nested types can get messy at first...
14:31:35<TonyTheTiger>i kept thinking a [[a]] could be [a,[]]
14:31:54<ahamay42>so it was good you stated your guess :)
14:31:56<TonyTheTiger>now it becomes easier
14:32:09<ahamay42>no, every element in a list needs to have the same type
14:32:17<Jedai>TonyTheTiger: Haskell is not Lisp
14:32:22<TonyTheTiger>ok so a list is a "type" then?
14:32:28<Jedai>TonyTheTiger: nor a dynamic language
14:32:32<TonyTheTiger>Jedai: I dont know about lisp :(
14:32:51<ahamay42>"a list of ..." is a type, like list of integers e.g.
14:32:53<Jedai>TonyTheTiger: [Int] is a type
14:32:55<Berengal>TonyTheTiger: A list is a type constructor
14:33:01<Jedai>TonyTheTiger: it's a list of Int
14:33:03<Berengal>That is, [] is a type constructor
14:33:18<Jedai>TonyTheTiger: [[Int]] is also a type, it's a list of lists of Int
14:33:25<Berengal>[] Int, or [Int] (they are the same), are lists of Ints
14:33:41<TonyTheTiger>ok so i cant have.... [[1,2,3],[1,2],5] but can have [[1,2],[3],[4,5]]
14:33:44<Berengal>Note that [] the value is an element of all lists
14:33:56<Berengal>> 3:[]
14:33:57<lambdabot> [3]
14:33:59<Berengal>> [3]:[]
14:34:00<lambdabot> [[3]]
14:34:04<Jedai>TonyTheTiger: Right, the list are homogenous (every element is of the same type)
14:34:20<TonyTheTiger>ok, thanks guys that really cleared that up
14:34:38<TonyTheTiger>i was thinking of various ways to validate if x was a list or a single element
14:34:55<Berengal>> concat [[[1],[2]],[[3],[4]]]
14:34:56<lambdabot> [[1],[2],[3],[4]]
14:35:04<Jedai>TonyTheTiger: That's not to say you can't do heterogenous lists (containing elements of miscellaneous types) in Haskell, but [] is not it
14:35:51<Berengal>> (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) (:[]) 5
14:35:52<lambdabot> Couldn't match expected type `t1
14:35:57<Berengal>:/
14:36:24<ahamay42>I've got another categorial question: Hughes "generalizing monads to arrows" paper introduces a maybe functor - but I don't believe it really is a functor
14:36:27<Jedai>Berengal: forgot the (.)
14:36:44<Berengal>Jedai: Yeah, I sort of noticed...
14:36:54<mreh>desktop gaming is almost history, is there a haskell for web project?
14:37:01<Jedai>ahamay42: Why ?
14:37:11<ahamay42>I mean instead of A -f-> B, you now have A -f-> Maybe B
14:38:07<ahamay42>but when you have B -g-> C as well, then there's no clear mapping for the object B
14:38:13<Jedai>mreh: You mean a "Haskell on Rail" ? There are several, Happstack is probably one of the nicer and most complete (and most Haskellite)
14:38:26<ahamay42>as for f, B is mapped to B again
14:38:39<ahamay42>but for g, B is mapped to Maybe B
14:38:39<adityam>is there a higher order function that captures if (something) then [] else [a complicated list]?
14:38:48<ahamay42>I mean it the other way around
14:39:01<ahamay42>f and g swapped
14:40:12<ahamay42>so to make it a functor, I guess it should be like Maybe A -f-> Maybe B, analogueous to fmap in Haskell's Functor class
14:40:23<Jedai>adityam: guard ?
14:40:37<quicksilver>what are you talking ahamay42 ? :) Insufficient context.
14:40:44<quicksilver>A -> Maybe B is an arrow
14:40:52<quicksilver>it's the kleisli arrow of the maybe monad
14:40:55<quicksilver>is that what you mean?
14:41:19<ahamay42>not necessairy kleisli, but yes
14:41:55<ahamay42>I mean the idea is to have an arrow of type A -> B which in reality maps to an underlying arrow of type A -Y Maybe B
14:42:21<quicksilver>you're still not making sense.
14:42:24<quicksilver>(sorry)
14:42:33<ahamay42>no I am sorry :)
14:42:40<quicksilver>data MyArrow a b = a -> Maybe b
14:42:45<quicksilver>^^ this is, indeed, an arrow
14:42:51<quicksilver>as it would be for any other monad instead of Maybe
14:42:55<adityam>Jedai: guard has a return type m (), I need a return [a] (or m a)
14:43:02<quicksilver>kleisli composition induces and arrow for all monads.
14:43:08<endojelly>hmm, so let me get synthesize in Data.Generics right...
14:43:16<endojelly>why is the following not working:
14:43:20<endojelly>linearizeStmt :: Code -> [Code] -> [Code]
14:43:22<lilac>ahamay42: Maybe is itself a functor. it maps the type X to the type Maybe X, and arrows (functions) X -> Y to arrows Maybe X -> Maybe Y
14:43:33<endojelly>oh wait a minute.
14:43:39<ahamay42>yeah but I'm not interested in Kleisli an Monads, just arrows in general
14:43:40<hatds>adityam: if/then/else
14:43:43<ahamay42>like in Hughes' paper
14:43:52<lilac>ahamay42: like all correct instances of the Functor typeclass, Maybe is a covariant endofunctor on Hask.
14:43:58<Jedai>adityam: guard False >> ['a'..'e']
14:44:02<endojelly>no it doesn't work.
14:44:03<endojelly>so:
14:44:04<Jedai>> guard False >> ['a'..'e']
14:44:04<hatds>adityam: or something like liftM3 if'
14:44:05<lambdabot> ""
14:44:09<endojelly>linearizeStmt :: Code -> [Code] -> [Code]
14:44:12<Jedai>> guard True >> ['a'..'e']
14:44:14<lambdabot> "abcde"
14:44:14<endojelly>linearize code = synthesize [] (++) (mkQ [] linearizeStmt)
14:44:24<endojelly>that's obviously wrong
14:44:26<endojelly>but... hm, why?
14:44:30<endojelly>:t synthesize
14:44:31<lambdabot>forall s t a. (Data a) => s -> (t -> s -> s) -> GenericQ (s -> t) -> a -> t
14:44:34<adityam>hatds: I wan to avoid if then else because the if condition is empty
14:44:51<endojelly>so the third argument should be of type (Data a => a -> s -> t), no?
14:44:56<adityam>Jedai: Thanks
14:44:57<endojelly>s and t are the same for me, both [Code]
14:44:59<hatds>adityam: then a guard is not what you maybe
14:45:05<hatds>adityam: *not what you want
14:45:06<ahamay42>I'm talking about the Arrow class and functors in a categorial sense (not the functor class which is just for functions)
14:45:07<Ferdirand>adityam: filterM perhaps ?
14:45:08<endojelly>so it should have type a -> [Code] -> [Code]
14:45:13<Jedai>hatds: guard works perfectly
14:45:38<endojelly>wouldn't (mkQ [] linearizeStmt) result in a function of type a -> [Code] -> [Code], given a function of type Code -> [Code] -> [Code]?
14:45:42<endojelly>:t mkQ
14:45:43<lambdabot>forall r b a. (Typeable b, Typeable a) => r -> (b -> r) -> a -> r
14:46:28<endojelly>so, for me, that's [Code] -> (Code -> [Code] -> [Code]) -> a -> [Code] -> [Code], no?
14:46:49<lilac>> let f x = guard (x > 1) >> [0..x] in (f 0, f 1, f 2, f 3)
14:46:50<lambdabot> ([],[],[0,1,2],[0,1,2,3])
14:47:05<Jedai>ahamay42: The functor class is not "just for function", it corresponds to a Functor in the CT sense
14:47:06<ahamay42>so to be more precise: My remark is about http://www.cs.chalmers.se/~rjmh/Papers/arrows.pdf page 26
14:47:31<ttmrichter>Are there any GHC porting experts available at the moment?
14:47:46<ahamay42>Jedai, yes it does but still it is limited to inputs od type a -> b instead of (Arrow ar) => ar a b
14:47:55<ahamay42>*of
14:48:34<lilac>ahamay42: the Functor class is for covariant endofunctors on Hask.
14:48:37<Jedai>ahamay42: Ok, in that sense I agree, it's just restricted to a certain category (Hask) where arrows are functions
14:48:47<ahamay42>yes
14:48:48<lilac>the arrows of Hask are functions, so in that sense you're right :)
14:49:41<ahamay42>I was just wondering about Hughes' introducing his MaybeFunctor as (mathematical functor, which doesn't make sense to me
14:50:05<ahamay42>as I don't find a mapping between the two involved categories
14:50:11<lilac>ahamay42: every Functor instance is a (mathematical) functor, but the converse is not true
14:50:55<ahamay42>lilac: yes, I agree, but I'm absolutely not talking about the Functor class, so let's forget about this for now :)
14:51:30<lilac>sounds like i should read the paper in question then :-)
14:51:55<Cale>ahamay42: hmm...
14:51:59<lilac>from which category is Hughes' MaybeFunctor a functor?
14:52:13<ahamay42>I hoped someone here had already read this :)
14:53:36<ahamay42>he doesn't state, but I guess it must be a mapping between the category with a (an Arrow instance) as morphisms and the one with MaybeFunctor a as morphisms
14:53:42<hatds>ahamay42: MaybeFunctor is a functor on Hask
14:53:50<ahamay42>though I'm not sure about the direction
14:53:55<Cale>ahamay42: hmm... well, this is a functor in a number of ways, but not the obvious way you'd expect.
14:54:21<ahamay42>how can it be a functor in Hask if the definition is an generic arrows and not functions?
14:54:54<ahamay42>cale: sounds interesting :)
14:56:07<Cale>If you think of the collection, for all types b and c of arrows a b c as a category under <<< and arr id, then you'd normally expect a functor F to send each object t to an object F t, and an arrow a b c to an arrow a (F b) (F c). But that's not what this does.
14:56:52<ahamay42>yes, I can follow until here :)
14:57:10<endojelly>ooh, I got it.
14:57:52<endojelly>@hoogle a -> [a]
14:57:52<lambdabot>Prelude repeat :: a -> [a]
14:57:53<lambdabot>Data.List repeat :: a -> [a]
14:57:53<lambdabot>Prelude iterate :: (a -> a) -> a -> [a]
14:58:07<endojelly>come on, there's got to be a singleton function for lists
14:58:13<Cale>(:[])
14:58:21<doserj>or return
14:58:24<quicksilver>fear the monkey.
14:58:30<endojelly>Cale, yes I know that one but that's not nice
14:58:32<endojelly>doserj, oooh.
14:58:35<endojelly>of course
14:58:40<Cale>endojelly: What's not nice about it?
14:58:43<Jedai>endojelly: You have pure too
14:58:44<quicksilver>how can you say the monkey isn't nice?
14:58:50<quicksilver>That's a pretty dangerous comment.
14:58:59<Jedai>> pure 5 :: [Int]
14:59:00<lambdabot> Ambiguous occurrence `pure'
14:59:00<lambdabot> It could refer to either `Control.Appl...
14:59:04<quicksilver>(:[ {- I've seen it eat young children whole -} ])
14:59:15<Jedai>> Control.Applicative.pure 5 :: [Int]
14:59:16<lambdabot> [5]
14:59:26<endojelly>Cale, because just "singleton" would be nicer, instead of combining two constructors
14:59:29<Cale>There is at least one sense in which it is a functor: if c is any type, MaybeFunctor a b can be applied to it, and if f: c -> c' is any function, then we get a corresponding function MaybeFunctor a b c -> MaybeFunctor a b c'
14:59:59<Cale>endojelly: "singleton" is way more typing for less clarity about what it does ;)
15:01:20<doserj>I bet there is a singleton::Collection c e => e -> c e somewhere
15:01:26<ahamay42>Cale: that sounds reasonable - but do you think this is what Hughes meant when he called if fucntor instead of say arrow transformer?
15:01:35<Cale>ahamay42: I don't think so.
15:01:44<hellige>is there an easy way to build profiling-supporting libraries without rebuilding all of ghc?
15:02:06<Cale>ahamay42: oh, wait, I see
15:02:15<hellige>i need ghc6-prof for 6.10.1 on ubuntu, and there's no package for it. :(
15:02:21<Cale>ahamay42: It's a functor, but not an endofunctor.
15:02:44<Jedai>hellige: If you build GHC yourselve and didn't build profiling... I don't think so. On the other hand, the binary package comes with profiled libraries
15:02:50<ahamay42>between which categories?
15:03:09<Cale>ahamay42: It goes from the category Hask to the Kleisli category for Maybe
15:03:27<Cale>well...
15:03:29<hellige>Jedai: no, it doesn't... not on ubuntu... :(
15:03:45<ahamay42>okay, so you're still with the same functor
15:03:47<hellige>Jedai: someone build a 6.10.1 binary package, but the profiling support is separate.
15:04:04<Cale>The subcategory of Hask constructed by Hughes arrows a to ...
15:04:04<hellige>and no one built it yet, i guess. so if i want a binary package with profiling, i have to go back to 6.8.2. :(
15:04:19<ahamay42>maybe I should email him and ask whether this is what he meant :)
15:04:22<Jedai>hellige: I use the binary package from GHC webpage myself
15:04:42<hellige>Jedai: ah, yeah, forgot they had one. i'll give that a shot, maybe. thanks for the reminder.
15:05:00<Jedai>hellige: it contains profiled version of the libraries IIRC
15:05:22<Cale>Okay, I think I can formalise this in a way which probably agrees with him.
15:05:31<Jedai>hellige: Don't forget to configure your cabal to gets profiled version of the package you install with it
15:06:15<hellige>Jedai: yeah, i know i'll have to rebuild some cabal stuff. but that won't take too long.
15:06:18<hellige>Jedai: thanks!
15:06:34<Cale>Fix the Hughes arrow a, and let Hask_a be the category whose objects are the objects of Hask, and whose arrows f: b -> c are the values of type a b c, with composition <<<
15:08:46<Cale>Let Hask_a^Maybe be the category whose objects are the objects of Hask_a (which are the objects of Hask), and whose arrows f: b -> c are the arrows in Hask_a, f: b -> Maybe c, but then these are the values of type a b c in Hask
15:08:54<Cale>er
15:09:02<Cale>values of type a b (Maybe c) rather
15:09:16<ahamay42>Cale: sorry, I've got to leave now - are you still with c->c' to MaybeFunctor a b c -> MaybeFunctor a b c' ? Or some new start and target categories?
15:09:24<Cale>ahamay42: New ones
15:09:41<Cale>Then MaybeFunctor a is a functor Hask_a -> Hask_a^Maybe
15:09:58<ahamay42>yeah, but I don't believe it really is a functor
15:10:05<Cale>We can check :)
15:10:09<ahamay42>maybe we can finish this diskussion another time
15:10:33<ahamay42>or mail me to bsteuber@gmail.com - this would be great :)
15:10:37<Cale>liftMaybe is the actual functor
15:10:44<ahamay42>hm ok
15:11:22<Cale>MaybeFunctor implements the type level machinery for it, and liftMaybe actually transforms the arrows as needed
15:12:16<Cale>In any event, this is more or less just the Kleisli category embedding. Maybe is also a monad on the category Hask_a
15:13:15<ahamay42>ok thanks for your help - I'll think it over
15:13:39<ahamay42>I'll go now - bye
15:15:58<Cale>Amazing the amount of discussion that 3 lines of code can generate ;)
15:17:40<endojelly>I don't think I really "get" synthesize yet %)
15:18:08<endojelly>"2nd argument o is for reduction of results from subterms"
15:21:34<Cale>Which synthesize?
15:21:52<endojelly>Data.Generics.Synthesize
15:21:57<Cale>Sounds like something from Generic... yes
15:24:17<Cale>hmm
15:24:21<Cale>synthesize z o f x = f x (foldr o z (gmapQ (synthesize z o f) x))
15:25:32<Cale>or...
15:25:45<qaz_>to delete from a BST do you really need 9 cases or should 3be enough?
15:26:21<Cale>qaz_: What does your BST type look like?
15:28:04<endojelly>nevermind. apparently, I want "everything" instead of "synthesize" anyway.
15:28:19<qaz_>Cale: data BinarySearchTree a =
15:28:19<qaz_> Leaf | Node a (BinarySearchTree a) (BinarySearchTree a)
15:28:19<qaz_> deriving(Show)
15:28:34<Tobsan>qaz_: three cases should be enough
15:28:53<Cale>I can't imagine what the 9 cases would even be ;)
15:29:00<qaz_>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4992#a4992
15:29:03<qaz_>^^ those
15:31:10<Tobsan>meh
15:31:13<qaz_>10 caes actually
15:31:17<Tobsan>oh
15:32:17<Cale>Let me give it a shot.
15:33:12<gnuvince_>@src ((->) a) mappend
15:33:12<lambdabot>Source not found.
15:33:16<gnuvince_>@src mappend ((->) a)
15:33:16<lambdabot>Source not found. That's something I cannot allow to happen.
15:33:24<gnuvince_>gah, I never can do this right
15:33:52<quicksilver>it's not a monoid, anyway.
15:34:01<quicksilver>it has the wrong kind - it still has a parameter.
15:34:07<quicksilver>Monoids have to have no parameter.
15:34:36<quicksilver>you could write a Monoid instance for Monoid m => Monoid (a -> m) but I don't think that's in the libs anywhere.
15:34:43<MyCatVerbs>I need a better model of GHC's type system. Some of the things it lets me get away with are just heinous, and yet at the same time relatively innocuous looking stuff fails. :)
15:35:02<endojelly>:t runWriter
15:35:03<lambdabot>forall w a. Writer w a -> (a, w)
15:35:48<gnuvince_>quicksilver: I'm trying to wrap my head around Monoids over functions, but I'm not sure I understand the intuition behind them
15:35:57<gnuvince_>> (1:) `mappend` (2:) $ [3]
15:35:59<lambdabot> [1,3,2,3]
15:36:26<quicksilver>that must be the instance I'm talking about
15:36:39<quicksilver>(f `mappend` g) x = f x `mappend` g x
15:36:42<quicksilver>pointwise mappend
15:36:46<Cale>qaz_: Well, in the interests of not keeping you too long, let's start here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4992#a4993
15:36:47<Xen0x>If you have defined a monad "QMonad a = ReaderT (Int) IO a" could you get the value out of the monad, just like using unsafePerforIO?
15:36:49<quicksilver>I'm pretty sure that's not in the standard libs though
15:37:00<quicksilver>must be a lambdabot extension
15:37:06<Cale>qaz_: Of course, the EQ case is going to be the most interesting.
15:37:11<dschoepe>gnuvince_: mappend for functions is composition
15:37:23<doserj>quicksilver: it is defined in Data.Monoid
15:37:27<jmcarthur>> (1:) . (2:) $ [3]
15:37:29<lambdabot> [1,2,3]
15:37:35<jmcarthur>^^ is different from the above
15:37:36<qaz_>hmm yea i must be able to simplify that
15:37:45<vixey>Xen0x, It would not be anything like unsafePerformIO
15:37:57<MyCatVerbs>:t runReaderT
15:37:59<lambdabot>forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
15:38:10<MyCatVerbs>Xen0x: you can get from the ReaderT Int (IO a) to (IO a) with runReaderT.
15:38:19<Cale>qaz_: Now, the trouble just becomes selection of a new root and an element to delete from either the left or right subtree.
15:38:24<MyCatVerbs>Xen0x: from there, you could use unsafePerformIO, but actually you probably don't want to.
15:38:41<dons>this needs help from a haskell person, http://stackoverflow.com/questions/876948/higher-kinded-generics-in-java
15:38:46<MyCatVerbs>Er, should not have put parens around the first (IO a) there.
15:38:54<MyCatVerbs>dons: oh DEAR me.
15:39:00<Xen0x>but with runReaderT, you don't lose the value carried around within the monad?
15:39:25<dons>quicksilver, Cale you guys should comment :)
15:40:06<MyCatVerbs>Xen0x: no? You have to *supply* that value in order to use runReaderT, so the value will still be in scope somewhere where you can use it.
15:40:09<Cale>qaz_: There are three cases, but they chain nicely. Either we find an element in the left subtree, delete it from there, and make that our new root, or we find an element in the right subtree, delete it from there, and make that our new root, or we fail to find an element in either, in which case we're left with a Leaf
15:40:54<Cale>qaz_: Maybe has useful functions for chaining things together in this way.
15:41:07<TonyTheTiger>how can i take a list and return the list but split into 2?
15:41:43<jmcarthur>:t \(x:xs) -> (x,xs) -- cheating
15:41:44<lambdabot>forall t. [t] -> (t, [t])
15:41:45<Xen0x>MyCats; maybe I don't understand, but how can I use the runReaderT then, to get the IO a?. Just use runReaderT monad?
15:41:58<jmcarthur>:t \(x:xs) -> ([x],xs) -- slightly more correct cheating
15:41:59<lambdabot>forall t. [t] -> ([t], [t])
15:41:59<Xen0x>where monad is of type; ;QMonad a
15:42:03<MyCatVerbs>Xen0x: runReaderT environment monad
15:42:04<mmorrow>splitAt, span, break
15:42:19<TonyTheTiger>how can i take a list and return the list but split into 2??
15:42:20<mmorrow>@type splitAt 1
15:42:21<lambdabot>forall a. [a] -> ([a], [a])
15:42:37<MyCatVerbs>Xen0x: e.g. you have type QMonad a = ReaderT Int IO a.
15:42:38<jmcarthur>TonyTheTiger, mmorrow is helping you
15:42:46<jmcarthur>i was pretending to
15:42:54<TonyTheTiger>jmcarthur: yeah i just realised, gonna go test.
15:42:55<TonyTheTiger>sorry
15:43:07<mmorrow>TonyTheTiger: how do you want to determine _where_ to split it?
15:43:17<MyCatVerbs>Xen0x: when you make use of that, the types will work out like: (runReaderT (foo :: Int) (monad :: QMonad a)) :: IO a
15:43:20<TonyTheTiger>mmorrow: has to be in the middle
15:43:33<MyCatVerbs>(Unless I made a mistake, which happens ~_^)
15:43:37<TonyTheTiger>mmorrow: so it can only be on lists of equal length
15:43:37<mmorrow>ah, \xs -> splitAt (length xs `div` 2) xs
15:43:41<mmorrow>or something then
15:44:00<TonyTheTiger>what would happen if a list that wasnt even is input?
15:44:07<TonyTheTiger>if using an if case appropriate?
15:44:09<mmorrow>, 5 `div` 2
15:44:11<lunabot> 2
15:44:31<MyCatVerbs>TonyTheTiger: with mmorrow's solution there, if you give an odd-length input then the second list will be one element longer than the first list.
15:45:08<mmorrow>jmcarthur: did you ever attempt a gcc compile of a /dict/words switch trie?
15:45:16<Xen0x>MyCatVerbs; I get the picture now. I was only thinking about the passing around of the carried value, but when I use runReaderT I probably don't want that value to be in the Monad (QMonad) anymore, so I don;t need the carried values anymore
15:45:21<qaz_>Cale: the problem is the base case
15:45:23<qaz_>s
15:45:26<TonyTheTiger>MyCatVerbs: yeah im not allowed that, but methinks an if can fix it, but not sure if thats the "correct" way
15:45:30<jmcarthur>mmorrow, no i never got a chance this weekend
15:45:36<jmcarthur>mmorrow, i still plan to
15:45:45<TonyTheTiger>but thanks i didnt know of the split At functions
15:46:23<mmorrow>jmcarthur: cool, i'm gonna try to remember to leave it running next time i'm away from the computer too
15:46:28<MyCatVerbs>TonyTheTiger: well, where *do* you want the odd element to go if the list's length isn't even?
15:46:54<Cale>qaz_: I think it helps to have a function findDeleteMin :: BST a -> Maybe (a,BST a), and similar for max
15:46:58<TonyTheTiger>MyCatVerbs: its an exam question that im practicing, so that doesnt really matter
15:47:47<MyCatVerbs>TonyTheTiger: if it doesn't specify what to do with lists of odd lengths then your exam question doesn't contain enough information to determine the solution. :P
15:48:22<Peaker>in which case you can write all the solutions!
15:48:24<TonyTheTiger>MyCatVerbs: yeah i wouldnt be surprised. The questions I keep seeing everyone round here keeps saying how they are "bad" questions :(
15:48:34<tetha>I vote to read two lists from the user and return those if the input length is odd
15:48:47<tetha>I once did something like that and hilarious things happened later on
15:49:06<roconnor>@src ReaderT
15:49:07<lambdabot>Source not found. Where did you learn to type?
15:49:10<jmcarthur>TonyTheTiger, i would solve it for even lists and write your assumptions about what the question really wants
15:49:22<roconnor>@unmtl ReaderT r m a
15:49:22<lambdabot>r -> m a
15:49:29<roconnor>@unmtl Reader r (m a)
15:49:29<lambdabot>r -> m a
15:49:47<jonathanturner>trying to wrap my head around type inference. "let a x = \x -> x + x" works with a 10, but doesn't with a 10.4.
15:49:48<jmcarthur>well, and obviously have it do *something* with odd lengths, but i just mean make sure that there was ambiguity about what the question was asking
15:50:04<mmorrow>,
15:50:05<jmcarthur>> let a x = \x -> x + x in a 10
15:50:05<lunabot> luna: <stdin>: Data.ByteString.hGetLine: end of file
15:50:06<lambdabot> Overlapping instances for Show (a -> a)
15:50:06<lambdabot> arising from a use of `s...
15:50:07<roconnor>@unmtl WriterT w m a
15:50:07<lambdabot>m (a, w)
15:50:08<jmcarthur>> let a x = \x -> x + x in a 10 10
15:50:10<lambdabot> 20
15:50:13<jmcarthur>> let a x = \x -> x + x in a 10 10.4
15:50:14<lambdabot> 20.8
15:50:23<roconnor>@unmtl m (Writer w a)
15:50:23<lambdabot>m (a, w)
15:50:47<mmorrow>@type \xs -> let n = length xs `div` 2 in if even n then [splitAt n xs] else [splitAt n xs, splitAt (n+1) xs]
15:50:49<lambdabot>forall a. [a] -> [([a], [a])]
15:51:04<MyCatVerbs>jonathanturner: if you type "let a = \x -> x + x" at GHCi's prompt, then it'll infer a monomorphic type for a.
15:51:05<jmcarthur>jonathanturner, you must be doing something different than i
15:51:18<jmcarthur>oh, yeah, ghci would do that
15:51:52<MyCatVerbs>jonathanturner: you've run into the monomorphism restriction. GHCi is defaulting to a :: (Integer -> Integer).
15:52:18<MyCatVerbs>If you define it by, let a x = x + x -- instead, then it will infer the correct type, (Num a) => a -> a.
15:52:23<jonathanturner>MyCatVerbs: I thought that might be the case, but "let b = \x -> x ++ x" works with both b [1] and b["bob"]
15:53:02<MyCatVerbs>jonathanturner: that's because b is being inferred as [a] -> [a], and there are no constraints at all on a.
15:53:22<MyCatVerbs>The monomorphism restriction only kicks in when there are typeclass constraints present.
15:53:45<jonathanturner>MyCatVerbs: that makes sense
15:54:02<MyCatVerbs>It's an artifact of a minor worry about efficiency that the Haskell98 committee had about polymorphic types and sharing.
15:54:05<jonathanturner>MyCatVerbs: still very much wrapping my head around this stuff
15:54:18<jonathanturner>MyCatVerbs: is it getting fixed in Haskell'?
15:54:48<MyCatVerbs>jonathanturner: yep. And it'll be turned off by default anyway in GHC 6.12 and up, AFAIK.
15:54:55<Cale>qaz: Oops! Those recursive cases are actually wrong in an obvious way ;)
15:54:59<MyCatVerbs>jonathanturner: long story short, it annoys the people who work on GHC itself too. :)
15:55:03<jonathanturner>MyCatVerbs: cool, not that it's bad or anything, just confusing
15:55:35<Cale>qaz: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4992#a4994
15:56:31<MyCatVerbs>jonathanturner: it *is* bad enough that the people who hack on GHC for fun and profit hate it and want to make it go away. :)
15:57:00<jonathanturner>MyCatVerbs: you said they had monomorphic restrictions because of efficiency concerns? do you know if there is an implementation discussion about that? I'm learning Haskell, but also interested in the implementation side as wel
15:57:47<MyCatVerbs>The wiki page, http://www.haskell.org/haskellwiki/Monomorphism_restriction explains it better than I could.
15:57:49<endojelly>:t runWriter
15:57:50<lambdabot>forall w a. Writer w a -> (a, w)
15:58:18<Cale>jonathanturner: Basically, the concern is that when you have a value like (Num a) => a it is implemented internally by a (non-memoised) function from a Num dictionary to an appropriate value of the right type.
15:58:28<Cale>jonathanturner: That is, as a function Num a -> a
15:58:55<Cale>jonathanturner: So, things which look like constants can actually end up being functions, and being recomputed each time they are used.
15:59:46<Saizan>(the haskell report actually explains it best, imo)
15:59:59<MyCatVerbs>Except that it never actually comes up in practice any more. For starters, the optimiser's gotten cleverer. For seconds, it never came up that often anyway.
16:00:05<Cale>jonathanturner: The MR is just a terrible solution to this problem. It says that if you have a pattern binding (something which looks like a constant definition), it can't be typeclass polymorphic unless it has an explicit type signature.
16:00:59<Cale>So basically, what should have been a warning at best, is now an error.
16:02:00<Cale>I think it's safe to say, given the last 10 years or so of everyone having to deal with it, that it's a flaw in the standard.
16:02:02<MyCatVerbs>Haskell lets me make up type-level lists. oO
16:02:26<Peaker>I think the concept of compiler warnings is a bad/silly one. If you don't want to fix it -- you can't just leave it there as noise -- you'll miss the warnings you do want to fix. So it might as well be an "overridable error" that you can override with some pragma or such
16:02:53<MyCatVerbs>Peaker: oh hey, that gets subsumed by LANGUAGE pragmas.
16:02:55<Cale>MyCatVerbs: That comment earlier about Haskell's type system letting you get away with things you expected not to, what was that about?
16:03:05<MyCatVerbs>Cale: that. ^^
16:03:08<jonathanturner>Peaker: that's not a bad idea, but it would slow new programmers down considerably
16:03:15<Cale>MyCatVerbs: Type level lists?
16:03:16<Peaker>MyCatVerbs: I'd rather these overrides were on a per-case basis, rather than a per-error-type basis
16:03:33<Saizan>you can already override MR by giving a type signature
16:03:37<MyCatVerbs>Peaker: to some extent, we already do this with things like -XOverlappingInstances.
16:03:42<Cale>Peaker: But it should never prevent a program from compiling.
16:03:56<Saizan>but still, it's awful to have to explain such a quirk to beginners
16:04:01<hatds>I think Peaker is talking about the notion of compiler warnings in general
16:04:10<Cale>We shouldn't prevent programs from compiling over minor potential performance problems.
16:04:11<MyCatVerbs>Overlapping instances are an error in H98, but asking for -XOverlappingInstances turns the check off.
16:04:20<Peaker>Cale: I think it should -- because mtime-based checking means that you're going to accidentally ignore all warnings if it did compile
16:04:33<Cale>mtime?
16:04:42<Peaker>Cale: its not preventing compilation, its just delaying it/requiring that you add an override
16:04:47<roconnor>Saizan: I believe that there are some obtuse cases were you cannot simply add a type signature.
16:04:52<MyCatVerbs>So there's no reason you couldn't stick lots of extra warnings in as LANGUAGE features. :)
16:05:08<Cale>Peaker: Well, in that case, we should remove it altogether.
16:05:10<Peaker>Cale: modification times on files is the common system that is unfortunately used to determine whether to recompile -- and any warnings that were issued before are not re-issued
16:05:11<roconnor>Saizan: thing of the MR applied in a where clause to something that contains type variables from the main function.
16:05:14<roconnor>think
16:05:21<Cale>Peaker: huh?
16:05:24<Cale>Peaker: Since when?
16:05:42<Cale>Peaker: I expect my compiler to report the exact same thing when given the same inputs.
16:05:45<MyCatVerbs>Cale: if I have F.hs and G.hs, compile both, F emits warnings.
16:06:00<Cale>Does GHC actually do that?
16:06:05<MyCatVerbs>Cale: and then modify G and recompile, where G depends on F... I won't get the warnings from F repeated to me.
16:06:13<endojelly>:t everywhere'
16:06:14<lambdabot>forall a. (Data a) => (forall a1. (Data a1) => a1 -> a1) -> a -> a
16:06:16<endojelly>:t everywhereM'
16:06:17<lambdabot>Not in scope: `everywhereM''
16:06:18<endojelly>:t everywhereM
16:06:19<lambdabot>forall (m :: * -> *) a. (Monad m, Data a) => GenericM m -> a -> m a
16:06:24<Cale>MyCatVerbs: Oh, because F is already compiled, sure.
16:06:30<hatds>MyCatVerbs: well, that's what separate compilation should do, no?
16:06:51<MyCatVerbs>hatds: well, I assume it ought to, but then I've never actually tried the alternative.
16:06:54<Cale>If there's an F.o and F.hs doesn't need to be compiled, then of course you won't see the warnings again.
16:07:02<Peaker>Cale: the prevalent build systems in use do not re-report warnings, which is another reason to not create the final output if there are warnings
16:07:13<Cale>Peaker: You mean cabal?
16:07:15<Peaker>Cale: its too easy to miss warnings by accident
16:07:18<Cale>Peaker: or GHC?
16:07:20<Peaker>Cale: cabal, ghc, make
16:07:25<Cale>Interesting.
16:07:39<endojelly>:t gmapT
16:07:39<MyCatVerbs>Peaker: no it isn't? Cabal's normal compilation output is *really* terse, one line per file.
16:07:40<lambdabot>forall a. (Data a) => (forall b. (Data b) => b -> b) -> a -> a
16:07:41<endojelly>:t gmapM
16:07:42<lambdabot>forall (m :: * -> *) a. (Monad m, Data a) => (forall a1. (Data a1) => a1 -> m a1) -> a -> m a
16:07:49<MyCatVerbs>Peaker: source warnings show up like glowy beacons in the middle of it.
16:07:50<Cale>I'm going to have to try this.
16:07:52<quicksilver>I don't find it easy to miss warnings by accident.
16:08:00<Peaker>MyCatVerbs: but then when you recompile, you don't get the warnings again
16:08:03<Saizan>roconnor: with the constraint on some other variable, yeah, but it's not so common i'd think
16:08:06<Cale>Somehow I can't believe that it would be the case.
16:08:37<Peaker>quicksilver: I just saw some mention of accidentally ignored warnings on Haskell blogs -- and it has bitten me before too
16:08:45<Peaker>quicksilver: its another thing I have to keep in mind when compiling
16:08:51<MyCatVerbs>Peaker: The only time you do seperate recompilation is when you're modifying the package yourself. Otherwise you're building the whole thing from scratch from Hackage, most likely.
16:09:04<Peaker>MyCatVerbs: right, and warnings are less interesting in that scenario
16:09:08<MyCatVerbs>Peaker: and if you're working on it yourself, then you just turn -Werror on if you care about warnings.
16:09:16<roconnor>Saizan: and it also cuts both ways. You cannot monomorphically restrict with the MR off by adding a signature. ... I guess the real problem is not being able to give signatures to any subexpression.
16:09:21<Cale>Peaker: It's a lie. GHC reports warnings every time a module is compiled.
16:09:22<Peaker>MyCatVerbs: Right, I suggest -Werror as a default
16:09:25<MyCatVerbs>(And runhaskell Setup clean, too.)
16:09:31<Peaker>Cale: but it doesn't recompile if a final output was produced
16:09:46<Saizan>roconnor: there's always `asTypeOf`
16:09:56<Peaker>Cale: if you were fixing some errors you got from a compilation, and then re-issue a recompile expecting to fix the remaining errors, you're going to ignore the warnings that you didn't fix
16:10:02<Peaker>Cale: (in files that had only warnings)
16:10:14<MyCatVerbs>Peaker: that won't help much. It'll break a whole pile of existing code for exceedingly little benefit. It's not like you can't put Werror in the .cabal file yourself, so having it not be the default doesn't prevent you from doing anything.
16:10:25<Cale>You'll get all the warnings for the module you just modified.
16:10:42<Peaker>MyCatVerbs: It might not be the best thing to do now, but I think it would be far better if it was that way in the first place
16:10:56<Cale>There's an easy solution though. rm *.o
16:10:59<Peaker>Cale: right, and you'll accidentally ignore all the warnings in modules that "successfully" compiled
16:11:05<Peaker>Cale: indeed, and -Werror too
16:11:11<MyCatVerbs>Peaker: and I do hope we can skip the "but undisciplined programmers will just ignore warnings", because IMHO undisciplined programmers will write crap code anyway no matter how fussy you make the compiler.
16:11:16<Peaker>Cale: IMO it should be a default
16:11:23<Cale>Peaker: But the warnings are not that important anyway
16:11:31<roconnor>Saizan: that requires writing an expression with the same type as thing thing you are trying to type, which can be diffcult, and I'm not convinced it is always possible. But it is probably always possible.
16:11:41<Cale>Actually, I never use -Wall
16:11:56<Peaker>Cale: Non-exhaustive pattern matches are a horrible thing to catch at runtime, IMO
16:12:15<Cale>Well, sure, but they're something I essentially just never write.
16:12:16<hatds>sometimes your function is supposed to be partial :)
16:12:22<Peaker>Cale: Fixing warnings costs nearly nothing, not fixing them has a non-negligent chance of being an actual bug
16:12:52<Peaker>Cale: If you're careful enough, of course you don't need the warnings. -Wall frees you from having to be careful about several things
16:13:11<quicksilver>-Wall gives warnings about various kinds of perfectly valid code
16:13:13<Saizan>roconnor: it's generally easy if you define an appropriately typed function using undefined as body
16:13:15<quicksilver>I do not find it useful.
16:13:17<Cale>I suppose. But quite often I actually don't want to write type signatures on things.
16:13:36<Peaker>quicksilver: type signatures on top-level names are nice, IMO, what else does it have that shows up often?
16:13:37<roconnor>Saizan: ya
16:13:45<quicksilver>-Wall frees you from having valuable free time, but forcing you to spend time fixing things that don't need fixing.
16:13:46<Cale>(In the case that they are noisy and unhelpful)
16:13:59<MyCatVerbs>Cale: I don't know about you, but without at least type declarations, I sometimes forget what entire chunks of code were for. ;)
16:14:10<quicksilver>Peaker: type-level signatures on top-level names, incomplete patterns, I don't remember what else.
16:14:14<Peaker>quicksilver: I think that it is a negligible proportion of the time you spend coding it..
16:14:21<quicksilver>Peaker: I tried it once, thought "This is stupid" and have never used it since.
16:14:23<Peaker>quicksilver: incomplete patterns are never bugs?
16:14:25<Cale>MyCatVerbs: For some types of code they are very useful, for other types of code they are not.
16:14:29<Peaker>quicksilver: (in your code/
16:14:30<quicksilver>Peaker: all kinds of things are bugs.
16:14:38<quicksilver>Peaker: when I write an incomplete pattern, I know what I have done.
16:14:39<Saizan>warning about name shadowing gets annoying most of the time, it should only warn about a really small surrounding scope
16:14:48<quicksilver>it is no more likely to be a bug than any other thing I write.
16:15:38<Peaker>quicksilver: I find it hard to believe that inexhaustive-pattern-matches are no more likely to be bugs than other things
16:15:39<Cale>That's the nice thing about algebraic types, it's really hard to write incomplete pattern matches in the first place.
16:15:44<quicksilver>yeah, the shadowing warning is another unhelpful one.
16:16:03<Peaker>quicksilver: When it is unambiguous (type-wise), sure. When its ambiguous? It's saved me before
16:16:19<hatds>stuff about patterns (overlapping, non-exhaustive) would be more useful to be told about while you are in the text editor
16:16:38<Cale>hatds: I agree.
16:16:40<Peaker>hatds: in a non-textual code editor it would be much easier :)
16:16:54<TonyTheTiger>how can I do the same thing as zip but on a list using list comprehension?
16:16:58<Peaker>Indeed a non-textual code editor would make most of these points completely moot, and you'd get type-inference "on-the-fly"
16:17:04<Cale>The compiler should certainly be able to tell me, on command, when pattern matches are incomplete.
16:17:05<quicksilver>Peaker: almost every haskell program I have ever written has at least one correct inexhaustive pattern
16:17:12<Berengal>TonyTheTiger: Explain
16:17:17<Saizan>it's easy in a textual editor too, see eclipse and the other ides :)
16:17:22<quicksilver>Peaker: adding a warning to all that code would be a misfeature.
16:17:23<Cale>quicksilver: Which wasn't a call to a library function?
16:17:29<MyCatVerbs>Cale: the other nice thing about algebraic types is that it's always possible to detect incomplete pattern matches when you do make 'em. ;)
16:17:33<quicksilver>Cale: some are, some aren't.
16:17:37<Peaker>quicksilver: I dislike that in programs, I try to refactor it into not having the impossible constructors in the first place.. do you have examples?
16:17:39<roconnor>TonyTheTiger: there is an extension called parallel list comprehensions
16:17:46<TonyTheTiger>Berengal: e.g [1,2,3] [4,5,6] becomes [1,4,2,5,3,6]
16:17:53<Peaker>quicksilver: is it really that painful to explicitly handle the _ -> ... case?
16:17:55<Cale>MyCatVerbs: Of course, once you add guards into the mix, things are more complicated
16:17:56<quicksilver>Peaker: suppose you make a pass over an AST which removes variables.
16:17:58<roconnor>> [(x,y) | x <- [1..] | y <- [2,4..10]]
16:17:59<lambdabot> [(1,2),(2,4),(3,6),(4,8),(5,10)]
16:18:15<quicksilver>Peaker: after that you have an AST which never uses the 'Var' constructor.
16:18:21<MyCatVerbs>Cale: you would bring Turing-complete predicates into it, wouldn't you? Feh.
16:18:26<quicksilver>when you operate on that, you don't want ot handly the useless case.
16:18:49<quicksilver>but it's a huge amount of boilerplate to define a fresh data type for that
16:18:54<Peaker>quicksilver: Why not put it under an anything-else -> error "Broken assumptions"?
16:18:58<quicksilver>especially if there are multiple such intermediate steps.
16:19:06<quicksilver>Peaker: because the compiler does that for me, for free!
16:19:09<Saizan>but then you don't get to write amusing errors like "the impossible happened!"
16:19:19<quicksilver>with a _ -> error "inexhaustive patterns"
16:19:20<Berengal>> concatMap (\(a,b) -> [a,b]) . zip $ [1,2,3] [4,5,6]
16:19:20<hatds>lol
16:19:21<lambdabot> Couldn't match expected type `[(t, t)]'
16:19:22<Peaker>quicksilver: its not free -- it costs you missing out on the cases where you did forget
16:19:29<quicksilver>which, IIRC, is actually *better* than an error message I can write
16:19:37<quicksilver>since it contains a function name and even line number?
16:19:40<Berengal>> concatMap (\(a,b) -> [a,b]) . zip [1,2,3] $ [4,5,6]
16:19:41<lambdabot> [1,4,2,5,3,6]
16:19:42<Saizan>yup
16:19:51<Saizan>even the column!
16:19:55<quicksilver>ACTION nods
16:20:00<Peaker>hmm.. there should be an "error" that does that too
16:20:09<hatds>yea, that's what I've been saying
16:20:20<quicksilver>that would certainly help.
16:20:27<Berengal>How come I always get the first expression given to lambdabot wrong when I'm in a public channel?
16:20:32<quicksilver>But I have a labouring suspicion you're solving a non-problem :)
16:20:56<quicksilver>because I honestly can't think of a single case where the non-exhaustive pattern match warning has helped me :)
16:20:59<Peaker>quicksilver: Its not a problem for me most of the time, because I use -Werror -Wall anyhow.. But I do forget to enable them both on new files I compile sometimes
16:21:01<hatds>there is an "assert" function for ghc which will spew out the line number
16:21:02<quicksilver>not even in ML, where it's on by default IIRC.
16:21:09<TonyTheTiger>Berengal: What you wrote is that usin a list comprehension?
16:21:52<Peaker>quicksilver: well, I heard once that "recursion is the assembly of FP" -- and in a sense I think pattern-matching is too. I don't find myself using it all that often. When I did use it more, it did catch bugs
16:21:55<Berengal>TonyTheTiger: No, I don't think it's possible in just a list comprehension...
16:22:28<TonyTheTiger>Berengal: Are you sure? my practice exam asks me to do it using a list comprehension
16:22:48<Cale>Berengal: I don't understand that question...
16:22:59<Cale>Berengal: Oh, I missed the word "wrong"
16:23:44<Jedai>TonyTheTiger: That would be really weird and stupid
16:24:00<Berengal>TonyTheTiger: A list comprehension always constructs single elements of a list. You want to create two and two elements, which means you need to do something else
16:24:10<Cale>huh?
16:24:32<Jedai>TonyTheTiger: I think the best way is probably to use explicit recursion in this case, it's probably the clearest you can do :
16:24:34<Cale>If you're doing a concatMap anyway, you might as well write a list comprehension
16:24:37<quicksilver>Peaker: sure. You use pattern matching for the basic operations which apply to a type, normaly.
16:24:51<endojelly>:t mapAndUnzip
16:24:52<lambdabot>Not in scope: `mapAndUnzip'
16:24:57<endojelly>:t unzipWith
16:24:58<lambdabot>Not in scope: `unzipWith'
16:25:00<Berengal>> [[a,b] | a <- [1,2,3] | b <- [4,5,6]]
16:25:01<lambdabot> [[1,4],[2,5],[3,6]]
16:25:06<Saizan>> [x | (a,b) <- zip [1..3] [4..6], x <- [a,b]]
16:25:07<lambdabot> [1,4,2,5,3,6]
16:25:09<Jedai>interleave (x:xs) (y:ys) = x : y : interleave xs ys
16:25:09<Jedai>interleave _ _ = []
16:25:15<Saizan>not that hard :)
16:25:21<vixey>Saizan very nice
16:25:29<quicksilver>Peaker: then you write more sophisticated claculations in terms of those simple ones.
16:25:40<hatds>matching on a tuple or a product type and binding each component to a variable is not really pattern matching
16:25:42<Cale>Saizan wrote the code I was about to write too :)
16:25:43<Jedai>Saizan: Pretty nice :)
16:25:49<Berengal>Saizan: I keep forgetting that list comprehensions are sugar for the list monad... very nice
16:25:55<roconnor>> tan (10^100) :: CReal
16:25:56<lambdabot> 0.4012319619908143541857543436532949583239
16:25:58<vixey>ACTION didn't figure out what Saizan wrote
16:26:01<hatds>well it is, but it is rare that matching will fail
16:26:02<quicksilver>Peaker: that means you don't pattern match very often, which makes it even more likely you don't make non-exhaustive pattern errors :)
16:26:10<roconnor>> tan (10^100)
16:26:11<lambdabot> -3.302509482989562e-2
16:26:54<ziman>> (sin (10^100) :: Double, sin (10^100) :: CReal)
16:26:56<lambdabot> (3.30071000245921e-2,-0.3723761236612766882620866955531642957197)
16:28:09<Cale>http://www.smbc-comics.com/ -- ahaha
16:28:48<TonyTheTiger>Berengal: turns out this was the answer, I understand it (somewhat) but didnt know haskell could use comprehensions like this
16:28:50<TonyTheTiger>concat [[x,y]|(x,y) <- zip xs ys]
16:29:22<Cale>TonyTheTiger: Well, you can even move the concat inside the comprehension as Saizan showed, by adding another generator
16:29:24<Berengal>TonyTheTiger: That was basically what my concatMap did above. Also, Saizan did it using just a comprehension
16:29:27<Jedai>TonyTheTiger: There is a concat, so it's not exactly a "pure" list comprehension
16:29:38<Cale>[z | (x,y) <- zip xs ys, z <- [x,y]]
16:30:13<TonyTheTiger>ohh sorry must have missed the answers posted above
16:30:21<Berengal>> do (a,b) <- zip [1,2,3] [4,5,6]; x <- [a,b]; return x
16:30:22<lambdabot> [1,4,2,5,3,6]
16:30:30<TonyTheTiger>[z | (x,y) <- zip xs ys, z <- [x,y]] <- this is a "pure" list comprehension then?
16:30:31<Jedai>TonyTheTiger: there is a zip too... I would argue that the question is pretty bad, it should not say that you have to use list comprehension
16:31:33<Jedai>TonyTheTiger: more or less pure, there is a zip inside, but it could be argued that the outermost expression is a list comprehension
16:31:38<Cale>I think it's a good exercise in making use of list comprehensions
16:32:01<ziman>how efficient is concat [[x,y]
16:32:03<Berengal>List comprehensions are good for understanding monads, but not much else
16:32:05<ziman>how efficient is concat [[x,y] | ... ?
16:32:09<Berengal>In my opinion, of course
16:32:14<Cale>ziman: Just as efficient as the other way
16:32:21<lilac>> (\xs ys -> [if n `mod` 2 == 0 then xs !! fromIntegral (n `div` 2) else ys !! fromIntegral (n `div` 2) | n <- [0..min (genericLength xs) (genericLength ys :: Natural) * 2 - 1]]) [1,2,3] [4,5,6]
16:32:22<lambdabot> [1,4,2,5,3,6]
16:32:24<lilac>there we go
16:32:36<Jedai>Cale: Right, but in this case the answer should be entirely formulated in term of list comprehension
16:32:55<ziman>Cale, "the other way" being your [z | ...] or the explicit recursive version?
16:33:10<Jedai>lilac: Wow !! ^^
16:33:30<qaz>how would you handle timeouts in Haskell? like the Erlang runtime has built-in support for handling stuff that takes to long
16:33:32<lilac>> (\xs ys -> [[xs !! fromIntegral (n `div` 2), ys !! fromIntegral (n `div` 2)] !! fromIntegral (n `mod` 2) | n <- [0..min (genericLength xs) (genericLength ys :: Natural) * 2 - 1]]) [1,2,3] [4,5,6]
16:33:33<lambdabot> [1,4,2,5,3,6]
16:33:36<lilac>better :)
16:33:41<ziman>> zipWith id (cycle [const, const id]) [1, 2, 3] [4, 5, 6]
16:33:42<lambdabot> Couldn't match expected type `[t1] -> t'
16:33:48<Jedai>Cale: I think it's probably less efficient than the explicit recursive version, no ? And less clear too
16:34:43<ziman>> (\xs ys -> zipWith id (cycle [uncurry const, uncurry $ const id]) (zip xs ys)) [1,2,3] [4,5,6]
16:34:45<lambdabot> [1,5,3]
16:34:46<Berengal>> zip [1,2,3] [4,5,6] >>= (\(a,b) -> [a,b])
16:34:48<lambdabot> [1,4,2,5,3,6]
16:34:53<ziman>ah. :)
16:35:18<Jedai>> let (x:xs) /\/ (y:ys) = x : y : (xs /\/ ys); _ /\/ _ = [] in [1..4] /\/ [5..8]
16:35:19<lambdabot> [1,5,2,6,3,7,4,8]
16:35:26<lilac>> [0 .. genericLength [0..] :: Natural]
16:35:31<lambdabot> * Exception: stack overflow
16:35:33<lilac>:(
16:35:41<lilac>broken enumFrom for Natural?
16:36:09<roconnor>@src genericLength
16:36:12<lambdabot>genericLength [] = 0
16:36:14<lambdabot>genericLength (_:l) = 1 + genericLength l
16:36:32<lilac>> enumFromTo 0 (fix (1+)) :: [Natural]
16:36:34<lambdabot> * Exception: stack overflow
16:36:44<qaz>hmm the whole Maybe and Monad stuff works a lot neater with a language that has pattenrmatching right?
16:36:47<lilac>> min (fix (1+)) 42 :: Natural
16:36:48<lambdabot> 42
16:36:48<roconnor>lilac: seems like it
16:36:57<qaz>my erlang-Maybe was a lot nicer than my Clojure one
16:37:15<lilac>hmm. that's unfortunate. so my solution is incorrect by extension then ;-(
16:37:43<Jedai>qaz: pzttern matching is nice for a lot of things, though you don't need it to make Maybe nice to use, maybe is enough
16:37:49<Jedai>@type maybe
16:37:52<lambdabot>forall b a. b -> (a -> b) -> Maybe a -> b
16:38:12<lilac>Jedai: "pzttern": pattern match failure
16:38:20<Twey>Hahaha
16:39:13<vixey>> enumFromTo 0 infinity
16:39:14<lambdabot> * Exception: stack overflow
16:39:22<vixey>> enumFrom
16:39:23<lambdabot> Overlapping instances for Show (a -> [a])
16:39:23<lambdabot> arising from a use of ...
16:39:26<vixey>> enumFrom :: [Natural]
16:39:27<lambdabot> Couldn't match expected type `[Natural]'
16:39:32<Jedai>> head (enumFrom 0)
16:39:34<lambdabot> 0
16:39:42<roconnor>lilac: enumFromTo x y = map toEnum [fromEnum x .. fromEnum y]
16:39:42<Jedai>> head (enumFrom 0 :: [Natural])
16:39:43<lambdabot> 0
16:39:50<roconnor>lilac: those defaults really need to be overridden
16:40:16<Jedai>> genericLength (enumFrom 0) :: Natural > 5
16:40:17<lambdabot> Only unit numeric type pattern is valid
16:40:20<roconnor>-- NOTE: these default methods only make sense for types
16:40:22<roconnor>-- that map injectively into Int using fromEnum
16:40:25<Jedai>> (genericLength (enumFrom 0) :: Natural) > 5
16:40:26<lambdabot> True
16:40:30<roconnor>which is not the case for Nat
16:41:09<vixey>qaz: Can't you add pattern matching to clojure?
16:43:07<vixey>> (genericLength (enumFrom 0) :: Natural)
16:43:11<lambdabot> * Exception: stack overflow
16:43:43<Jedai>vixey: This one makes sense
16:43:45<vixey>> let _ + _ = error "stack overflow" in 1 + 1
16:43:46<lambdabot> * Exception: stack overflow
16:44:42<Eelis>the lhs2tex manual doesn't mention coloured syntax highlighting. is this not supported?
16:44:46<qaz>lol dont realize how good monads are until you try a functional language without them :P
16:44:57<roconnor>lilac: source: http://hackage.haskell.org/packages/archive/numbers/2008.4.20.1/doc/html/src/Data-Number-Natural.html
16:45:14<roconnor>lilac: it should be easy to patch.
16:45:42<roconnor>lilac: then you can upload a new version to hackage and Cale can recompile lambdabot.
16:45:50<roconnor>lilac: oh an then tell augustss_ too
16:47:43<Eelis>can hscolour be used with lhs2tex, perhaps?
16:47:55<kyevan>BEEP
16:50:06<malcolmw>Eelis: my guess would be that hscolour and lhs2tex are either/or. But you could try it and see what happens (both ways round)
16:50:44<Eelis>malcolmw: well, i run lhs2tex on literate haskell, so i'm not sure how i could squeeze hscolour in there. but i'll have a look
16:50:52<vixey>http://www.loper-os.org/?p=41
16:51:04<vixey>it says 'can we instead build on the idea that a computer program is a mathematical object that can be understood through logic'
16:51:14<kyevan>ACTION glares at ghc
16:51:24<kyevan>manpages, damnit!
16:52:30<Apocalisp>> length $ tails [1..26] >>= inits
16:52:31<lambdabot> 378
16:56:13<malcolmw>Eelis: looking at the lhs2tex manual, I see that you can substitute different formatting for almost any element, e.g. keyword, conid, pragma
16:56:24<bremner>kyevan: man pages exist, at least on Debian.
16:56:43<malcolmw>Eelis: see Table 3 on page 36, wrt the %subst directive
16:56:47<kyevan>Not here, though... >_>
16:57:20<bremner>complain to your linux distro, unless your linux distro is VMS or Windows or something...
16:57:38<kyevan>Somehow I doubt Apple cares :P
16:57:44<bremner>or you didn't install the distro ghc, which I guess is pretty likely
16:57:54<bremner>ah, VMS with bling :-)
16:58:06<kyevan>Well. I suppose macports is the pokereyd person, not Apple.
16:58:23<roconnor>vixey: I always thought the future of computing was biology, not logic; I will now read lamport's article.
16:58:24<adamvo>ACTION wonders where the Functor ((,) t) instance has gone
16:59:01<vixey>roconnor: well some sya that logic is completely based on biology
16:59:02<MyCatVerbs>adamvo: Control.Monad.Instances.
16:59:12<Eelis>malcolmw: yes, but i'm reluctant to take that route. i also think there's more to syntax highlighting than just replacing keywords. i would also want highlighting for things like literals, punctuation, and different kinds of identifiers (ones that start with a capital, and ones that don't, for example)
16:59:14<kyevan>Also, Debian creates their own manpages if upstream lacks them... :J
16:59:37<adamvo>MyCatVerbs: thanks
16:59:44<bremner>kyevan: sure, but they are always freely usable
16:59:58<malcolmw>Eelis: well, that is exactly the categorisation that lhs2tex (and hscolour) give you
17:00:34<Eelis>malcolmw: oh, i see. interesting
17:00:51<kyevan>Yeah, Debian's manpages are Debian-made :J
17:00:55<roconnor>vixey: but I mean, I expect computer programs will be "grown" using genetic algorithms and in an "environment" of test harnesses that will mould the program into the desired functionality.
17:01:10<MyCatVerbs>roconnor: oi, genetic *programming*. :)
17:01:22<qaz>how would you handle timeouts in Haskell? like the Erlang runtime has built-in support for handling stuff that takes to long
17:01:25<malcolmw>Eelis: oh, actually, now I look closely at the lhs2tex table, it does look more specific - categorisation plus more info, like the first character of a conid (upper-case identifier)
17:01:35<vixey>roconnor, hat sounds cool :) I think it's one of many paradaigms
17:01:37<kyevan>So, my glaring still stands, since the main GHC distribution lacks them, so...
17:01:38<MyCatVerbs>roconnor: GAs are a slightly wider field, including some strictly less powerful things too. :)
17:01:53<Eelis>malcolmw: i'll certainly play around with those, then. thanks!
17:02:01<jmcarthur>qaz, depends what you are timing. pure computation? IO?
17:02:11<jmcarthur>any way you look at it, you need IO to get the times
17:02:18<roconnor>MyCatVerbs: fair
17:02:45<jmcarthur>but if it's pure, it helps to have some abstraction that allows you to pause and resume the computation so you can go to IO to check the time and stuff
17:02:56<malcolmw>Eelis: anyway, the default definitions are in lhs2TeX.fmt, so you could just try adding some colours in there
17:02:58<jmcarthur>or perhaps use threads to do something similar
17:03:24<MyCatVerbs>qaz: there's a Hackage package for things like this (attempting possibly-nonterminating pure computations with timeouts and other such safeties, all in IO of course), but I can't remember what it's called.
17:04:05<MyCatVerbs>qaz: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ChasingBottoms
17:06:48<MyCatVerbs>qaz: I suppose it's overkill for the purposes of just trying to evaluate things with timeouts, but still. It might come in handy to have the extra firepower if you want to go debugging really huge expressions =)
17:09:00<cedricshock>I was looking at a simple http server, and it inspired a question about IO. Let's say I have an interactive process that does something like looking up a reverse DNS request to write to the log. I want to serve the page as fast as possible, but don't want to do the DNS request again to put in the data given to the page handler, which is pure.
17:10:26<cedricshock>How could I accomplish this? forkIO the DNS request (and the log writing) with an STM variable that gets passed into the page handler? Is it impossible for the page handler to be pure and lazy in IO (my guess)?
17:12:50<mmorrow>qaz: System.Timeout
17:13:22<kyevan>Hmm. Has anyone used TextWrangler on the mac with Haskell?
17:13:36<MyCatVerbs>cedricshock: the easy way is to just forkIO the whole (lookupDNS >>= logToDisk) action.
17:13:42<kyevan>I'm trying to get it to let me easily load the current file in ghci >_>
17:14:06<cedricshock>When you bind a in f :: a -> b, does the sequence generating a necessarily get executed. I don't think so, so then the pure f a->b can have some wonderful uglies in its a (which may not be an a yet). Then it would need to be guaranteed that the DNS lookup would succeed eventually or never terminate, which would just mean the type for it would need to be some kind of Maybe.
17:14:40<MyCatVerbs>cedricshock: personally, I'd write one thread permanently listened on a Chan String (or Chan ByteString) and wrote whatever got written to that channel to disk, and then logToDisk s = putChan toDiskLogger s;
17:15:16<cedricshock>MyCatVerbs: Yeah, but can I lazily get the dns lookup out of lookupDNS into the page request info for the handler without waiting on it succeeding so it only waits on handlers that need it?
17:15:19<MyCatVerbs>cedricshock: just do DNS lookup in the IO monad and multithread it. This is not a good place to use lazy IO.
17:16:26<cedricshock>No. I want the DNS lookup to be eager, but share the lookup with the page handler that will only wait for it to be done when it needs it.
17:16:34<MyCatVerbs>cedricshock: you could do let dnsresult = (unsafePerformIO lookupDNS), which would then defer the DNS lookup until it's needed, but I suspect you wouldn't gain anything interesting by doing that.
17:17:32<MyCatVerbs>Ah, right. Hrmn. I suspect that the best answer is to never write page handlers that make use of reverse DNS. (They'll always have crap latency anyway, no matter what the environment or how they're written.)
17:17:46<MyCatVerbs>If you really did want to do that, just memoize lookupDNS.
17:17:59<lysgaard>Anyone have a good example of how to make the (+) function work for my datatype. Trying to make a algebraic math datatype/class?
17:18:11<MyCatVerbs>lysgaard: hpaste what you have so far, please?
17:18:16<MyCatVerbs>@where hpaste
17:18:16<lambdabot>http://hpaste.org/
17:18:54<cedricshock>lysguard: instance (The class plus is defined in) (Your class) where:
17:19:04<mmorrow>cedricshock: um, i don't understand your question. so you want to (do dns <- lookupDNS; send (reponse dns); log dns; return ()) ?
17:19:57<MyCatVerbs>mmorrow: I think he wants to always use lookupDNS in the logging function, and only sometimes use lookupDNS in the page handler; and if it is used in both, then only make one DNS request.
17:20:27<lysgaard>MyCatVerbs: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4997#a4997
17:20:29<mmorrow>it's only ever used once in that pseudo-code
17:20:34<MyCatVerbs>For which the easiest solution is to write a caching version of lookupDNS. But either way, making your pages depend on reverse DNS will suck for performance.
17:20:48<mmorrow>\req -> do dns <- lookupDNS req; send (reponse dns); log dns; return ()
17:21:12<mmorrow>lookupDNS doesn't have to actually do it, it can be an arbitrary function
17:21:36<MyCatVerbs>lysgaard: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4997#a4998
17:23:15<skorpan>what's the haddock syntax for code blocks in comments?
17:23:18<lysgaard>MyCatVerbs: Ah! Of course, thanks :)
17:24:25<doserj>skorpan: http://www.haskell.org/haddock/doc/html/ch03s08.html#id289905
17:24:44<skorpan>thanks!
17:24:44<lysgaard>MyCatVerbs: Coming from the imperative world haskell is so elegant. Totally different way to think
17:24:57<cedricshock>More genrally: I want to share a result of IO() with two functions, without the sequence to generate it necessarily occuring unless one of the two needs it. I still want to restrict the type of the functions it's used in as much as possible so there aren't arbitrary side-effects. In my specific example one of the two threads is always going to use it.
17:25:16<MyCatVerbs>lysgaard: you will most likely end up needing to add Mul, Add, etc, to Algebra, in order to represent things like Variables being added to one another. :)
17:25:53<MyCatVerbs>cedricshock: same way you'd achieve that in imperative-land. (Not a coincidence, since you're working in IO.) Memoize the IO action.
17:26:48<cedricshock>And then it doesn't get done until either thread has output dependent on it. That's too simple and beautiful.
17:26:57<lysgaard>MyCatVerbs: Yeah, i realised that now, how do i proceed?
17:27:14<mmorrow>cedricshock: ok, so if one always needs it, then just generate it once, and pass it to both. if one doesn't need it, it just ignores it.
17:27:34<lysgaard>MyCatVerbs: Eg if i add a number and a variable, will i need a new datatype?
17:27:46<MyCatVerbs>lysgaard: if you're attempting to do what I think you are attempting to do, add a constructor to represent addition, another one to represent multiplication...
17:28:01<MyCatVerbs>lysgaard: no, just more alternative constructors for the Algebra type.
17:28:16<lysgaard>MyCatVerbs: Oh, I'll try it out ;)
17:29:26<mmorrow>cedricshock: or something like: type MaybeINeedIt req res = req -> Either (DNS -> res) res
17:30:04<cedricshock>So something like STM is only ever needed when the method of definition is decided upon in one of the threads, like threads competing to find minimas but sharing their best minimas for heuristics.
17:30:45<mmorrow>cedricshock: i don't see how STM fits in here
17:30:48<Cale>qaz: See also http://www.haskell.org/haskellwiki/Timing_out_computations
17:31:10<kyevan>UGHAREWAREAARAYHWATWER
17:31:17<kyevan>KYEVAN SMASH
17:31:34<kyevan>WHY do all text editors suck so much!?
17:31:35<cedricshock>mmorrow: Yeah, STM is overkill.
17:31:37<Cale>Whaaaat
17:31:45<zachk>kyevan: are you sure you arent Tarzan?
17:31:49<bremner>kyevan: we already had this discussion
17:32:09<kyevan>bremner: It was rhetorical.
17:32:17<kyevan>I'm just expressing frustration, not seeking answers :J
17:32:31<Cale>vim is okay
17:32:36<TomMD>M-c Its because you're used to solutions with more flexibility perhaps? Solutions like MS Pen and Paper? C-x-s
17:32:55<zachk>kyevan: pick vim or bigeemacs
17:33:12<kyevan>Cale: Vim is too cryptic for my tastes...
17:33:23<kyevan>And emacs is moreso :P
17:33:32<zachk>kyevan: try nano then
17:33:37<zachk>or pico
17:33:45<kyevan>Nano doesn't do what I need >_>
17:33:49<TomMD>kyevan: I've used vim for many years and probably don't know more than 5 commands - not a good thing, but it doesn't have to be cryptic if you don't let it.
17:33:50<thomastc>what do you need?
17:34:16<zachk>kyevan: kevin i use vim and i know like 3 commands
17:34:25<kyevan>Well. What I'm currently using is textwrangler, and it works, except there's no way to run a random unix command on the thing.
17:34:34<Apocalisp>vim is not cryptic at all once you get past the idea that edit mode is not the default.
17:34:40<kyevan>zachk: I knoawrgh can I finish my thinkings? >_>
17:34:41<MyCatVerbs>Cale: vim's syntax highlighting sucks, for one thing.
17:34:57<MyCatVerbs>Cale: most of the rest of it is good, though. :)
17:35:11<Cale>It doesn't suck enough to bug me.
17:35:11<Philonous>:t cond
17:35:12<qaz>whats that word for eterniy_machine?
17:35:12<lambdabot>Not in scope: `cond'
17:35:14<kyevan>And having to go to terminal, navigate to the right folder, and run ghci with the right file manually is a pain in the arse
17:35:19<MyCatVerbs>And not many text editors have interestingly better highlighting than vim.
17:35:19<qaz>ah wait, perpetual?
17:35:23<Twey>Apocalisp: Which of course makes perfect sense in an editor.
17:35:36<cedricshock>I think memoizing it would actually do the following: Open the DNS socket, wait for it to open, Send the request, (not try to read it until the letted variable is read)
17:35:45<Cale>kyevan: You should always have a terminal window open with ghci already ;)
17:35:52<roderyk>does anyone have some code/links demonstrating gtk2hs and TreeModel. I have code working based on the gtk demos, but I can't successfully update the Data.Tree stored as my model after the initial init.
17:36:03<MyCatVerbs>Cale: the default mode for Haskell curls up into a ball and cries like a little baby if you nest {- -} comments, and occasionally it ditzes out over pathentheses. Otherwise fine.
17:36:16<kyevan>*sigh* I *do*
17:36:16<TomMD>Good work style: XMonad with 9 desktops and 2-8 terminals open on each desktop.
17:36:28<thomastc>I like kate for these kind of things
17:36:31<Cale>Well, yeah, anything which uses regular expressions to deal with comments will have trouble.
17:36:33<kyevan>But I don't want to mess with that session, to load the other thing...
17:36:42<thomastc>you can get a terminal window right inside your editor
17:36:48<thomastc>it highlights and does regex search
17:36:51<thomastc>and indents
17:37:11<kyevan>thedward: Yeah, but I don't want to install KDE just to use a text editor, and Apple's x11 implementation sucks horribly anyway.
17:37:20<Cale>Haskell's comments can't be matched by regular expressions, because they rely on nesting depth.
17:37:32<Apocalisp>Try yi
17:38:00<kyevan>No.
17:38:10<kyevan>We've been through this before >_>
17:38:24<MyCatVerbs>Cale: and yet it gets parentheses matching (mostly) right. :/
17:38:28<kyevan>I was just expressing frustration, anyway, and I've already said that, so <_<
17:38:37<Apocalisp>Well, maybe write us all a good text editor then.
17:39:02<kyevan>Apocalisp: >_> I'm not talented enough.
17:39:19<TomMD>lyatefgg == Learn you a text editor for great good
17:39:29<Apocalisp>Nobody's talented enough to make a text editor to satisfy everybody.
17:41:00<Berengal>We need a text editor everyone's talented enough to make good enough to satisfy themselves
17:41:17<Berengal>Problem solved
17:41:54<TomMD>What if we overestimate the minimum talent of a potential user?
17:42:20<Philonous>Berengal: You mean like Emacs, but with VBS instead of Lisp?
17:42:23<Berengal>TomMD: We redefine them as users
17:42:29<Berengal>lusers*
17:42:31<Berengal>:/
17:42:54<Berengal>Philonous: No, I mean like Word but with Lisp instead of VBS
17:43:02<Berengal>By which I mean emacs
17:43:29<Berengal>ACTION feels he isn't making much sense
17:45:09<copumpki>:o
17:45:42<endojelly>:t runRWS
17:45:43<lambdabot>forall r w s a. RWS r w s a -> r -> s -> (a, s, w)
17:45:57<opqdonut>:kind RWST
17:46:12<vixey>:k RWST
17:46:13<lambdabot>* -> * -> * -> (* -> *) -> * -> *
17:46:54<User2185>http://www.Marie-gets-Deflowered.com/?id=576098f2
17:47:14<copumpki>uh
17:47:48<lukeo05>Does anyone know any good pieces for learning about proving properties of haskell programs with structural induction?
17:49:05<Twey>lukeo05: I think SICP covers it
17:49:25<Twey>‘The Haskell Road to Logic, Maths, and Programming’ does too
17:50:08<vixey>what does it cover?
17:50:40<Twey>vixey: Inductive proofs
17:50:44<copumpki>ACTION is frustrated at his lack of organization
17:51:02<vixey>Twey, but I mean what does it prove
17:51:03<vixey>?
17:51:21<Twey>Correctness, I suppose. For a certain value of correctness.
17:51:41<lukeo05>Ah, thank you Twey.
17:52:03<vixey>:S
17:52:08<vixey>but like of what
17:54:06<Taejo>why are Haskeller's constantly inventing their own `data Failable a = Success a | Failure b`? What's wrong with Either String (or a type synonym for it)?
17:54:23<pumpkin>Left and Right aren't particularly descriptive
17:54:27<Taejo>*Haskellers
17:54:34<Cale>I like Either
17:54:41<pumpkin>apart from historical prejudice, nothing in "left" makes it inherently less good than "right" :P
17:54:56<pumpkin>I propose data Either a b = Sinister a | Dexter b
17:55:03<Twey>Ooh, I like that
17:55:05<Cale>One good reason I can imagine is that Either has a stupid instance of Monad in mtl
17:55:08<Twey>It has class
17:55:09<Taejo>pumpkin: Right is the right constructor, Left is the wrong one
17:55:22<pumpkin>Taejo: if you need a mnemonic, that might be a bad sign :P
17:55:23<Twey>We need more Latin in our language
17:55:31<Twey>Haskelligata
17:55:34<pumpkin>:P
17:55:43<pumpkin>ACTION is a leftie
17:56:21<Taejo>pumpkin: it's not that I think Either is good... I just resent having to write my own functor instances, versions of fromRight, etc. when the stdlibs have perfectly good ones
17:56:30<pumpkin>yeah, that is annoying
17:56:32<mmorrow>either Right Left
17:56:57<Taejo>mmorrow: if that's what I think it is, then you are evil
17:57:03<Taejo>:t either
17:57:04<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
17:57:06<pumpkin>Taejo: but Either feels more general than error conditions, and having the monad instance make fail = left is ugly
17:57:08<Cale>data Either a b = 下 a | 上 b
17:57:13<mmorrow>Taejo: heh
17:57:23<pumpkin>Cale: is that allowed?
17:57:26<pumpkin>that'd be cute
17:57:38<mmorrow>data Either a b = (:下) a | (:上) b
17:57:48<Cale>yeah, probably needs the :
17:58:05<pumpkin>data Either a b = 陰 a
17:58:22<mmorrow>, isSymbol '陰'
17:58:23<pumpkin>blah, damn enter key :P
17:58:23<Asztal>operator constructors don't have to be binary?
17:58:24<lunabot> False
17:58:26<pumpkin>or 陽 b
17:58:31<mmorrow>, isAlpha '陰'
17:58:33<lunabot> True
17:58:38<mmorrow>, isUpper '陰'
17:58:39<lunabot> False
17:58:42<pumpkin>that's lame
17:58:48<mmorrow>heh
17:58:57<pumpkin>are there any CJK characters that are uppercase?
17:59:13<pumpkin>(CJKV)
17:59:15<Taejo>pumpkin: the CJK "copies" of latin letters?
17:59:26<bd_>uppercase isn't really meaningful for CJK
17:59:27<pumpkin>I guess :)
17:59:34<Cale>I don't think so, but I think katakana ought to be in terms of GHC's rules about constructors.
17:59:47<Taejo>pumpkin: if you include Vietnamese, then every uppercase vietnamese letter :)
18:00:12<pumpkin>lol
18:00:18<pumpkin>by the V, I meant han nom
18:00:20<Cale>, isUpper 'A'
18:00:22<lunabot> True
18:00:31<pumpkin>with the appropriate diacritics on it
18:00:33<bd_>Things are hard to read if you put them in the wrong kind of kana :) It's not really like english where you can change the case of the first letter with no problem...
18:00:53<Cale>bd_: You often see signs where katakana is used for emphasis.
18:01:06<pumpkin>Taejo: http://en.wikipedia.org/wiki/Chữ_Nôm
18:01:25<Taejo>how about making the circled Han characters uppercase?
18:01:33<bd_>Cale: I suppose, but in computing a lot of your terms are going to be katakana /anyway/...
18:01:34<pumpkin>a significant portion of the han-based characters in unicode are from vietnam
18:01:35<Taejo>for the purpose of Haskell identifiers
18:01:56<pumpkin>Taejo: that'd be kind of ugly :/
18:02:04<Cale>bd_: I suppose that is true.
18:02:27<pumpkin>we should sample unicode space and count what percentage of isAlpha characters satisfies isUpper
18:03:02<pumpkin>> length (filter isAlpha [minBound..maxBound] :: [Char])
18:03:04<lambdabot> 90547
18:03:10<pumpkin>> length (filter isUpper [minBound..maxBound] :: [Char])
18:03:11<lambdabot> 1221
18:03:18<pumpkin>prejudice!
18:03:33<bd_>> length (filter (\c -> not isAlpha c && isUpper c) [minBound..maxBound] :: [Char])
18:03:34<lambdabot> Couldn't match expected type `Bool'
18:03:35<Cale>> length (filter isLower [minBound..maxBound] :: [Char])
18:03:37<lambdabot> 1415
18:03:43<bd_>> length (filter (\c -> (not $ isAlpha c) && isUpper c) [minBound..maxBound] :: [Char])
18:03:44<Cale>Most are neither.
18:03:45<lambdabot> 0
18:03:46<mmorrow>> length (filter (c -> isAlpha c && isUpper c) [minBound..maxBound] :: [Char]) {- just checking -}
18:03:47<pumpkin>oh
18:03:47<lambdabot> <no location info>: parse error on input `->'
18:03:51<Asztal>> drop 200 (filter isUpper [minBound..maxBound] :: [Char])
18:03:52<lambdabot> "\538\540\542\544\546\548\550\552\554\556\558\560\562\902\904\905\906\908\9...
18:04:06<mmorrow>> length (filter (\c -> isAlpha c && isUpper c) [minBound..maxBound] :: [Char]) {- just checking -}
18:04:08<lambdabot> 1221
18:04:28<pumpkin>:t isLower
18:04:29<lambdabot>Char -> Bool
18:04:35<pumpkin>aha, that way we can get "neither
18:04:53<pumpkin>> isUpper &&& isLower $ '何'
18:04:54<lambdabot> (False,False)
18:05:04<Cale>> length (filter (\c -> isAlpha c && not (isLower c || isUpper c)) [minBound..maxBound] :: [Char])
18:05:05<lambdabot> 87911
18:05:10<cedricshock>I have reached a new conclusion. Haskell needs an impure, side-effect free type and a single-valued, impure, side-effect free type. These might be Monads, but I think can have fewer laws.
18:05:27<mmorrow>@let isNeither c = not (isUpper c || isLower c)
18:05:28<lambdabot> Defined.
18:05:28<pumpkin>cedricshock: why?
18:05:37<Cale>cedricshock: What do you mean by that? Something like ST?
18:05:46<mmorrow>crap, shoulda included isAlpha in there..
18:05:55<Cale>Maybe an implementation of IVars in ST?
18:06:11<Gracenotes>cedricshock: you might be interested in something called effectful types, which are sort of an annotation on functions indicating their effect. You can also have an Identity effect, meaning pure
18:06:12<bd_>> length (filter (\c -> isAlpha c && isNeither c) [minBound..maxBound] :: [Char])
18:06:14<lambdabot> 87911
18:06:24<pumpkin>I'd like a more à la carte IO
18:06:28<Gracenotes>cedricshock: however, there aren't many languages today with 'em. Monads are Haskell's way.
18:07:01<Gracenotes>and they were mainly intended to *sequence* events in a lazy language, something mere annotations can't do
18:07:47<Apocalisp>Java has monads.
18:07:50<Apocalisp>;)
18:07:55<Gracenotes>another alternative to monads, just to mention them, uniqueness types
18:08:47<vixey>Apocalisp what does that mean
18:08:49<vixey>'has monads'
18:08:51<cedricshock>To separate sensors that necessarily change the outside world to look at it, affectors that execute decisions, and decision making agents that must not, but can use up-to-date outside information
18:09:03<Apocalisp>; is >>= in the Java monad.
18:09:12<pumpkin>cedricshock: an à la carte IO could do that
18:09:21<Gracenotes>Apocalisp: perhaps >> ...
18:10:01<pumpkin>cedricshock: http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf
18:10:04<Gracenotes>cedricshock: hrm. That's a logical separation that doesn't sound like it has much to do with purity.
18:10:57<Gracenotes>and might be difficult to enforce in a type system, although effect types again provide a way to do this. And possibly specific monads.
18:11:05<cedricshock>It doesn't actually need the second, it can be made with a simple let binding of the first.
18:11:09<Apocalisp>int x = 1; x = x + 1; => \f -> return 1 >>= \x -> x + 1 >>= \y -> f x
18:11:19<Apocalisp>something to that effect
18:12:11<lysgaard>MyCatVerbs: Hi, still there? I've made a good bit of progess, but now I want to make a divide function, without rationale numbers: Explenation here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4997#a4999
18:13:30<Gracenotes>Apocalisp: Perhaps.. more like newIORef 1 >>= \x -> modifyIORef x (1+)
18:14:05<Apocalisp>Gracenotes: Why IORef?
18:14:06<lilac>ACTION has fixed the Natural bug
18:14:21<lilac>anyone here who has / can grant me a hackage user account?
18:14:21<Gracenotes>Apocalisp: that's what variables in imperative languages are, aren't they?
18:14:35<cedricshock>pumpkin: That
18:14:38<Apocalisp>Gracenotes: No, int x = 1; x = x + 1; is pure
18:14:40<Gracenotes>x would probably be stored somewhat readily available (a register, possibly?), but still, this is just a behind-the-scenes optimization
18:14:44<cedricshock>'s a great article, thanks.
18:15:01<pumpkin>cedricshock: it moves to something you're describing near the end :)
18:15:11<lilac>roconnor: if you want to upload, the fixed version is here: http://metafoo.co.uk/downloads/numbers-2009.5.18.1.tar.gz
18:15:18<cedricshock>It'
18:15:37<Gracenotes>Apocalisp: declaring an int and modifying it is more than just changing what it's binded to
18:15:44<cedricshock>s going to make a new monad with only some of the state transitions of the IO monad (my guess).
18:15:55<hatds>Apocalisp: what's so bad about just doing that in Haskell and giving x+1 a new name?
18:15:58<afedorov>Is there a standard Haskell datatype for Haskell's AST?
18:15:59<Gracenotes>you're modifying the memory location. But... this can at least be simulated by monads in a pure way
18:16:01<lilac>Gracenotes: that depends on whether it's forced to memory (whether its address is taken, basically), right?
18:16:08<cedricshock>I need to learn not to hit the enter key with shift.
18:16:13<lilac>otherwise it may as well be pure
18:17:00<Gracenotes>lilac: what do you mean?
18:17:08<mmorrow>pumpkin: we can just use (data A; newtype IOA a = IOA (ST A a) to get different IO's
18:17:18<lilac>ACTION notes that we were talking about Java...
18:17:25<mmorrow>no one has done this, but it would work nicely
18:17:47<pumpkin>mmorrow: wouldn't we need to change the type of ST to get that?
18:17:54<mmorrow>pumpkin: no
18:18:06<afedorov>is there an "official" haskell parser in haskell?
18:18:08<Gracenotes>I do like Apocalisp's example much better in terms of readability, and it helps shed light on a simple Java monad would be... not sure if it's entirely accurate :)
18:18:13<Apocalisp>Gracenotes: You're not modifying the int. int is immutable. Nothing wrong with doing that in Haskell.
18:18:29<lilac>Gracenotes: well, consider the program converted to SSA form. at that point, everything except memory reads and writes and calls to externals is pure
18:18:30<pumpkin>mmorrow: how would you say that "this function modifies files AND talks to the network"?
18:18:33<dcoutts_>afedorov: yes, but it's not as good as the unofficial one :-)
18:18:34<mmorrow>pumpkin: (you'd just need to use unsafeCoerce a bunch of places in your implem)
18:18:49<Apocalisp>there was a paper...
18:18:54<mmorrow>pumpkin: you'd do that by only writing functions for IOA that do those things
18:19:08<Apocalisp>http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.1523
18:19:08<afedorov>dcoutts_: here, I'm just looking to see if there's anything like a standard for the Haskell AST
18:19:10<pumpkin>so you'd need an A for each conjunction of "features"?
18:19:10<d3mn0id>Ahh, intelligent lifeforms, run!
18:19:15<afedorov>~hehe
18:19:15<dcoutts_>afedorov: see the packages haskell-src and haskell-src-exts but also the ghc api, which you should choose depends on your application
18:19:21<mmorrow>pumpkin: well, it would probably be simpler to just use:
18:19:22<Baughn>Not to be a bother, but is it currently possible at all to install reactive with cabal-install?
18:19:27<Gracenotes>lilac: yes. memory reads and writes aren't pure though.
18:19:30<Baughn>I'm getting conflicting QuickCheck versions
18:19:43<mmorrow>pumpkin: newtype IOA a = IOA (IO a)
18:19:45<dcoutts_>afedorov: in that case also consider TemplateHaskell, it also has an AST
18:19:49<afedorov>dcoutts_: thanks :)
18:19:57<Gracenotes>ST handles them, but ST is also impossible to implement in plain Haskell
18:20:05<afedorov>dcoutts_: do they all use different AST's?
18:20:10<lilac>Gracenotes: int in Java is unboxed, so an int 'on the stack' is never required to be written to memory. in that sense, all int operations are pure.
18:20:11<FliPPeh>I feel like abusing Haskell :(
18:20:17<mmorrow>pumpkin: but if you want a function like: runIOA :: IOA a -> a, then you'd want to use (ST A a)
18:20:21<pumpkin>FliPPeh: that's fun!
18:20:23<dcoutts_>afedorov: there is no official AST, because there are different language extensions, and how you design the AST depends on what you're actually interested in doing
18:20:25<afedorov>dcoutts_: or, rather, different datatypes to represent it?
18:20:25<FliPPeh>I keep writing functions for commonly used calculations of my homework
18:20:27<pumpkin>mmorrow: hmm
18:20:35<FliPPeh>And use it just to solve my homework!
18:20:37<dcoutts_>afedorov: yes, all 4 are different
18:20:40<mmorrow>pumpkin: and you'd write it like:
18:20:43<afedorov>dcoutts_: eek
18:20:57<afedorov>dcoutts_: sounds good, I'll take a look, thanks for the pointers :)
18:20:59<mmorrow>pumpkin: runIOA (IOA staa) = runST (unsafeCoerce staa)
18:21:02<Gracenotes>lilac: althogh, implementation detail
18:21:15<Apocalisp>Gracenotes: Also, there's nothing stopping you in Java writing an immutable List with fmap and bind, giving you a list monad.
18:21:31<Gracenotes>Apocalisp: of course... why would there be...?
18:21:36<dcoutts_>afedorov: the haskell-src ast covers Haskell 98, the others cover Haskell 98 + many extensions. The ghc ast includes line numbers and documentation comments.
18:21:56<afedorov>dcoutts_: gotcha
18:22:00<Apocalisp>Gracenotes: Just saying... Monads are not just a Haskell thing. They're fundamental to programming.
18:22:15<Gracenotes>lilac: if you want to deal with both primitives and non-, you may find yourself dealing with messy abstractions when implementing via monads
18:22:43<pumpkin>mmorrow: I don't understand how you would mix these things, without having to write a different A each time
18:22:45<Gracenotes>Apocalisp: yeah, just like anamorphisms, catamorphisms, and a thousand other category structures :P
18:23:02<lilac>Apocalisp: there's a big difference between 'you can do monads here' (true of scala, Java and C++) and 'you can usefully and easily do monads here' (true of haskell)
18:23:03<mmorrow>pumpkin: you'd have a different A for every different IO_ monad you want
18:23:20<mmorrow>pumpkin: and that different A is what keeps them separate
18:23:24<pumpkin>yeah
18:23:29<lilac>Apocalisp: where by 'do monads' i mean define and use custom monads
18:23:48<lilac>if you're in the IO monad or similar anyway, then monads as a programming technique lose a lot of value
18:23:56<Gracenotes>I once wrote a monad in Java. Really abused is generics.
18:24:01<Gracenotes>its
18:24:32<mmorrow>pumpkin: hmm, ok a better way to phrase this i think is to ditch the newtype, and just use (ST <my-phantom-type> a) directly
18:25:29<Gracenotes>or effect types >_>
18:25:50<monadic_kid>:t StateT Int IO a
18:25:51<lambdabot>Not in scope: data constructor `Int'
18:25:51<lambdabot>Not in scope: data constructor `IO'
18:26:03<pumpkin>http://okmij.org/ftp/Computation/Subtyping/ (what's up with him mentioning Haskell as a language with "a native or emulated OO system"?)
18:26:03<hatds>is there a way to view source code in ghci?
18:26:14<roconnor>:k StateT Int IO a
18:26:15<lambdabot>Not in scope: type variable `a'
18:26:25<pejo>pumpkin, see OOHaskell
18:26:45<vixey>:k a -> a
18:26:46<lambdabot>Not in scope: type variable `a'
18:26:46<lambdabot>Not in scope: type variable `a'
18:26:46<pumpkin>pejo: yeah, I've seen that, but didn't think it was widespread enough to be mentioned as "a haskell"
18:26:59<pumpkin>maybe if he'd said OOHaskell :P
18:27:03<monadic_kid>anyways from what I just glanced from the discussion above, why not use a state transformer?
18:27:14<Gracenotes>:k Int -> Int
18:27:15<lambdabot>*
18:27:17<Gracenotes>hrm.
18:27:22<Apocalisp>lilac: The big win with Haskell is that you can define Monad in general.
18:27:29<mmorrow>:k forall a. a -> a
18:27:30<lambdabot>*
18:27:31<pumpkin>mmorrow: hrm :P
18:27:34<Gracenotes>ooh.
18:27:48<byorgey>Gracenotes: any type that actually classifies values has kind *.
18:27:56<byorgey>so that includes any function type.
18:27:56<Apocalisp>lilac: Not just this monad or that monad, but "every m such that... is a monad"
18:27:58<monadic_kid>did someone say they want a state and IO monad?
18:28:02<lysgaard>Having some type problems. I want to make an instance of the (%) function, but i can't find what class it belongs to.. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4997#a4999
18:28:03<Gracenotes>byorgey: of course. I'm just wondering why a -> a didn't work
18:28:10<Gracenotes>but it seems an explicit forall was needed
18:28:15<byorgey>oh, I see
18:28:25<Gracenotes>does seem a bit odd, though, right?
18:28:37<byorgey>lysgaard: % isn't a class method, it's the constructor for values of type Ratio
18:29:00<mauke>pumpkin: huh? it's just a library. why "a haskell"?
18:29:05<Gracenotes>you don't need ExistentialQuantification on, too
18:29:20<byorgey>lysgaard: do you really mean (%) or do you mean mod?
18:29:22<lysgaard>Darn, hmm, ok but i still wan't it to act as (+) (-) and (*) does, how?
18:29:48<pumpkin>mauke: well, citing haskell as an OO language because someone built an OO simulator library for it seems odd, unless that simulated OO is very widespread (which I thought it wasn't)
18:29:50<pejo>pumpkin, that's Oleg's homepage, and he's one of the authors of OOHaskell.
18:29:50<Gracenotes>Apocalisp: I tend to like typeclasses over inheritance for open polymorphism, but still it is limited sometimes
18:29:56<Gracenotes>they are.
18:30:08<pumpkin>pejo: oh, I wasn't aware that he was one of the authors, that makes more sense then
18:30:26<lysgaard>byorgey: I mean division like in (/), just that i want it to be lazy. I'm trying to make a little algebra datatype that i can explore
18:30:46<byorgey>lysgaard: how would division work? what should (Number 3) / (Number 5) be?
18:31:23<lysgaard>byorgey: it should be Divide 3 5
18:31:45<byorgey>lysgaard: ah, ok. that should work fine. Just make Algebra an instance of Fractional.
18:31:48<d3mn0id>http://haskell.org/haskellwiki/Introduction does a very good job of showing you the code line number benefits of Haskell.
18:32:01<byorgey>lysgaard: Fractional has (/), recip, and fromRational
18:32:11<mauke>> 3 / 5 :: Expr
18:32:12<lambdabot> 3 / 5
18:32:21<vixey>lysgaard: not Divide (Number 3) (Number 5)?
18:32:43<mmorrow>pumpkin: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2445#a2445
18:32:52<lysgaard>vixey: oh, yeah, Divide (Numbe... is correct
18:33:30<pumpkin>mmorrow: I understood that bit, but I was wondering how you'd compose those things elegantly
18:33:37<mmorrow>pumpkin: compose what?
18:33:48<pumpkin>say you have an RNet for network access
18:33:49<pumpkin>and an RFile
18:33:53<pumpkin>they're fine on their own
18:33:54<lysgaard>byorgey: isn't fractional a lossy datatype?
18:34:10<pumpkin>say you wanted to write a simple webserver, that needs file access and network access
18:34:12<byorgey>lysgaard: Fractional isn't a data type.
18:34:15<mmorrow>pumpkin: well, you'd need a monad that has both capabilities
18:34:27<byorgey>it's a type class that specifies certain functions that should be available.
18:34:34<mmorrow>pumpkin: then rfileToRFileAndRNet and rnetToRFileAndRNet
18:34:38<lysgaard>byorgey: I mean is 10/3 = 3.333 or 10/3 = 10/3?
18:34:50<byorgey>lysgaard: it depends on the type.
18:34:53<pumpkin>mmorrow: ah, so you'd make an RFileAndRNet type
18:35:00<mmorrow>pumpkin: :: RFile a -> RFileAndRNet a, RNet a -> RFileAndRNet a
18:35:06<byorgey>lysgaard: Double is an instance of Fractional; it is lossy. Rational is also an instance of Fractional; it is not lossy.
18:35:06<mmorrow>pumpkin: something like that
18:35:09<mm_freak>doWhatIMean :: IO ()
18:35:26<pumpkin>that feels cumbersome :/
18:35:32<mm_freak>whatIMean :: a
18:35:33<mmorrow>pumpkin: i bet there's a more elegant way to express a monad's capabiltiies thgouh
18:35:34<byorgey>lysgaard: Fractional is completely agnostic about how (/) actually works for each particular type. that is up to the instance.
18:35:38<frwmanne1s>> (10/3) :: Double
18:35:39<lambdabot> 3.3333333333333335
18:35:45<byorgey>lysgaard: for your Algebra type, it looks like it will not be lossy.
18:35:47<mm_freak>> whatIMean
18:35:48<lambdabot> Not in scope: `whatIMean'
18:35:48<mmorrow>pumpkin: (than simply making an entirely new type)
18:35:49<pumpkin>mmorrow: that à la carte paper seemed pretty nice
18:35:49<lysgaard>byorgey: Oh!
18:35:50<mm_freak>=/
18:35:52<Eelis>is there a cabal-specific channel?
18:35:57<mmorrow>pumpkin: i haven't read it
18:36:05<mmorrow>pumpkin: link?
18:36:08<mmorrow>:)
18:36:15<pumpkin>mmorrow: that's what got me interested in doing this, it's pretty neat :) http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf
18:36:15<thoughtpolice>@go data types a la carte
18:36:17<lambdabot>http://lambda-the-ultimate.org/node/2700
18:36:17<lambdabot>Title: Data Types a la Carte | Lambda the Ultimate
18:36:31<pumpkin>mmorrow: specifically, near the end, but the whole paper is pretty awesome
18:37:12<mmorrow>pumpkin: oh yeah, i've seen that stuff
18:37:13<mauke>Eelis: signs point to "no"
18:37:20<Eelis>mauke: ok
18:37:32<[bjoern]>I am looking for a more elegant way to do map (\p -> if p == 5 then 2 else p) [0..9] - where the list and integers are variable of course
18:37:44<lysgaard>byorgey: Ok, i think i understand, i'll try it =)
18:37:50<mmorrow>pumpkin: have you looked at the code to IOSpec?
18:37:56<mmorrow>(it's on hackage)
18:38:00<pumpkin>mmorrow: a little
18:38:30<mmorrow>it's neat
18:38:42<pumpkin>I'll take a closer look
18:38:55<pumpkin>gotta run :)
18:38:57<mmorrow>ooh, nice. i just saw this bit:
18:39:09<mmorrow>FilePath → Term (Teletype :+: FileSystem) ()
18:39:13<pumpkin>yeah :)
18:39:16<Eelis>cabal's "setup configure" can run a user-supplied configure script. when it does, it passes it a bunch of options including --prefix, if the user specified those. however, when the user didn't, nothing is passed. is the default prefix completely fixed, or does it differ from platform to platform?
18:39:27<pumpkin>mmorrow: that's really attractive to me :P but unfortunately haskell can't infer that type
18:39:30<mmorrow>pumpkin: so you just do ST (Teletype :+: FileSystem) a
18:39:35<pumpkin>so you need to annotate it explicitly
18:39:36<mmorrow>et voila
18:39:51<mmorrow>hrm
18:40:00<dcoutts_>Eelis: yeah, that's not good really, it should always specify all the vars explicitly to configure. Feel free to file a ticket.
18:40:11<Eelis>dcoutts_: alright, i will.
18:40:23<pumpkin>mmorrow: I'll be back in a bit :)
18:40:27<dcoutts_>Eelis: thanks
18:40:27<mmorrow>cool
18:41:24<dcoutts_>Eelis: in practise it's not been a problem because haskell packages with configure scripts are not usually generating anything that embeds paths, usually just checking prerequisites and generating flags for include dirs etc
18:41:40<lysgaard>byorgey: How do i find out what class an function is from eg: (^)
18:41:47<vixey>:t (^)
18:41:48<lambdabot>forall a b. (Integral b, Num a) => a -> b -> a
18:41:59<vixey>it's got to be either in Integral or Num or neither
18:42:09<Eelis>dcoutts_: yeah, i can imagine. unfortunately, i've run into a case where i really do need to know the prefix in the configure script (because i have some post-cabal installation steps)
18:42:14<vixey>or actually it could be in any other class I guess
18:42:23<lysgaard>vixey: How can it be in neither?
18:42:29<byorgey>actually, (^) isn't in a class
18:42:31<vixey>@src (^)
18:42:31<lambdabot>x ^ 0 = 1
18:42:32<lambdabot>x ^ n | n > 0 = f x (n-1) x
18:42:32<lambdabot> where f _ 0 y = y
18:42:32<lambdabot> f x n y = g x n
18:42:32<lambdabot> where g x n | even n = g (x*x) (n `quot` 2)
18:42:33<lambdabot> | otherwise = f x (n-1) (x*y)
18:42:35<vixey>like that ^
18:42:35<lambdabot>_ ^ _ = error "Prelude.^: negative exponent"
18:42:54<byorgey>lysgaard: it is just implemented in terms of methods in the Integral and Num classes
18:43:02<dcoutts_>Eelis: right, it's always possible to override the code that calls configure and you can call it yourself.
18:43:27<byorgey>lysgaard: but in general, you want to use ghci (or lambdabot) to look at the type
18:43:41<Eelis>dcoutts_: interesting. override where? in Setup.hs? guess i should read the cabal manual again :)
18:43:41<byorgey>then look at any classes you see in its type
18:43:43<lysgaard>i use ghci all the time
18:43:52<byorgey>you can get more info about a class using :info
18:43:54<byorgey>like :info Integral
18:43:55<dcoutts_>Eelis: yes, using the hooks in Setup.hs
18:44:05<Eelis>dcoutts_: ok, i will look at those. thanks!
18:44:09<byorgey>will show you all the methods in the Integral class.
18:44:17<Berengal>lysgaard: or just ':info (^)'
18:44:27<Berengal>Prelude> :info (+) <\n> class (Eq a, Show a) => Num a where<\n> (+) :: a -> a -> a
18:44:34<dcoutts_>Eelis: see autoconfUserHooks in Distribution.Simple
18:44:36<Berengal>↑ What I get from ghci
18:44:42<lysgaard>but say i want to make a (^) function for my algebra, how do i do thot then, when it's in no class?
18:44:58<byorgey>ah, right, at first I thought :info for (^) didn't work since it didn't show me a class... but that's because (^) isn't in a type class =)
18:45:25<byorgey>lysgaard: the type of (^) says it works for any arguments whose types are instances of Num and Integral
18:45:40<byorgey>so if your algebra type is an instance of those classes, (^) will automatically work for it
18:45:47<Berengal>(^) is defined in terms of the class functions. If you want it to work for your type you need to implement the class functions such that they provide the answers (^) expect of them
18:47:26<lysgaard>well, my algebra type includes variables, so it can't be a member of Integral or Num, but it includes the type Number, wich is an Integral. look here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4997#a5001
18:47:48<vixey>lysgaard: here's what I do
18:47:52<vixey>import Prelude
18:48:04<vixey>Number x + Number y = ...
18:48:14<vixey>define (+) yourself and forget about the normal definition
18:50:07<vixey>btw putting | at the end of all the lines except one is ugly
18:50:11<vixey>you can write
18:50:15<vixey>data X = ...
18:50:21<vixey> | ...
18:50:22<vixey> | ...
18:50:23<vixey>instead
18:50:46<vixey>also (Number a) == (Number b) = a == b can be Number a == Number b = a == b
18:51:36<frwmanners>lysgaard: something along the lines of (Raise a b) * (Raise c d) | a == c = Raise a (b + d) might get the standard (^) to work
18:51:38<lysgaard>vixey: Thanks, i love syntax tips, they always make the code cleaner
18:52:45<frwmanners>lysgaard: btw, is (Add (Variable "x") (Variable "y")) not equal to itself?
18:55:08<lysgaard>frwmanners: Well, i don't know how to express two variables, who in practise can be any number you want, in any more sensibel way
18:55:49<frwmanners>lysgaard: sure
18:56:12<frwmanners>lysgaard: but if == is really ===, then you could get away with Add a b == Add c d = a == c && b == d
18:56:29<copumpkin>:o
18:56:32<frwmanners>lysgaard: or
18:56:42<frwmanners>lysgaard: with the arguments flipped or something
18:56:44<copumpkin>ACTION is back!
18:57:41<SubStack>finally!
18:58:12<dolio>@yow! The volcano taco is back!
18:58:13<lambdabot>MMM-MM!! So THIS is BIO-NEBULATION!
18:58:22<lysgaard>frwmanners: One more time, i think you're at a wery important point, but i didn't understan how you meant i should implement it?
18:59:46<frwmanners>lysgaard: instance Eq Algebra where Number a == Number b = a == b; Variable a == Variable b = a == b; Add a b == Add c d = (a == c && b == d) || (a == d && b == c)
19:00:10<frwmanners>lysgaard: with some more cases for multiplication &c
19:00:40<d3mn0id>I'll come back when I know some Haskell.
19:00:49<frwmanners>lysgaard: assuming your algebraic expressions are finite, eventually you'll bottom out into one of those
19:01:02<frwmanners>lysgaard: and then a massive a == b = False at the end
19:01:18<lysgaard>frwmanners: They are finite, that's for shure
19:01:57<frwmanners>lysgaard: so right, a recursive definition of equality is probably the way to go
19:02:30<lysgaard>Yeah, i got your point now, genious :D
19:04:43<lysgaard>But to be even more general, this Eq, the one for add is also true for Multiply. And for subtraction, and division, it's true, but not the arguments flipped. Is there a way to make the algebra type so that it can figure out this?
19:06:31<frwmanners>lysgaard: data Algebra ... deriving Eq would be nearly there, but you'd lose the argument flipping I guess
19:06:57<lysgaard>frwmanners: What if i made an opperator type or something?
19:07:38<lysgaard>frwmanners: Or isn't that the way to go?
19:07:48<frwmanners>lysgaard: could work
19:07:54<frwmanners>lysgaard: up to you I guess
19:08:32<frwmanners>lysgaard: data BinOp = CommutativeOperator String | NonCommutativeOperator String would not be unsensible
19:08:49<vixey>I'd rather
19:09:00<vixey>data CommutativeOp = Add | Multiply
19:09:03<vixey>than 'String'
19:09:13<frwmanners>sure
19:09:35<frwmanners>depends how many exotic operators you're likely to dream up I suppose
19:09:37<lysgaard>Ok, what does that mean :P
19:10:11<vixey>anyway having == for syntactic equality, but then a different equality test for semantic equality is a good idea
19:10:15<vixey>so deriving Eq is cool
19:10:51<frwmanners>so an === operator or something?
19:10:57<lysgaard>Hehe, I'm doing this mostly as an exersise to get to know the typesystem of haskell. Therefore I'd like to get as complicated as i can understand
19:11:24<frwmanners>lysgaard: so, if you make CommutativeOp = Add | Multiply
19:12:06<frwmanners>lysgaard: you can then have data Algebra = Number Integer | ... | CommOp CommutativeOp Algebra Algebra
19:12:36<frwmanners>lysgaard: | NonCommOp NonCommutativeOp Algebra Algebra
19:12:58<frwmanners>where you've also got data NonCommutativeOp = Sub | Div
19:13:01<Baughn>ACTION finally got reactive working (work on that dependency algorithm..), and is now in the process of blowing up his head. Thanks, guys.
19:13:04<Eelis>dcoutts_: (fyi, reported: http://hackage.haskell.org/trac/hackage/ticket/553 )
19:13:12<dcoutts_>Eelis: thanks
19:14:03<Baughn>Using reactive-glut to make a mini-GUI toolkit.. I can't quite understand things yet, but it looks very, very sweet.
19:14:16<frwmanners>lysgaard: So ``x + y'' becomes CommOp Plus (Variable "x") (Variable "y")
19:14:30<frwmanners>lysgaard: &c.
19:14:46<Baughn>Now if only I could figure out the Show instance for Event. It doesn't do what I expected (eg. let me print events as they happen).
19:14:53<lysgaard>frwmanners: Yeah, i think i've got it
19:14:59<frwmanners>lysgaard: cool
19:15:05<hatds>I'm making my own mini-GUI toolkit, what do you see useful about reactive?
19:15:58<Baughn>hatds: The sheer functionalness, basically; they've figured out a way to let me write imperative code declaratively, in a much nicer fashion than I've ever seen before
19:16:11<roconnor>hatds: have I told you about GuiTV before?
19:16:18<Baughn>hatds: ..I can't be much more specific than that, since I only just got started
19:16:19<hatds>roconnor: yea
19:16:26<roconnor>hatds: ok
19:16:36<roconnor>carry on then :)
19:16:39<hatds>roconnor: I've read a bit about it, is there something particular about that one versus the others?
19:17:06<Baughn>hatds: But it takes care of all the usual machinery (event handlers, callbacks, etc.) under the covers, in a way that I don't even need to know they're there
19:17:07<roconnor>hatds: I'm not sure. GuiTV is the only Gui system I've ever used in haskell.
19:18:12<hatds>my GUI system is tick-based and not event-driven, the outer system has to call app_draw and app_main
19:18:23<hatds>but I've been thinking about whether that could be better
19:18:31<endojelly>why are there bottom-up and top-down versions of everywhere (everywhere and everywhere', respectively), but only a top-down version of everywhereM in the standard library? I had to define everywhereM' myself...
19:18:54<frwmanners>Baughn: do you want to print Events when they happen or when they become defined?
19:19:22<copumpkin>omg there are
19:19:23<pumpkin>two of me
19:19:57<Baughn>frwmanners: I'm afraid I don't understand the difference. If you wouldn't mind? ;)
19:20:02<lysgaard>frwmanners: Think I've got it, but i'll need to add algebra to Show :S http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5005#a5005
19:20:34<pumpkin>Algebra is an odd name
19:21:06<roconnor>newtype Algebra f a b = Algebra (f a -> b)
19:21:07<Baughn>frwmanners: I mean, I'd like to print them when they happen - just to make sure this is working - but I'd like to know what "defined" means in terms of reactive
19:21:08<frwmanners>Baughn: So, as I understand it, something like atTimes [0..] is defined from the word go, even though things only happen at times 0, 1, 2 ...
19:21:17<pumpkin>roconnor: that's what I normally think of
19:21:20<lysgaard>pumpkin: Yeah, you have any better, i don't like it either, but i'm not to good in math phrasology
19:21:39<Baughn>frwmanners: Makes sense
19:21:45<pumpkin>lysgaard: you can ask haskell to derive Show for you, too
19:21:50<Baughn>frwmanners: It'd just block until time reaches those.. times, I suppose
19:22:03<frwmanners>Baughn: ok
19:22:10<Baughn>frwmanners: Incidentally, what I've got right now is "sink UI{..} = pure (print 42 >> print leftButtonPressed)", which prints 42 and then 'thread blocked indefinitely'
19:22:27<TonyTheTiger>hiya how do i write a type signature for somthing like... twice f x = f (f x)
19:22:28<Baughn>frwmanners: Oh, I think I just figured it out myself..
19:22:51<roconnor>twice :: (a -> a) -> a -> a
19:22:52<Baughn>frwmanners: pure (Behavior) describes it at time -infinity, /once/.. right?
19:22:59<Baughn>But mostly at time -infinity
19:23:25<pumpkin>TonyTheTiger: by the way, twice = join
19:23:27<Baughn>So of course the keys never get pressed, as far as that behavior is concerned
19:23:40<frwmanners>a pure Behaviour should take the same value at all time
19:23:42<TonyTheTiger>roconnor: but its a function that it takes,
19:23:46<roconnor>pumpkin: in what monad?
19:23:51<TonyTheTiger>roconnor: does that not matter?
19:23:57<roconnor>TonyTheTiger: (a -> a) is a function
19:24:03<pumpkin>roconnor: oh wait, that makes no sense, sorry :)
19:24:09<frwmanners>a pure event happens once at (-infinity)
19:24:12<patch-tag>hey is there a haskell package or "style" that can be used to program simple command line stuf that's okay on both unix and dows? like, really simple, just cd here and there, and then run ghc commands. hsh is really nice but seems to be unix only
19:24:25<Baughn>frwmanners: Right you are
19:24:36<Baughn>frwmanners: And my behavior is not supposed to be pure, so I shouldn't be using it. :)
19:24:39<pumpkin>roconnor: it could be join (.) though
19:24:55<Baughn>..nice choice of function name, there
19:24:56<pumpkin>since it's really twice f x = ((.) f f) x
19:25:04<TonyTheTiger>roconnor: ohh ok, and would i need to do this too... twice :: (Num a) => (a -> a) -> a -> a?
19:25:10<TonyTheTiger>would that be correct?
19:25:11<hatds>I was almost going to do a reactive approach when I started, but I didn't know of reactive back then
19:25:31<hatds>the best I could come up with was like an infinite stream of inputs with unsafeInterleaveIO
19:25:39<roconnor>TonyTheTiger: well, you don't really need the Num constraint since the function has nothing to do with numbers, but adding the constraint doesn't really hurt much.
19:26:20<TonyTheTiger>roconnor: oh yeah the "function" that im calling will handle that, thanks i understand now.
19:26:54<hatds>having imperative push-based events does not rule out declarativeness though
19:28:03<roconnor>> myThreadID
19:28:04<lambdabot> Not in scope: `myThreadID'
19:28:05<roconnor>> myThreadId
19:28:06<lambdabot> Not in scope: `myThreadId'
19:28:22<roconnor>@hoogle mythreadid
19:28:22<lambdabot>Control.Concurrent myThreadId :: IO ThreadId
19:54:00<Baughn>conal: Would you accept a reactive-glut patch to add leftButton/rightButton Behavior Bools and equivalent keyboard behavior? (I'm very new to this whole "reactive" thing, but.. kinda need those)
19:54:25<lysgaard>I've gotten a bit furter, but now i have some problems with a simplyfy function. I think i've missunderstood the typesystem or something :S http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5005#a5006
19:54:39<TonyTheTiger>hi guys can explain to me how you use null and where it would be appropriate?
19:55:53<lysgaard>TonyTheTiger: What do you want to do?
19:56:17<Berengal>TonyTheTiger: We don't have null, only nil and Nothing
19:56:21<lysgaard>TonyTheTiger: Null like in imperative languages (c, python ...) does not exist
19:56:22<pejo>TonyTheTiger, whenever you want to know if a list is empty or not.
19:56:49<lysgaard>TonyTheTiger: All functions in haskell has to return someting
19:56:55<adamvo>> null []
19:56:56<lambdabot> True
19:57:09<lysgaard>What you need is I guess is Maybe
19:57:24<Baughn>conal: ..make that Set Key for the keyboard
19:57:31<pejo>TonyTheTiger, (but pattern matching might be more clear in a recursive function, for example).
19:58:10<vixey>> null null
19:58:12<lambdabot> Couldn't match expected type `[a]'
19:58:25<vixey>null is pretty much useless
19:58:33<vixey>I guess there are sometimes you can use it
19:58:46<Berengal>vixey: I use if null foo then ... often enough
19:58:57<roconnor>@type let foo 7 = () in foo
19:58:58<lambdabot>forall t. (Num t) => t -> ()
19:59:05<vixey>lysgaard: You need to write:
19:59:07<pumpkin>> null [null]
19:59:08<lambdabot> False
19:59:12<FunctorSalad>hehe
19:59:12<vixey> CommOpp (Add a b) = ...
19:59:14<pumpkin>> null [null [null]]
19:59:14<vixey>it can't be
19:59:15<lambdabot> False
19:59:17<vixey> CommOpp Add a b = ...
19:59:23<pumpkin>> null [null [null [null]]]
19:59:25<lambdabot> False
19:59:25<vixey>the reason is because 'CommOpp' isn't an operator
19:59:33<FunctorSalad>> fix (\x -> null [x])
19:59:35<lambdabot> False
19:59:37<FunctorSalad>:o
19:59:37<ziman>> fix (nul . (:[]))
19:59:38<lambdabot> Not in scope: `nul'
19:59:44<TonyTheTiger>guys can you explain to me how null works and applying it?
19:59:44<ziman>> fix (null . (:[]))
19:59:46<lambdabot> False
19:59:47<FunctorSalad>ziman :)
19:59:54<ziman>FunctorSalad, you got it right ;)
20:00:00<Berengal>@type null
20:00:02<lambdabot>forall a. [a] -> Bool
20:00:12<lysgaard>vixey: CommOpp is an constructor?
20:00:22<adamvo>@src null
20:00:22<lambdabot>null [] = True
20:00:22<lambdabot>null (_:_) = False
20:00:29<vixey>fus
20:00:32<vixey>yes*
20:00:36<Berengal>map null $ iterate (():) []
20:00:53<Berengal>> map null $ iterate (():) []
20:00:55<lambdabot> [True,False,False,False,False,False,False,False,False,False,False,False,Fal...
20:00:57<TonyTheTiger>huh, its alot more simple than i thought about
20:01:00<TonyTheTiger>cheers
20:01:46<lysgaard>vixey: Yay! I think i'm getting the hang of this
20:01:53<vixey>:)
20:02:14<lysgaard>vixey: But how can i do the patternmatching then?
20:02:15<FunctorSalad>ISTR there's a rewrite rule that replaces stuff like (x==[]) with a pattern match
20:02:24<vixey>lysgaard pattern matching of what?
20:02:28<FunctorSalad>or a different ghc optimization
20:02:40<copumpkin>people talk about all haskell data being codata
20:02:44<lysgaard>vixey: Eg: | a == - b = Number 0 for Add
20:02:45<copumpkin>or am I misremembering?
20:02:48<adamvo>@type (==[])
20:02:50<lambdabot>forall a. (Eq a) => [a] -> Bool
20:03:03<FunctorSalad>copumpkin: :O I considered asking this several minutes ago.
20:03:04<vixey>adamvo: yeah null has to be pattern matching
20:03:15<osfameron>copumpkin: coremembering?
20:03:36<FunctorSalad>copumpkin: I wonder what the full story behind this "ADTs are both initial algebras and final coalgebras" thing is
20:03:39<FunctorSalad>:)
20:03:54<sjanssen>FunctorSalad: I don't think there is a rewrite rule for that, it is invalid
20:04:09<copumpkin>FunctorSalad: hah :P I got tired of wondering what coinduction was so I looked it up, and it mentioned that codata was coninductively defined data, and was typically infinite... then I remembered someone saying that all haskell data was codata so now I'm confused :P
20:04:33<FunctorSalad>sjanssen: not a rewrite rule I guess, but I remember seeing compiler output like "replacing (==) with pattern match"?
20:04:43<conal>Baughn: i like the Bool & Set suggestions. perhaps both could implemented on top of current interface plus button release events.
20:04:45<roconnor>copumpkin: I think I said all data in Haskell is codata
20:04:51<copumpkin>aha :)
20:04:54<roconnor>copumpkin: but It's not entirely true I guess
20:04:57<copumpkin>could you elaborate on that? I'm clueless
20:04:58<copumpkin>oh
20:05:06<dolio>In a complete partial order category, which is where Haskell gets its semantics, all initial algebras are final coalgebras and vice versa.
20:05:08<Peaker>Baughn: I wrote a Set Key thing myself for Reactive
20:05:11<roconnor>cause data Foo = Foo (Foo -> Bool) can be done in haskell
20:05:18<roconnor>and who know WTF that is.
20:05:41<roconnor>maybe dolio knows what it is.
20:06:14<dolio>I've never been able to find a category theoretic proof of it, but the fact that you can define both fold and unfold for every suitable datatype using general recursion pretty much demonstrates it.
20:06:38<Peaker>Baughn: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5007#a5007
20:06:40<dolio>Considering only strictly positive types, and not the weird ones like roconnor just mentioned.
20:06:44<vixey>dolio: can't it always be done by single step structural recursion?
20:06:56<copumpkin>hmm
20:07:01<Baughn>conal: That's fine. I need button release events to implement them anyway, so might as well export them
20:07:07<Baughn>conal: I'll get you a patch soonish, then
20:07:07<copumpkin>what would codolio say though?
20:07:34<Peaker>conal: ah, you're here, here's a Behavior (Set Key) implementation on top of existing keyAction: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5007#a5007
20:08:11<Baughn>conal, Peaker: Thanks, I'll just include that one then. :)
20:08:15<FunctorSalad>dolio: the thing I find slightly confusing is that "infinite lists over A" is not an initial \X -> X * (A -> X -> X) algebra in Set
20:08:54<Peaker>Baughn: note that Behavior loses the discrete nature of the events, though. Maybe its better to use accumE and get an event, instead
20:09:10<mreh>how can i determine what GHC a certain library was distributed with?
20:09:31<FunctorSalad>err wait that functor is wrong
20:09:37<Baughn>Peaker: We're getting leftButtonReleased too, as per conal's request
20:09:45<dolio>F X = A * X you mean?
20:09:49<FunctorSalad>\X -> 1 + A*X
20:09:58<dolio>Oh.
20:10:00<Baughn>Peaker: So you can use eitherE
20:11:11<FunctorSalad>I guess thinking about it in terms of sets is totally misleading
20:11:29<vixey>yeah down with sets!!
20:12:02<mmorrow>ACTION gets his pitchfork and riot shoes on
20:12:38<dolio>Well, to be honest, I'm not too familiar with that area of discussion, either. I'd have to think about it a bit.
20:13:09<roconnor>start with Cale! he is a set sympathizer!
20:13:14<FunctorSalad>=)
20:13:18<dolio>However, the initial algebra in Set would have to be such that for any other algebra, there's a total function to it from the initial algebra.
20:13:36<FunctorSalad>dolio: yep, in Set the intial algebra is just the finite lists
20:14:07<FunctorSalad>the infinite risks aren't "reached" by specifying an algebra
20:14:16<FunctorSalad>so they could map to anything, hence no unique morphism
20:14:26<FunctorSalad>*infinite lists
20:14:28<dolio>And there's probably not always a total function from the set of possibly infinite lists to other appropraite sets, so that's why it isn't initial.
20:15:06<dolio>Like, for instance, foldr (+) 0 :: [Natural] -> Natural.
20:15:13<roconnor>I wish I knew what the semantics for data types in haskell were.
20:15:43<roconnor>@type foldr (+) 0 :: [Natural] -> Natural.
20:15:44<lambdabot>parse error on input `.'
20:15:47<FunctorSalad>dolio: there exist plenty of total functions, but you have to arbitrarily choose the image of infinite lists
20:15:47<roconnor>@type foldr (+) 0 :: [Natural] -> Natural
20:15:48<lambdabot>[Natural] -> Natural
20:16:04<roconnor>dolio: Haskell's Natural contains infinity
20:16:09<roconnor>@type infinity
20:16:11<lambdabot>Natural
20:16:16<Beelsebob>wow, Haskell is green today
20:16:27<FunctorSalad>(or rather, you get to make a choice for every equivalence class of infinite lists, where two lists are equivalent if they have the same tail eventually)
20:16:29<dolio>FunctorSalad: Well, yes, but they have to satisfy certain laws to qualify as algebra homomorphisms.
20:17:14<dolio>roconnor: Yes, but we're talking about Set, not Hask.
20:17:19<TonyTheTiger>is this stuff true about haskell?
20:17:20<TonyTheTiger>http://uncyclopedia.wikia.com/wiki/Haskell
20:17:43<pumpkin>lol
20:17:50<roconnor>dolio: didn't you see the pitchforks?
20:17:54<FunctorSalad>dolio: hmm right, if the algebra we map to has operations nil and cons, then we need f [] = nil and f (x:xs) = cons x (f xs)
20:18:08<pumpkin>TonyTheTiger: "Uncyclopedia, the content-free encyclopedia"
20:18:12<FunctorSalad>dolio: so I think you're right that morphisms may not exist (not sure)
20:18:18<nagnatron>lmao
20:18:29<dolio>roconnor: We're throwing out Set? Then I guess we won't giving semantics to our total languages. :)
20:18:50<pumpkin>> fix$(<$>)<$>(:)<*>((<$>((:[{- OH MY GOD IT'S A COMMENT!!! -}])<$>))(=<<)<$>(*)<$>(*2))$1
20:18:53<lambdabot> [1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,...
20:18:56<pumpkin>lol
20:18:58<roconnor>dolio: not using Set we won't.
20:19:19<SamB>dolio: Total langauges don't use *that* Set
20:19:41<TonyTheTiger>pumpkin: funny. :)
20:19:45<roconnor>dolio: we use type theory for our semantics.
20:19:50<dolio>What Set do they use, other than the category of sets and total functions?
20:19:56<roconnor>dolio: which is great because we are defining type theory.
20:20:02<roconnor>dolio: makes it much easier.
20:20:05<[bjoern]>I had trouble coming up with the right signature for this function (or have some other problem i have yet to debug...)
20:20:06<[bjoern]>basically i want f(List of triples of X, list of X, list of triples of X) maps to a list of triples of X (X in this case is Int)
20:20:07<SamB>dolio: they don't use sets from set theory!
20:20:22<dolio>That doesn't answer my question.
20:20:36<[bjoern]>I get "Occurs check: cannot construct the infinite type: x = [x]"
20:20:51<FunctorSalad>dolio: you're right, "foldr (+) []" with domain the infinite lists doesn't exist in Set. if x = cycle [1], then we have 1:x == x, but there's no natural fx such that 1+fx==fx
20:20:54<SamB>they use more constructive things
20:20:58<roconnor>[(x,x,x)] -> [x] -> [(x,x,x)] -> [(x,x,x)]
20:21:07<[bjoern]>ACTION tries
20:21:26<sjanssen>[bjoern]: the error probably means there is an error with your code, not the signature
20:21:40<FunctorSalad>btw guys I really didn't mean to start a Set vs. Type Theory war ;)
20:21:41<pumpkin>that's an odd signature
20:21:41<pumpkin>what does it do?
20:21:42<[bjoern]>Yeah, ideas how to debug that?
20:21:55<roconnor>[bjoern]: I'm assuming that you rewrite your function in the usual curried style.
20:22:00<dolio>FunctorSalad: Right. So I think that shows that the initial algebra of 1 + A*X in Set doesn't have infinite lists.
20:22:14<mreh>are they going to bundle cabal with GHC soon?
20:22:22<roconnor>ACTION bets [bjoern] is dealing with colour.
20:22:29<pumpkin>mreh: nope, cabal-install comes with the platform though
20:22:36<dolio>SamB: What category would you use if you want to talk about the initial algebra semantics of a total functional programming language?
20:22:39<FunctorSalad>*"foldr (+) 0" actually
20:22:39<dcoutts_>mreh: that's what the platform does
20:22:41<[bjoern]>no, the triples are weighted edges in a graph
20:22:42<pumpkin>mreh: the cabal infrastructure already comes with ghc
20:22:46<roconnor>damn
20:22:46<Berengal>System.IO.Unsafe.Really.IMeanIt.reallyReallyAbsurdlyUnsafePerformIOShameOnYou
20:22:47<vixey>FunctorSalad: was there a war and I missed it?
20:22:54<SamB>dolio: dunno!
20:22:55<mreh>pumpkin: but i still need the other three packages
20:23:02<dolio>The one I've typically seen is Set.
20:23:05<roconnor>[bjoern]: you should paste your code
20:23:07<roconnor>@paste
20:23:07<lambdabot>Haskell pastebin: http://hpaste.org/new
20:23:10<SamB>I didn't haven't even failed category theory yet!
20:23:10<mreh>i'm trying to build cabal myself
20:23:31<lysgaard>vixey: If you look at the bottom of the hpaste, "instance Calculate" you see that i try to find special cases for the expressions eg: a * 1 = a. How do i make that part work
20:23:32<SamB>I have yet to discover where I might be able to attempt this feat
20:23:34<pumpkin>mreh: the bootstrap script doesn't work?
20:23:35<dcoutts_>mreh: you can use the bootstrap script to automate that
20:23:43<mreh>okay
20:23:54<dcoutts_>@quote stereo
20:23:55<lambdabot>LoganCapaldo says: * LoganCapaldo must resist urge to mention stereo
20:23:58<dcoutts_>bah
20:24:04<vixey>lysgaard: to write something like this I would use a fold
20:24:04<FunctorSalad>vixey: seemed like it was about to start, people already had their riot shoes out
20:24:16<SamB>dcoutts: ooh, I like it!
20:24:17<SamB>variety
20:24:20<mreh>pumpkin, dcoutts_: i have 6.8.3, and i've been told that i have to do it manually
20:24:29<hydo>Does the gitit author happen to hang out here by chance? I thought I'd ask before I sent him email.
20:24:44<SamB>hydo: would that be gwern?
20:24:47<dcoutts_>mreh: the bootstrap script will work fine with 6.8.x
20:24:49<mreh>atleast that's what RHW says
20:24:51<Heffalump>SamB: no
20:24:57<mreh>RWH
20:25:01<mmorrow>the gitit guy is a philosophy professor :)
20:25:06<hydo>SamB: jmacfarlane
20:25:09<SamB>oh.
20:25:10<lysgaard>Would you mind explaining please?
20:25:10<FunctorSalad>SamB: of course Set would be unnecessarily large because countable sets should suffice for the semantics of a programming language?
20:25:16<hydo>ah, so probably doesn't hang out on irc. hehe
20:25:20<dcoutts_>mreh: right, RWH was published before the bootstrap script
20:25:20<SamB>does gwern at least hack on gitit a lot ?
20:25:22<FunctorSalad>but I don't see why you couldn't use it
20:25:32<Heffalump>SamB: yes, or at least on filestore which is closely related
20:25:32<SamB>hydo: uh, but that sounded like an IRC nick to me!
20:25:52<hydo>SamB: I was abbreviating his name... for reasons still unkown to me.
20:25:56<SamB>so ... since when do philosophy professors know how to program ?
20:26:09<lysgaard>vixey: You mean like folding over the expression?
20:26:10<ent20py1>since prolog :P
20:26:14<SamB>much less in Haskell!
20:26:26<Eelis>is there a way to get cabal to copy a directory in whole when installing? i tried putting "data-files: thedir" in my .cabal, but this produces "Setup.hs: thedir: copyFile: inappropriate type (is a directory)"
20:26:59<FunctorSalad>roconnor: are you saying that the problem with "data Foo = Foo (Foo -> Bool)" is that the functor is contravariant? hmm
20:27:07<Baughn>conal: Probably a reactive issue; it occurs to me that flipFlop should not generate a new (internal) event when it does not, in fact, flop
20:27:22<dcoutts_>Eelis: you can use a limited form of wildcard in Cabal 1.6 and later
20:27:34<Eelis>dcoutts_: yes, i noticed, but that would actually be very painful for my case
20:27:47<dcoutts_>Eelis: but there's deliberately no recursive directory copy
20:27:54<Eelis>dcoutts_: what's the rationale?
20:27:58<Eelis>annoying people?
20:28:08<dcoutts_>Eelis: accidentally picking up too many files
20:28:11<Baughn>conal: Anyway. Patch: http://brage.info/~svein/reactive-glut.patch
20:28:12<Heffalump>debris
20:28:27<Eelis>dcoutts_: sigh.
20:28:35<conal>Baughn: "internal" event?
20:28:57<[bjoern]>Okay, figured it out. needed to replace a 'a:b' by '(a:b)'
20:29:01<Baughn>conal: Whatever causes the action to be re-executed (well, "change") in action <$> behaviour
20:29:06<Eelis>dcoutts_: i guess i'll have to override some more hooks then. but seriously, this is plain stupid
20:29:16<roconnor>[bjoern]: a common error
20:29:34<dcoutts_>Eelis: if you can think of a better balance in expressiveness vs safety then do say so
20:29:59<Baughn>conal: You'll see what I mean if you try adaptSimple "" (print <$> keyboard)
20:30:04<Peaker>Baughn: wouldn't it be nicer to define those events in terms of the GLUT events, rather than have many events created with legacy adapters?
20:30:09<Eelis>dcoutts_: well, personally i think the current solution is completely unbalanced. it should just copy the directory. making life miserable for people who actually have a need for the functionality, just to protect those that don't, is silly
20:30:15<FunctorSalad>roconnor: how about F: Endo(Hask * Hask^op), F(X,Y) = (Y -> Bool, X -> Bool)? but that's absolutely ad-hoc ;)
20:30:39<lukeo05>[bjoern]: i have done that a ridiculous amount of times, and still keep doing it. the error message is always never helpful to realize the stupid error.
20:31:06<Peaker>> (maxBound :: Int) + 1
20:31:10<lambdabot> -9223372036854775808
20:31:16<Peaker>yairchu: here's an overflow
20:31:16<dcoutts_>Eelis: suppose we added "data-files: dir/" should it include hidden files etc too?
20:31:29<conal>Baughn: maybe you mean that stepper isn't optimized for event occurrences that switch from a value to the same value.
20:31:38<mreh>so am i bootstrapping cabal, or cabal-install?
20:31:38<Baughn>Peaker: Probably, yes. Might be nice to have the callbacks stuff their events directly into an FRP Event
20:31:38<Eelis>dcoutts_: yes, the whole thing. i like the idea with the trailing / !
20:31:59<Baughn>conal: I might. I didn't check to see how flipFlop is implemented. ;)
20:32:22<Peaker>> 600851475143::Int
20:32:23<lambdabot> 600851475143
20:32:52<dcoutts_>Eelis: and we'd have to check for symlinks (and not follow them, or at least check for no cycles) etc etc
20:33:01<Peaker>> showHex 600851475143 ""
20:33:03<lambdabot> "8be589eac7"
20:33:06<conal>Baughn: FRP isn't really meant to be used with IO (e.g., print). i regrettably took a short-cut and exposed and IO interface, but i really mean something more like O.
20:33:26<dcoutts_>Eelis: which is the other problem, safe recursive dir traversal is not trivial or portable
20:33:28<Eelis>dcoutts_: yes, some work would be involved. i never said it would be free
20:33:35<conal>Baughn: in other words, it's my inteface-bad that allows you to notice the missing optimization.
20:33:41<dcoutts_>Eelis: feel free to file a feature request :-)
20:33:44<Heffalump>conal: wouldn't print be O?
20:33:48<Eelis>dcoutts_: alright, i will
20:33:48<conal>i'll remove the IO stuff at some point.
20:34:08<Baughn>conal: How's that going to work? Wrapping every function in the opengl library? -_-
20:34:33<conal>Heffalump: not in the sense i mean. more like idempotent actions. though that's probably not quite it either.
20:34:49<Baughn>Besides, I might genuinely want to do IO when a user presses some button in my ui
20:34:50<Peaker>a "denotational debugger" for Haskell could be useful, an "operational debugger" could be difficult (hard to debug lazy code as execution jumps all over the place), but if you just debug the values, and not how they're computed, its easy and useful
20:34:56<conal>an example is updating a visual display, such as a gui widget.
20:35:02<skorpan>what does this mean in a type signature? (Tok Token ~ Element syntax) => ..
20:35:12<Heffalump>conal: so O within the scope of the reactive thing
20:35:22<conal>Baughn: a semantic mis-fit for behaviors, then.
20:35:22<Heffalump>skorpan: type equality
20:35:26<Heffalump>it's a new type families thing
20:35:43<skorpan>Heffalump: so it means kind of like Tok Token = Element?
20:35:48<Heffalump>yes
20:35:52<Baughn>conal: Well, of course I'll make my IO idempotent too
20:36:04<Heffalump>well, Tok Token = Element syntax in the case you quoted
20:36:09<mreh>oh, can't I bootstrap on Windows?
20:36:18<Heffalump>one of Tok or Element would have to be a type function for it to be satisfiable
20:36:24<Baughn>conal: But.. right, I see what you mean. I did mention I'm not experienced with FRP. :)
20:36:26<conal>Baughn: oh. what'll your idempotent IO be like?
20:36:35<Baughn>conal: Reading files?
20:38:21<conal>Baughn: oh, hm. i guess you'd have to figure out how you want to relate file-reading to the *semantic* framework of FRP. For instance, files as (immutable) behaviors or events.
20:38:35<conal>Baughn: that's what i'd do.
20:38:55<Baughn>conal: I'm still trying to work out how to actually do opengl output. :/
20:39:31<Baughn>I certainly don't want to re-render a frame every time the user does any input whatsoever
20:39:49<dolio>FunctorSalad: I've re