Experimental IRC log haskell-2009-05-21

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:10<persica>Wraithan: Huh, I was unaware.
00:00:24<erikc>C99 variable length arrays are just sugar for alloca
00:00:38<Cale>romildo: You might also use a Map or IntMap, if there is the possibility of gaps between elements.
00:00:54<Wraithan>persica: yeah, C99 added it
00:01:06<copumpkin><3 alloca
00:01:40<newsham>hahah. conal's blog post rules. I'm afraid conal has oved to IO (as he is having an affect on the world)
00:01:47<newsham>s/oved/moved/
00:02:02<_JFT_>newsham: lol
00:04:17<romildo>Cale, there is no gap in between elements. A list is good for me. I just thought that a mutable array would be better. As a consequence of user interaction, any element in the list can be changed. So I thought that a mutable array would be apropriate. Remember that the imutable list is already stored in an IORef variable.
00:05:02<Cale>romildo: Perhaps Data.Sequence would improve performance for you.
00:05:13<romildo>Cale, with an imutable structure, every time the user changes an element, a new structure should be constructed.
00:05:20<roconnor>> 49000000/14000000
00:05:21<lambdabot> 3.5
00:05:35<romildo>Cale, I will take a look at Data.Sequence.
00:05:39<_JFT_>romildo: check zippers ;)
00:06:04<romildo>_JFT_, what are zippers?
00:06:12<roconnor>49 `choose` 6
00:06:13<Cale>romildo: Yes, but in Data.Sequence's case, only an amount of memory logarithmic in the size of the structure is needed to get a new structure that has all the elements in common except one.
00:06:16<roconnor>> 49 `choose` 6
00:06:17<lambdabot> Couldn't match expected type `t1 -> t'
00:06:37<_JFT_>romildo: http://www.haskell.org/haskellwiki/Zipper
00:06:40<Cale>roconnor: It's because internally, the structure is a tree, and subtrees can be shared.
00:06:53<roconnor>romildo
00:06:58<_JFT_>romildo: something that alleviate the cost of changing part of an immutable structure
00:07:15<Cale>Zippers are good when you need to make lots of modifications around one particular "cursor" in the structure.
00:07:25<roconnor>> product [49-6+1..49] `div` product [1..6]
00:07:26<lambdabot> 13983816
00:07:42<Cale>But if you need random access, nothing is going to do better than some kind of tree.
00:10:41<thoughtpolice>copumpkin: yeah for sure
00:10:57<copumpkin>thoughtpolice: you addicted to killzone now? :)
00:10:58<thoughtpolice>copumpkin: now that bootstrapping is in place again I'm trying to get HEAD working on linux ppc/ppc64
00:11:05<copumpkin>oh
00:11:09<thoughtpolice>copumpkin: well i bought fallout 3 too
00:11:14<copumpkin>lol
00:11:19<copumpkin>that's a fun game
00:12:16<thoughtpolice>copumpkin: but yeah, I want to try optimized HEAD build + mac os x + 64bit + DPH and see how it goes :)
00:12:27<copumpkin>mmm
00:12:39<copumpkin>I need to get me more cores
00:12:42<copumpkin>only got four
00:15:21<roconnor>> 3.5*0.4
00:15:22<lambdabot> 1.4000000000000001
00:16:20<p_l>copumpkin: SiCortex? 72cores in single tower computer? :D
00:16:28<copumpkin>p_l: sounds good
00:17:15<p_l>copumpkin: it would require some work on GHC, though (for MIPS64)
00:17:32<Badger>:t 3.5 * 0.4
00:17:33<lambdabot>forall t. (Fractional t) => t
00:17:40<Badger>curse thee fractional
00:17:44<copumpkin>p_l: yeah
00:17:54<erikc>gnumake -j72
00:18:20<p_l>erikc: you'd max I/O before reaching 72 :)
00:18:31<erikc>heh, yea
00:18:38<p_l>(well, maybe with 10GBit RDMA NFS...)
00:19:11<erikc>not if some of your build tasks are generating lightmaps :)
00:19:20<p_l>well, true :)
00:20:10<p_l>IMHO 36 cores per processor board is nice package :)
00:31:31<amckinley>hey, could someone explain why this doesnt work? http://pastebin.com/m1e57c498
00:34:00<amckinley>getting a type error: No instance for (Stream s m Char)
00:34:01<amckinley> arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31
00:34:56<kniu>amckinley, what's the type of isUpper?
00:35:08<persica>amckinley: Sorry, I'm still learning Parsec myself.
00:35:26<amckinley>:t isUpper
00:35:27<lambdabot>Char -> Bool
00:35:41<kniu>oh hey
00:35:43<amckinley>:t satisfy
00:35:44<lambdabot>Not in scope: `satisfy'
00:35:57<kniu>strange.
00:36:04<amckinley>:t Text.Parsec.Prim.Satisfy
00:36:05<lambdabot>Couldn't find qualified module.
00:36:09<amckinley>argh
00:36:18<amckinley>:t Text.Parsec.Char.Satisfy
00:36:19<lambdabot>Couldn't find qualified module.
00:36:56<amckinley>satisfy :: (Stream s m Char) =>
00:36:56<amckinley> (Char -> Bool) -> ParsecT s u m Char
00:37:20<kniu>my ghci > :t satisfy
00:37:20<kniu>satisfy :: (Char -> Bool) -> CharParser st Char
00:37:35<amckinley>kniu: you're using a 2.x version of parsec
00:37:48<kniu>and what's yours?
00:37:58<amckinley>3.x
00:38:32<amckinley>hey Cale
00:39:00<amckinley>any idea why this doesnt work now that ive switched to parsec 3.x? http://pastebin.com/m1e57c498
00:39:02<amckinley>:)
00:40:39<copumpkin>uh, not without an error :P
00:40:57<amckinley>No instance for (Stream s m Char)
00:40:57<amckinley> arising from a use of `satisfy'
00:41:29<conal>sclv: thanks for your blog comment. mind if i replace "lennary" with "lennart" (or "Lennart")?
00:43:13<amckinley>copumpkin: i feel like i need a more explicit type signature
00:43:56<copumpkin>probably
00:44:15<Cale>amckinley: Sorry about that... where is your code now?
00:44:25<Cale>amckinley: I'll see if I can help sort it out
00:44:32<amckinley>Cale: np, wb :) http://pastebin.com/m1e57c498
00:45:39<BMeph>ACTION wants a T-shirt with (imagine the solidi mark new lines): "Haskell | PARENTAL ADVISORY | Explicit Type Signatures"
00:46:06<copumpkin>lol
00:46:09<amckinley>:)
00:47:46<FunctorSalad>nice one
00:48:31<Cale>amckinley: hmm
00:48:40<Cale>amckinley: What trouble are you having with that?
00:48:52<amckinley> No instance for (Stream s m Char)
00:48:53<amckinley> arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31
00:49:39<Cale>amckinley: I don't get that error...
00:50:10<amckinley>amckinley:dns amckinley$ runghc ../tmp/wtf.hs
00:50:10<amckinley>../tmp/wtf.hs:6:17:
00:50:10<amckinley> No instance for (Stream s m Char)
00:50:11<amckinley> arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31
00:50:11<amckinley> Possible fix: add an instance declaration for (Stream s m Char)
00:50:11<amckinley> In the first argument of `skipMany1', namely `(satisfy isUpper)'
00:50:12<amckinley> In the expression: skipMany1 (satisfy isUpper)
00:50:14<amckinley> In the definition of `foo': foo = skipMany1 (satisfy isUpper)
00:50:31<sclv>conal: please do replace the typo. thx!
00:50:59<sclv>oh, and "the point about monads" should be "the point about monoids" oops.
00:51:05<Cale>amckinley: I just copied and pasted that code into a new file and loaded it in ghci with no problems
00:51:15<FunctorSalad>DMR?
00:51:21<ray>ACTION wants a t-shirt with one of those ghc error messages that tells you "possible fix: add an instance"
00:51:22<Cale>oh!
00:51:27<Cale>That might be it
00:51:40<ray>i'm not sure what dumb joke to work into it, though
00:51:49<kyevan>YES!
00:51:53<kyevan>er.
00:51:56<kyevan>Wrongchan
00:52:02<Cale>amckinley: Try putting {-# LANGUAGE NoMonomorphismRestriction #-} at the top of the file, and see if it helps
00:52:30<amckinley>that fixed it
00:52:32<amckinley>*awesome*
00:52:52<amckinley>:P
00:53:16<amckinley>since ive been screwing with this for an hour, i feel like i should at least know what that language pragma does
00:53:26<copumpkin>are there any parser combinators that work on top of Data.Text?
00:53:28<bremner>ACTION orders whatever kyevan is having
00:55:00<roconnor>the monomorphism restriction is a bit complicated and stupid.
00:55:11<copumpkin>I agree :/
00:55:48<ray>the monomorphism restriction is widely reviled
00:57:18<amckinley>presumably because it results in noobies dealing with incomprehensible error messages, among other reasons? :)
00:58:45<ray>it certainly does that
00:59:18<Gracenotes>lifting the monomorphism restriction would make things that appear to be constant expressions actually be reevaluated every time
00:59:27<Gracenotes>especially in the way it interacts with the Num typeclass
01:00:03<Gracenotes>(of course, it's not guaranteed these things won't be reevaluated every time, but one can generally depend on it...)
01:00:19<ray>the num typeclass isn't nearly reviled enough
01:00:22<amckinley>the wiki article makes sense
01:00:31<amckinley>thanks again Cale :)
01:01:23<aavogt>that reevaluation issue would be better delt with by a warning, not an error IMHO
01:02:32<Gracenotes>the great fault of the Num typeclass is that you generally expect to be dealing with a specific type when working with numbers: that is, you have a specific type in mind, like an Int or Double
01:02:52<Gracenotes>imho anyway
01:03:01<FunctorSalad>you just have to fix the type once though, it will propagate
01:03:11<Gracenotes>well. Not if you have many top-level functions.
01:03:41<FunctorSalad>(and isn't ghc good at eliminating dictionaries anyway?)
01:03:43<Gracenotes>but annotation is known to improve performance.
01:03:54<jeff_s_>I have to say: I love functional languages.
01:03:58<Gracenotes>FunctorSalad: well. For whole-program compilation maybe :)
01:04:31<eivuokko>..or in local scope, ie after inlining.
01:04:38<hatds>does ghc do whole program optimization?
01:05:35<eivuokko>Not explicitly, but you may get inlining that looks a lot like it.
01:06:33<jeff_s_>finally! Solved http://www.spoj.pl/problems/ONP/
01:07:21<roconnor>solve O = NP?
01:07:35<jeff_s_>in Haskell? Can't. give me a better language
01:08:03<dons>hatds: 90% of it.
01:08:49<dons>Gracenotes: but the great benefit is that we get to use (+) for adding things
01:09:15<dons>anyway, give type decls. it's good for you.
01:09:34<Gracenotes>yes. But it is somewhat unintuitive, and would be worsened much more -- perfect storm, perhaps! -- with the monomorphism restriction
01:09:50<BMeph>Gracenotes: IMWO, the faults of the Num typeclass are so varied and full, that picking just one to be "great" is almost as Worthless as this very opinion. :)
01:10:26<Gracenotes>eh. I think it is the greatest: the concept of its existence and the Haskell numerical system :) others tend to be more nitpicky
01:10:47<Gracenotes>but there are pros to the approach, amidst the cons
01:10:51<Gracenotes>and the snocs
01:11:01<Gracenotes>anyway. my opinion, 's all.
01:11:02<FunctorSalad>+ and * should be seperate really...
01:11:03<dons>i bet ghc would surprise you if you looked at the core
01:11:16<FunctorSalad>(for vectors, mostly)
01:11:42<Gracenotes>eh. non-numerical Num instances, *suspicious*
01:11:49<conal>sclv: i just fixed both typos. thx. :)
01:12:06<Gracenotes>dons: howso?
01:12:07<BMeph>ACTION would love to bitch-slap the genius that decided to toss Show into the Num class...
01:12:16<gwern>(go peacefully among the cons and snocs of the world / lispers have their place, just as you do / and no doubt all is executing as it should)
01:12:16<FunctorSalad>granted, it's not a big thing to use some other operator for adding vectors
01:12:41<Gracenotes>BMeph: perhaps an argument for typeclass synonyms from the beginning
01:13:43<Gracenotes>except, how would GHC know to merge (Show a, Num a) into a synonym automatically. It's all so ... hrmhrmeate9werayhwefa :/
01:13:50<dons>gwern: upload the Quantum IO monad to hackage... http://www.cs.nott.ac.uk/~txa/publ/qio.pdf
01:14:13<copumpkin>lots of big Qs in that paper
01:14:25<gwern>dons: bleh, is still working on the math package! he wanted to cabalize it hisself
01:14:45<gwern>(foolish, since I could do it so much faster)
01:15:11<dons>he's sigfpe's friend
01:15:51<Gracenotes>0|copumpkin> + 1|pumpkin>
01:15:56<gwern>no license info. figures.
01:16:15<Gracenotes>a non-probabilistic pumpkin bit
01:16:17<copumpkin>:o
01:17:14<mux>dons: hey! bsd-sysctl 1.0.1 should work on openbsd with numeric oids, if you want to give it a try I'd be glad
01:18:10<gwern>dons: who, this Alexander Green?
01:19:01<FunctorSalad>isn't copumpkin more like a linear functional?
01:19:06<mux>btw, does anyone know if the hackage build bot defines some specific macro when building haddock documentation, so that I can generate docs for the whole module even if it's built on an architecture where not all functions will be available?
01:19:14<copumpkin>I feel pretty constant :/
01:19:38<gwern>mux: specific macro?
01:19:48<mux>as in cpp macro
01:21:50<FunctorSalad>a workaround would be to upload the docs for the bsd version somewhere and link from the description page..
01:22:12<gwern>dons: ok, I've sent'em an email asking about licensiong info for QIO
01:22:49<mux>FunctorSalad: I'm ready to define all the functions as error calls if there are no other solutions
01:22:52<gwern>dons: although in retrospect I should've asked about their QML as well...
01:23:12<gwern>dons: 'A functional quantum programming language implemented in Haskell.' http://fop.cs.nott.ac.uk/qml/compiler/
01:24:29<gwern>ack! qml's entire licensing info is '(c) Jonathan Grattage, 2008. jonathan.grattage@imag.fr'
01:24:36<gwern>well gee. that's helpful
01:25:07<MyCatVerbs>gwern: didn't even bother to write "all right reserved", huh? :/
01:25:37<gwern>hey now, maybe it's really under the GPL but he was too fagged by the second line
01:26:07<gwern>oh, and the haskell generated by happy? it's a managed file
01:26:11<gwern>-_-
01:26:49<dons>"a managed file"?
01:26:57<gwern>dons: ie checked into darcs
01:26:59<eivuokko>I guess version controlled.
01:27:17<gwern>presumably if the happy grammar is ever changed, he'll rerun happy and commit those changes as well...
01:27:29<SamB>gwern: one hopes!
01:27:38<gwern>I daren't check
01:27:41<SamB>sometimes people forget these things
01:28:14<eivuokko>Happy didn't used to be self-evident, so maybe it was just easier for people playing with it.
01:28:18<dons>ah, so the grammar file itself isn't included?
01:28:29<gwern>no, the grammar file is
01:28:50<gwern>it includes both the grammar file and the file happy generates from the grammar file. I just consider it to be something of a wtf
01:28:57<dons>shrug
01:28:59<gwern>one wouldn't manage the contents of dist/, for example
01:30:19<MyCatVerbs>Yeah, I'm with gwern on this one.
01:31:24<MyCatVerbs>No automatically generated file should be in your version control.
01:31:54<MyCatVerbs>For one thing, you'll get spurious changes all over the place if people have differing versions of the generator installed.
01:32:19<marcusb>haskell mode for emacs doesn't get do-if-then-else indentation right :-/
01:32:32<gwern>marcusb: yi does, fwiw
01:32:50<FunctorSalad>you need the generated file for ghci though
01:35:29<FunctorSalad>(of course that's just a question of convenience. I mean that someone getting the repo will be able to develop with ghci right away)
01:35:50<gwern>indeed. the pdf says to just load up in ghci
01:41:19<jeff_s_>does anyone have a more awesome haskell-y way to write http://pastebin.com/d5c29dfc5 ?
01:49:08<conal>hm. the "our branding sucks" haskell reddit thread got deleted (http://www.reddit.com/r/haskell/comments/8m092/why_our_branding_sucks_monads_are_okay_after_a/). anyone know why? i wrote a comment and got "that comment has been deleted".
01:49:46<copumpkin>:o
01:50:55<jeff_s_>hey! Monads are easy. it's using them properly taht's hard imo
01:51:00<jeff_s_>and/but I"m a newbie
01:51:28<aavogt>jeff_s_: use $ instead of brackets
01:51:40<jeff_s_>ok I will try taht
01:51:55<Zao>jeff_s_: getContents >>= mapM_ (print <$> toRPN . read)
01:52:11<Zao>What's a non-applicative variant of <$>, if any?
01:52:19<aavogt>liftM
01:53:21<copumpkin>Zao: `fmap`
01:53:46<copumpkin>Zao: <$> is only in the Applicative module, it actualy only relies on Functor
01:53:55<Zao>copumpkin: Using `fmap` in that context will make the compiler pissy about precedence parsing though.
01:54:02<copumpkin>true
01:54:03<monochrom>I think it was deleted because someone misread it as "why our branding sucks monads".
01:54:23<copumpkin>Zao: define your own precedence for it :P
01:54:32<Zao>Or just use <$>, as it makes sense :)
01:54:39<copumpkin>yup
01:55:02<dons>conal: i removed it only because i thought i was editorialising
01:55:24<dons>conal: but it does express what I think is a problem: the outside world sees monads as a problem, not a solution
01:55:34<dons>i.e. the branding sucks
01:55:38<conal>dons: yeah.
01:55:52<dons>the very thing that e.g. means their language is implementable simply as our library!
01:55:53<monochrom>the branding sucks monads :)
01:56:05<conal>dons: if you'll repost, i'll add my analysis & suggestion.
01:56:09<dons>will do.
01:56:24<Zao>Monads are like sucking.
01:56:25<monochrom>Phil Wadler's branding of monads is still the best to date.
01:56:47<conal>monochrom: what's is it?
01:56:54<jeff_s_>Zao - for read ghc says: Expected type Char inferred type String
01:57:05<dons>i want people to think: awesome! this thing i'm struggling with is a monad. now my life just got easier.
01:57:14<Zao>jeff_s_: Oh right, the lines.
01:57:20<Zao>jeff_s_: Had different test data :)
01:57:21<conal>dons: amen!
01:57:27<jeff_s_>I wondered where that was supposed to go
01:57:37<monochrom>"monads for functional programming" http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf
01:57:46<dons>conal: http://www.reddit.com/r/haskell/comments/8m1gj/our_branding_sucks_monads_are_okay_after_a_bit/
01:58:07<conal>dons: and similarly for other type classes. i think giving monads special attention is part of the problem.
01:58:47<conal>s/monad/Monad/
01:59:00<conal>oops. s/monads/Monad/
01:59:05<dons>agreed.
01:59:09<conal>dons: there. i just posted my comment.
01:59:12<dons>instead of presenting the wealth of abstraction power
01:59:26<dons>instead we get lost in the quicksands of IO.
01:59:33<dons>the stickiest ground to try to fight our battles on
01:59:57<conal>yeah. and we encourage people to muddle two independent powerful and relatively simple ideas.
02:00:04<conal>into one mysterious wad.
02:00:43<conal>i'd like us to be more careful with our language. for instance, i'd replace the common phrase "understanding monads" with "understanding Monad".
02:01:00<dons>oh, i really like this idea of talking about IO as a (data) type, like String
02:01:03<Zao>jeff_s_: lines <$> getContents >>= ...
02:01:10<conal>:) !
02:01:32<edwardk>dons: i.e. as a free monad of its operations?
02:01:35<conal>i think the goal of "understanding monads" is a confusion, since there are infinitely many, quite different monads.
02:01:43<dons>asa type, with operations on it.
02:01:49<MonadBaastad>conal: Or even "understanding the Monad class" - except, then you risk running into all of the baggage that goes along with the name "class"
02:02:09<jeff_s_>say typeclass instead
02:02:12<monochrom>To understand "+" you already run into typeclasses.
02:02:23<Zao>jeff_s_: Writing Haskell code is mostly a matter of ensuring that signature impedance matches.
02:02:28<monochrom>Hell, to understand "0"...
02:02:35<Zao>jeff_s_: And being overly clever so your code is unreadable after a few days :P
02:02:38<conal>yeah. "understanding Monad" or "understanding the Monad typeclass" (for verbosity).
02:02:47<dons>time for Conal's guide to monads, (and monoids, and functors, and applicatives)...
02:02:59<conal>or byorgey's!
02:03:10<dons>"The IO monad" considered harmful
02:03:14<dons>there's your title
02:03:29<conal>yes! and the quotation marks are vital.
02:03:40<MonadBaastad>dons: Better: The IO Monad - Mostly Harmless!
02:03:55<conal>the title would draw people in with one expectation (forgetting to notice the quotes), and then surprise them.
02:04:08<Zao>Monads all look the same to me.
02:04:16<dons>hehe. bait and switch :)
02:04:54<conal>edwardk: no, not the free monad. the abstract IO type.
02:05:23<marcusb>you want a beginners opinion? I have extensive CS and math backgrounds and spent a week to learn the basics of haskell, monads, monad transformers and generic programming.
02:05:35<edwardk>conal: example? or do you just mean treating it like an opaque type with just the knowledge you get from the operations allowed?
02:05:49<edwardk>i.e. that it could be secretly implemented as data IO a = GetChar (Char -> IO a) | PutChar Char (IO a) | ...
02:06:13<marcusb>I think one of the problems is that most documentation follows the historical development of the language and its focus on abstractions.
02:06:17<conal>edwardk: right. an opaque/abstract type.
02:06:35<conal>edwardk: having the semantics of IO
02:06:37<marcusb>it would have been easier if I had seen complete(!) simple examples illustrating the concepts
02:07:03<edwardk>conal: fair enough, that fits with the way i've been teaching it to folks
02:07:13<conal>edwardk: glad to hear. :)
02:07:16<marcusb>this was my issue: I understood the concept of monads early (the math is no problem for me), but I had trouble figuring out how to use the state monad
02:07:32<marcusb>until after couple of hours of reading I found out that it is just a chain of functions
02:07:37<marcusb>that was a major lightbulb
02:08:16<conal>marcusb: i think your difficulty is another example of my recommendation to separate IO from Monad.
02:08:17<marcusb>by that time I had read about 12 times that a monad has a unit and a bind interface
02:08:22<edwardk>marcusb: yeah i think monads really clicked for me by reading one of wadlers early example papers where he just defined a whole bunch of them. (even if he did get a few 'wrong' by modern parlance, i.e. bag, set, strict, etc)
02:08:29<conal>marcusb: the State *type* is simple.
02:08:51<marcusb>conal: yes, although to be fair most tutorials I read don't start with IO, but with Maybe, List, and some others
02:08:53<conal>marcusb: but trying to think about State and Monad simultaneously taxes the brain.
02:09:01<roconnor>@type GetChar
02:09:02<lambdabot>Not in scope: data constructor `GetChar'
02:09:04<roconnor>@type getChar
02:09:06<lambdabot>IO Char
02:09:08<marcusb>"you could have invented monads" is really good
02:09:24<conal>marcusb: glad to hear (Maybe, List, ...).
02:09:42<marcusb>conal: I don't know. maybe is too trivial to make the concepts clear
02:09:45<marcusb>same for lists
02:10:00<marcusb>by the time I read that, everything I did with Maybe and Lists would have worked even if they are not monads
02:10:01<conal>similarly, i'd like IO tutorials to start with examples that do not involve Monad.
02:10:04<marcusb>(at least superficially)
02:10:32<conal>marcusb: similarly, lots of IO code can be written with simpler interfaces.
02:10:37<marcusb>I still don't actually see Maybe and Lists as Monads when hacking
02:10:49<marcusb>conal: I just use WriterT [String] :)
02:11:10<conal>marcusb: did you know that list comprehensions used to be much more general? they were *monad* comprehensions.
02:11:21<marcusb>conal: no, that's new to me
02:11:29<conal>marcusb: it was beautiful!!
02:11:47<conal>part of the dumbing down of haskell. i think from 1.3 to 1.4. (or was it 1.4 to 98?)
02:12:02<marcusb>haskell has this special flare, where the language is backed by a solid theoretical framework. as a mathematician, I can appreciate that
02:12:10<marcusb>but as a hacker, it's not the first thing I am interested in
02:12:13<marcusb>not even the second
02:13:04<Zao>conal: Aren't there extensions to manlify comprehensions?
02:13:11<conal>marcusb: graphics researchers/programmers i know are that way also. they like math and they like programming, but they don't think of them as the same thing.
02:13:18<edwardk>1.4 to 98
02:13:27<marcusb>the first thing is how to solve basic problems in programming. how to handle data in various formats (unicode, binary)? how to get the same support for your own types as for built in types (generic programming)? even when not yet understanding the theory behind that
02:13:33<conal>Zao: do you mean beyond lists?
02:13:45<Zao>Aye.
02:13:53<conal>Zao: not that i know of.
02:14:10<Zao>I'm having trouble bending my head around how one of those would look though.
02:14:41<conal>anyone else know of anything like a {-# LANGUAGE MonadComprehensions #-} pragma?
02:14:45<marcusb>conal: I like how I can do both in haskell with quite some elegance. I love the do notation as much as a generic map+fold over my data types.
02:15:03<conal>Zao: check out Wadler's "Comprehending Monads" (iirc)
02:15:51<edwardk>zao: no, no one has gone back and hacked monad comprehensions back into ghc. marlow and company indicated they'd take a patch, but the sugar module where the comprehensions are parsed is particularly ugly because it has so many efficiency hacks that only work for list comprehensions, so its hard to figure out where to start.
02:16:13<conal>ack. :p
02:16:16<randomity>conal: monad comprehensions aren't really any cleaner than "do", they don't visually appear to have sequencing (which is perfect for [] but bad for many monads) and they don't support ghc's parallel list comprehensions (sort of a new syntax for zip)
02:16:39<marcusb>conal: are there experiences/studies on teaching haskell to non-programmers, and maybe even non-scientists?
02:16:48<marcusb>I wonder how that works out
02:17:03<marcusb>I can see it go either way :)
02:17:38<edwardk>randomity: you can extend monad comprehensions to cover zip comprehensions you just need a notion of Zippable functor (ala Control.Functor.Zip in category-extras)
02:17:48<IntergalacticOwl>how do you know when you're a scientist?
02:18:05<conal>marcusb: i don't know. my personal conviction is that pure (no IO) functional programming is inherently suited to right-directed thinkers/creatives. and that the textual packaging obscures that suitability. elaborated on my google tech talk on tangible functional programming.
02:18:12<marcusb>IntergalacticOwl: I was going to write non-mathematicians, and then wanted to include engineers, etc
02:18:15<randomity>as far as I know, dublin IT teaches Haskell to first-years. Not sure how long they keep it up
02:18:20<randomity>edwardk: cool! must look at.
02:18:30<Zao>conal: I was misremembering, there was a discussion a few days ago with code that at first glance looked quite non-listy.
02:18:32<IntergalacticOwl>I thought engineers didn't consider themselves scientists.
02:18:46<marcusb>conal: being free of side effects is definitely easier than understanding cell-based programming, I would think
02:19:00<monochrom>Some engineers consider themselves scientists. Some know they aren't.
02:19:07<IntergalacticOwl>haha
02:19:09<conal>some people carve up the world into engineers, scientists, etc. some don't.
02:19:24<edwardk>randomity: now, there is a lack of support for the later query comprehension improvements that SPJ and Wadler put together to respond to LINQ, that would be tricky to generalize to an arbitrary monad
02:20:05<conal>edwardk: that's why i winced at that paper. i hate seeing monad comprehensions slip further away.
02:20:05<edwardk>i remember i took a quick stab at it when the paper first came out and put it down as too scary at the time. Might take a crack at it again some time.
02:20:35<randomity>would some LINQ-style magic generalise nicely over Arrows?
02:20:51<jimmyjazz14>why are there three exponent functions in haskell?
02:21:03<monochrom>And some people compare apples with oranges.
02:21:27<edwardk>randomity: i'd hoped to employ the arrow calculus at some point for something like that but there appear to be enough problems with the rederived arrow calculus that i put it down and backed away slowly ;)
02:21:32<conal>jimmyjazz14: the answer is probably in their types.
02:21:38<conal>@type (^)
02:21:39<lambdabot>forall a b. (Integral b, Num a) => a -> b -> a
02:21:44<conal>@type (^^)
02:21:45<lambdabot>forall a b. (Integral b, Fractional a) => a -> b -> a
02:21:47<conal>@type (**)
02:21:48<lambdabot>forall a. (Floating a) => a -> a -> a
02:22:15<conal>jimmyjazz14: make sense?
02:22:25<jimmyjazz14>mmm yeah kinda
02:22:42<edwardk>arrow calculus as in: http://homepages.inf.ed.ac.uk/wadler/papers/arrows/arrows.pdf and http://homepages.inf.ed.ac.uk/wadler/papers/arrows-and-idioms/arrows-and-idioms.pdf
02:22:44<jimmyjazz14>still learning the type system
02:22:56<conal>jimmyjazz14: it's a fancy one. there's a lot to learn. :)
02:23:42<conal>jimmyjazz14: iirc, (^) raises an error for negative exponents, since the base & result are integral.
02:24:04<randomity>edwardk: yeah, the actual semantics of the arrow calculus seem giant and complicated and confusing. I've never looked at it formally properly, but the intuitive notion of "generalisation of a function" is pretty cool, and you can do some pretty cool stuff with it (signal-processing-style chains of functions or erlang-style communications)
02:24:11<gwern>if only we had Nat!
02:24:38<randomity>then (-) would break on many inputs. Is this better?
02:24:57<jimmyjazz14>I find the number types to be more confusing
02:24:57<gwern>nah, - just defaults to 0 with Nats
02:25:16<gwern>better than _|_ lurking in half the basic numerical functions
02:25:19<randomity>gwern: you're joking. Really?
02:25:37<randomity>so (a - b) + b is something totally random?
02:25:49<gwern>randomity: no, that's the usual proposal for Nats. 5-10=0
02:25:58<conal>"monus"
02:26:07<jimmyjazz14>conal: know of any good guides on easing one into the type system
02:26:18<jimmyjazz14>specifically numeric types
02:26:30<conal>jimmyjazz14: hm. not offhand. anyone else?
02:27:03<randomity>gentle introduction to haskell has a decent type system section
02:27:05<conal>jimmyjazz14 have you read "a gentle introduction to haskell" (hudak, peterson, fasel)?
02:27:08<conal>:)
02:27:10<randomity>:D
02:27:16<jimmyjazz14>no I havn't
02:27:22<jimmyjazz14>I will check it out
02:27:28<edwardk>randomity: i was originally trying to see if i could define a simple enough base language that it could for the most part 'compile' to the arrow calculus, to see if i could make a nice language with 'programmable application', with the arrow apply rules its equivalent to a monadic language but without the separate syntax barrier we have.
02:27:34<conal>it was my first exposure to haskell. i loved it. ymmv.
02:27:49<jimmyjazz14>I'm currently reading Real World Haskell
02:27:55<randomity>although when I was first learning haskell, I had to flick through that chapter initially and read the rest, then go back to it. It all makes wonderful sense eventually, and then you wonder what was so difficult at the start
02:28:31<jimmyjazz14>I like it although I find it goes a little quick at points (or perhaps needs a few rereadings)
02:28:56<randomity>edwardk: yeah, I was toying with that notion as well. I think a version of haskell where \ wasn't just lambda but was polymorphic over all arrow types would be kinda cool
02:29:16<randomity>but learning it would be even less possible than learning haskell currently :D
02:29:41<randomity>jimmyjazz14: yeah, it's great but the title's inaccurate.
02:30:30<jeff_s_>Zao - just saw your message from 10 minutes ago, thanks
02:30:32<edwardk>randomity: one thing to note: you need some extra magic for pattern matching constructors and case analysis, so getting a full haskell into it'd be a lot of work.
02:31:02<randomity>I think that can be done if the arrow in question is an ArrowChoice
02:31:23<conal>hm. my C-is-functional post is now at 117 (216-99) on reddit. i usually score *much* closer to 0.
02:31:39<randomity>you'd have to have this weird operation of reducing datatypes down to pairs and Eithers (prod + sum), but I think it could be done
02:31:43<copumpkin>sensational titles always work wonders on reddit
02:31:59<copumpkin>ACTION knows all about marketing!
02:32:03<jimmyjazz14>I feel like there should be a shorter (simpler) version of Real World Haskell as a first step intro
02:32:16<copumpkin>omg it's edwardk
02:32:41<copumpkin>edwardk: do you have a working parallel CFL parser somewhere deep in your monoids?
02:33:03<conal>copumpkin: rather a personal question, don't you think?
02:33:08<copumpkin>lol
02:34:52<randomity>conal: that looks awesome (the functional-c page)
02:35:19<randomity>actually, I think the C++ template system is purely-functional and duck-typed
02:35:27<edwardk>copumpkin: still working on it
02:35:38<conal>randomity: thx :)
02:35:43<edwardk>copumpkin: work picked up a bit for a week or so, hence why i've been scarce lately
02:36:01<edwardk>but now things are slow again, so i'm free to resume working on parsimony =)
02:36:40<edwardk>copumpkin: started adding some nice monoidal statistical accumulators though, i'll be pushing those up to hackage pretty soon.
02:36:58<edwardk>i.e. for computing mean, stddev, variance, kurtosis, skewness, etc. in parallel
02:37:27<copumpkin>edwardk: :o
02:37:29<copumpkin>nice
02:37:39<copumpkin>how about median ;)
02:38:19<copumpkin>(just kidding)
02:38:22<edwardk>i don't currently have a parallel median calculator =)
02:40:22<edwardk>there should be some monoidal encoding of kth item selection though.
02:40:35<edwardk>since there are decent parallel algorithms for it
02:43:02<dmwit>jimmyjazz14: You might also like Learn You a Haskell.
02:43:04<dmwit>?where LYAH
02:43:04<lambdabot>www.learnyouahaskell.com
02:43:11<Cale>edwardk: What counts as a monoidal encoding here?
02:43:19<edwardk>hrmm, anyone here familiar with "monoid comprehensions?" ala the monoid comphrension calculus
02:44:03<edwardk>cale: well, what i'd be looking for is an efficient way to parse part of the string and another part of the string and join the intermediate results together.
02:46:01<edwardk>cale: in the parlance of my 'monoids' library, an "a `Reducer` m" -- is a Monoid m, with unit :: a -> m -- i.e. Num a => a `Reducer` Sum a where unit = Sum
02:47:01<edwardk>cale: you can in general encode any fold as a reducer like that but its not all that interesting unless you can shrink the size of the intermediate result to be smaller than a tree involving the entire input string
02:47:28<edwardk>so some notion of progress is usually essential to encoding something as a useful Reducer.
02:50:32<Cale>Curious, I just realised that the bittorrent tracker for the anime I'm downloading is apparently edwardk.info
02:50:34<edwardk>in practice i let a Reducer also define an efficient 'cons' and 'snoc' for prepending a value or appending a value to an already reduced result, because that is often a lot more efficient than the general monoidal operation, and then let different containers use those as they see fit
02:50:47<copumpkin>:o
02:51:03<edwardk>haha, not me though.
02:51:55<Chicao>anyone familiar with qtHaskell?
02:52:13<Cale>I'm only familiar in the sense that I've heard of it.
02:53:29<Chicao>Thanks Cale
02:53:37<MonadBaastad>Wow... I read some of that Scala thread, and...the ignorance is scary.
02:53:41<Cale>Chicao: What did you need to know about it?
02:53:52<copumpkin>MonadBaastad: what thread is that?
02:54:08<rovar>MonadBaastad: I'm happy as long as all of those java coders aren't coding in java anymore.
02:54:17<Chicao>To tell you the truth
02:54:34<Chicao>i'm trying to learn it right now
02:54:51<MonadBaastad>copumpkin: http://www.reddit.com/r/programming/comments/8krbo/erlang_is_not_functional_response_to_scala_is_not/
02:54:59<Chicao>but i cant install in my computer
02:55:04<Chicao>got some errors
02:55:22<MonadBaastad>Hmm, so I guess I should call it "that Eralng response to that Scala thread"... ;p
02:56:24<rovar>how about we call them both imperative language so that all of those people afraid of functional languages will use them
02:56:29<rovar>then eventually see the light
02:56:37<rovar>to be honest. I came to Haskell by way of Erlang
02:56:58<SamB>Erlang *is* an imperative language, isn't it?
02:57:01<rovar>my preconception of functional programming was "it's cool, but not useful for real world stuff"
02:57:15<SamB>it doesn't have an imperative abstraction like Haskell does ...
02:57:21<rovar>erlang is an expression based language and supports tail recursion
02:57:24<SamB>but then neither does any other imperative language I've ever used ;-P
02:57:43<MonadBaastad>rovar: I think a better idea is to shoot 'em over to conal's blog post, so they can learn how "C programming" is really functional... 8D
02:57:48<SamB>oh, but I call CL and Scheme and Emacs Lisp imperative too
02:57:49<rovar>but you're right.. it's imperative.
02:58:02<edwardk>erlang is functional, its strict and has some baked in message passing bits, bit i can't really bash its overall functionalness
02:58:13<rovar>MonadBaastad: which is that?
02:58:18<dmwit>Hoogle has no result for "sleep"!
02:58:27<rovar>and it's dynamically typed,, which annoys the crap out of me
02:58:34<rovar>one reason i switched to haskell
02:58:41<MonadBaastad>rovar: http://conal.net/blog/posts/the-c-language-is-purely-functional/
02:59:17<rovar>"Modulo some minor historical accidents." hahaha
03:00:00<MonadBaastad>conal++
03:00:08<dmwit>Oh, it's called threadDelay.
03:00:11<dmwit>hokay
03:00:13<MonadBaastad>(If only for the lulz factor. ;)
03:00:17<Gracenotes>I like the use of "modulo" in non-mathematical sense
03:00:18<conal>MonadBaastad: :) thx.
03:00:40<Gracenotes>it's certainly acquired a life of its own. the phrase. sort of.
03:01:10<rovar>hahha
03:01:13<rovar>that is brilliant
03:01:30<edwardk>gracenotes: my coworkers sometimes look at me funny for using 'modulo', 'without loss of generality' and 'orthogonal' as just every day vocabulary.
03:01:34<MonadBaastad>conal: Thank you! I always find your posts informative and entertaining - and it's surprising at times which one is more the one than the other. ;)
03:01:52<Gracenotes>edwardk: hah! Surely all human beings speak like this???
03:02:39<edwardk>Gracenotes: it has been called to my attention that not all humans understand these things. I have since endeavored to succeed in either enlightening them, or narrowing my social circle ;)
03:03:18<Gracenotes>i am truley sorry for your lots
03:03:31<copumpkin>ACTION facepalms
03:03:58<monochrom>Haskell is the finest imperative language on Earth. That's what SPJ says.
03:04:19<rovar>edwardk: I use orthogonal quite a bit, I also use asymptote in a non mathematical sense, which really effs with people.
03:04:30<monochrom>I propose to add it to whatever "about haskell" page or blurb on the haskell wiki.
03:04:38<Gracenotes>yes, math has proved to be a fertile cornucopia of vocabulary words
03:04:48<Gracenotes>if nothing else
03:04:58<rovar>surely it has some other redeeming qualities
03:05:02<copumpkin>without loss of generality, we can speak of non-mathematical concepts with mathematical terminology
03:05:12<monochrom>"simple group" is the best math name of all. :)
03:05:33<Gracenotes>it could also be used to describe people who don't understand math terminology
03:05:39<rovar>hehe
03:05:45<Gracenotes></elitist>
03:05:50<monochrom>You should also begin inflicting law words such as "hitherto" to your coworkers.
03:05:53<randomity>or to make bad puns about a finite group of mathematicians standing in a ring
03:05:54<dmwit>So, uh, how do laziness and MVars interact?
03:06:20<rovar>randomity: if they're standing in a ring they would have to be a finite group, yes?
03:06:20<randomity>simply enough, MVars are in the IO monad where laziness doesn't really exist
03:06:25<dmwit>If I write a complicated computation into an MVar, and another thread takes that MVar, who's responsible for the expensive calculation and when did it happen?
03:06:27<Gracenotes>an MVar is like holding a reference... reading it is an operation that can be sequenced in IO
03:06:39<Gracenotes>oh, I see
03:06:55<edwardk>rovar: that and 'carrying capacity of a population,' 'kth weighted central moment', 'right Kan extension', 'comonad,' 'zygohistomorphic prepromorphism' or any 'free' construction that doesn't involve free food or free beer seem to zip right past most of these strange people.
03:07:05<monochrom>"without loss of generality, hitherto thereof we assume x>=0"
03:07:05<randomity>oh, ok. AFAIK, it's stored as a thunk in the Mvar so the receiving thread evaluates it
03:07:20<Gracenotes>I'd imagine you could put an infinite list in an MVar
03:07:30<Gracenotes>or an undefined
03:07:36<edwardk>Gracenotes: yeah
03:07:44<dmwit>Doesn't this sort of negate the usefulness of multiple threads?
03:07:58<dmwit>Maybe I should ask a different question.
03:07:59<rovar>edwardk: how could you possibly use the lot of those nonmathematically?
03:08:10<monochrom>No, the receiving thread may just give the thunk to someone else.
03:08:20<dmwit>If I want a responsive UI thread and a complicated computation thread, how should I ensure that the complicated computation is not being done in the UI thread?
03:08:28<edwardk>rovar: well, everything is a Kan extension ;)
03:08:30<randomity>most of the cool stuff from mvars doesn't come from sharing cpu across threads, but from writing sequential-looking code which overlaps
03:08:43<Saizan>dmwit: you can seq or rnf the value before you put it in the MVar
03:09:12<dmwit>Okay, as long as that's considered best practice, I'm fine with doing that.
03:09:21<Gracenotes>seq is a bit weaker than rnf
03:09:35<edwardk>rovar: and i had a use for using weighted moments around the origin in a business capacity when writing an MDX query the other day ;)
03:09:35<Saizan>well, it depends on the structure of the value
03:09:38<randomity>haskell isn't widely enough used to have a considered best practice :P
03:09:39<Gracenotes>but you do need a typeclass for rnf, which in most cases is simple to implement
03:09:56<monochrom>Heh, I store a thunk into an MVar, then I seq it, what happens? :)
03:09:59<dmwit>Yep, I understand the tradeoffs between rnf and seq.
03:10:17<kniu>Guys, I just had a crazy idea.
03:10:27<Saizan>monochrom: you get a pony
03:10:43<edwardk>monochrom: it gets put in the mvar, then you start evaluating it, if someone else grabs it they may or may not see it before your blackhole marks it depending on how eager the blackholing is that day
03:10:51<rovar>edwardk: must have been a hulluva query
03:10:54<kniu>I was reading trough SICP again, and came upon the bit about the separation of implementation from interface.
03:10:54<edwardk>so they may start evaluating it too
03:11:24<kniu>It is common knowledge that many data structures can be implemented with function closures.
03:11:39<edwardk>rovar: hah, well, 5 pages of proof to justify 3 lines of MDX ;) but its shiny and fast and it does the job
03:11:51<monochrom>Interesting.
03:12:02<kniu>Can you instance a function type with a class?
03:12:04<Gracenotes>kniu: well... more difficult with static types. But definitely
03:12:04<edwardk>kniu: s/many/any/ =)
03:12:20<kniu>If so, then why have types at all, right?
03:12:35<kniu>just create functions for every implementation, and have the classes represent types.
03:12:36<rovar>edwardk: I've always looked for excuses to do multidimensional analysis on data, but my hatred for RDBMS's has kept me away
03:12:38<edwardk>kniu: convenience
03:13:04<randomity>rovar: the RDBMS model is actually really nice. SQL is hideous.
03:13:10<kniu>So convenience is the only reason?
03:13:21<Gracenotes>implementing data structures with closures isn't so important that it's worth a trade-off with your entire type system
03:13:35<Gracenotes>imho anyway.
03:13:58<rovar>i agree.
03:13:59<Gracenotes>and quite tricky to optimize.
03:14:18<rovar>i actually went too far in that direction and started coding in Timber
03:14:32<kniu>hm
03:14:57<edwardk>i dunno. i find newtype Tree a = Tree { viewTree :: forall o. (Tree a -> a -> Tree a -> o) -> o -> o } -- to be an amusing encoding of a binary tree ;)
03:15:11<jimmyjazz14>how similar is Haskell to Erlang?
03:15:44<Saizan>ACTION doesn't see why that's hard with static types
03:15:52<edwardk>if only because if you swap the a and the first Tree a, that its in the style of.. you guessed it, a right Kan extension. ;)
03:15:54<rovar>jimmyjazz14: Haskell is a superset of erlang. Modulo the nasty bits such as dynamic typing
03:15:55<Gracenotes>edwardk: cute... hm...
03:15:56<Saizan>unless you hate the newtype constructor so much
03:16:09<randomity>they're pretty different at first. With some of Haskell's newer libraries, you can get a lot of the erlang-style communication stuff
03:16:15<Gracenotes>edwardk: what does the second parameter o represent?
03:16:21<randomity>and erlang's recently got working functional programming
03:16:27<rovar>and more importantly.. you can get sub-thread scheduling via forkIO
03:16:39<MyCatVerbs>jimmyjazz14: they're both functional. Haskell is statically typed, Erlang dynamically. They have rather different concurrency models. Concurrent Haskell is designed for SMP machines, whereas Erlang's concurrency is all message passing.
03:16:50<randomity>the main differences now are haskell having a truly awesome type system, and erlang having truly awesome clustering and failover abilities
03:17:01<rovar>oh.. and RPC
03:17:20<rovar>being the foundation of erlangs awesome clustering distributed blah blah
03:17:21<edwardk>Gracenotes: (a -> Tree a -> Tree a -> o) -- is the result from handling a Bin node and the next argument 'o' -- is the result for handling a Tip.
03:17:28<randomity>and erlang's live code updating (rewrite your app with no downtime) is amazing
03:17:39<rovar>there was a haskell project for that
03:17:42<Gracenotes>edwark: ah, so all Tips are handled the same way?
03:17:44<edwardk>the forall encodes the fact that you can extract any result type from viewing it
03:17:45<rovar>it appears to have been abandoned
03:17:50<amz>hrm, easiest way to apply "f" to "x" n times?
03:17:53<jimmyjazz14>so I am learning haskell but need to know erlang (for work and such) will learning Haskell a good path to having to work with Erlang in the future?
03:17:54<edwardk>no, thats why you need the universal quantification.
03:17:54<Gracenotes>hm. I suppose this make sense if Tip doesn't carry anything
03:18:00<edwardk>to 'case' off it you hand it two values.
03:18:06<randomity>of course, haskellers have such a cool type system that their code is proven correct by the compiler, so they don't need live code updating as there are no bugs :P
03:18:07<rovar>jimmyjazz14: yes
03:18:08<dmwit>amz: foldr (.) id (replicate n f) x
03:18:08<Gracenotes>hm...
03:18:20<SamB>randomity: yeah right
03:18:21<dmwit>amz: or maybe
03:18:23<randomity>hehehe
03:18:24<amz>dmwit: I mean as in f $ f $ f $ ... x
03:18:30<dmwit>amz: So do I.
03:18:35<amz>oh
03:18:37<amz>oh, I see, .
03:18:41<Gracenotes>edwardk: so how could you represent the typical Branch Tip 10 (Branch Tip 20 Tip) in your scheme?
03:18:46<dmwit>:t foldr
03:18:47<lambdabot>forall a b. (a -> b -> b) -> b -> [a] -> b
03:18:50<SamB>randomity: you're thinking of Agda, maybe, where your programs are proven *both* correct *and* incorrect by the compiler
03:18:51<amz>I'm trying this with a recursive function and it's stack overflowing on me
03:18:52<dmwit>:t ($)
03:18:53<lambdabot>forall a b. (a -> b) -> a -> b
03:18:54<randomity>jimmyjazz14: there are significant differences, but they're both a lot closer to each other than either is to, say, Java
03:18:59<amz>doSteps ls 0 = ls
03:18:59<amz>doSteps ls n = doSteps (map (\x -> step x 1.5) ls) (n-1)
03:19:01<dmwit>:t foldl
03:19:02<rovar>randomity: there is a lot of truth to that.. subtracting the huge potential for space leaks, I would trust haskell for a large project over any other language
03:19:02<lambdabot>forall a b. (a -> b -> a) -> a -> [b] -> a
03:19:30<edwardk>lookup b t = getTree t (\a l r -> case compare a b of LT -> lookup b l; EQ -> Just a; GT -> ...) Nothing
03:19:35<dmwit>:t foldr ($)
03:19:35<lambdabot>forall b. b -> [b -> b] -> b
03:19:40<rovar>but we've had space leaks in c++ that caused our production system to crash after 2 months of running
03:19:41<randomity>it's the first language I've used where I've felt the compiler was actually on my side (unlike, say, Python where the compiler doesn't seem to exist, or C++ where it's actively working against you)
03:19:59<copumpkin>is it just me or has a really trollish user showed up on the haskell subreddit recently, called grauenwolf? :P
03:20:01<dmwit>amz: foldr ($) x (replicate n f) -- could also work
03:20:06<kniu>really?
03:20:07<rovar>randomity: that's the fault of c++ idioms
03:20:10<rovar>idioms of idiots
03:20:11<kniu>Sometimes, I think GHC hates me.
03:20:16<dmwit>copumpkin: He's been around a while.
03:20:18<rovar>kniu: it's firm, but fair
03:20:19<SamB>randomity: yeah, in C++ it seems like the point of the compiler is to insert lots of code that I didn't write, most of which exists mostly to cause unexpected segfaults ...
03:20:26<randomity>nah, it's the fault of the C++ "type system".
03:20:30<Gracenotes>edwardk: hm. So you do you get the tree in the first place? Seems a bit.. making-something-out-of-nothing-ish :)
03:20:34<edwardk>Gracenotes: just define two combinators branch a l r = Tree (\k _ -> k a l r); tip = Tree (\_ t -> t)
03:20:41<copumpkin>dmwit: ah, I guess I only just had the pleasure of reading his comments
03:20:48<kniu>The error messages are so cryptic, it's like a chick playing hard-to-get.
03:20:56<erikc`>it's the fault of c++ users secretly wanting a good language and trying to build language features out of popsicle sticks and glue
03:20:56<MyCatVerbs>edwardk: is that a continuation-passing binary tree? :)
03:20:59<edwardk>gracenotes and then use them as smart constructors
03:21:01<Gracenotes>ah. continuation style....
03:21:03<edwardk>mycatverbs: yeah
03:21:09<rovar>the full c++ type system is pretty awesome.. if people would use it.. but people don't because it involves a crapload of <>'s and pure functional, type based programming
03:21:17<jbhatta>hmmmmmmmmm, anybody know a good algorithm for finding the median of a list of Ords?
03:21:20<SamB>kniu: which ones ?
03:21:35<randomity>templates take type parameters which are typechecked by "whether or not they support this set of named operations", and pass them onto more templates, and so on until you get a giant backtrace of why substitution failed with one type error covering pages of useless output
03:21:50<SamB>randomity: not even that, really
03:21:50<edwardk>nicely you can make up new constructors for building 'flattened' trees, etc. and the api doesn't change ;)
03:21:51<rovar>that output can be fixed
03:21:53<kniu>since I'm not really working on anything right now, there are none that I can name off the top of my head.
03:22:06<MyCatVerbs>edwardk: Why? Were you struck by a sudden urge to use Church-style data structures instead of the usual pattern matching on constructors malarkey?
03:22:13<SamB>I wish I could declare even that much typing about template parameters ...
03:22:32<edwardk>MyCatVerbs: someone above mentioned you can replace many data types with functions, and i replied s/many/any
03:22:40<edwardk>and someone asked about trees or something like that
03:22:41<monochrom>generic programming without theorem proving is really strange
03:22:42<amz>dmwit: both are still giving me a stack overflow :(
03:22:43<kniu>That's me.
03:22:45<randomity>it's more the duck typing of the templates that annoys me. Even in java I can say that I don't just want a T, I want a "T extends SomeInterface". In C++ you can't specify what type you want, the compiler just keeps bashing until enough substs fail
03:22:45<amz>even forcing strictness
03:22:59<SamB>randomity: that's just what I mean
03:23:00<monochrom>hell, aspect-oriented programming without theorem proving is strange too
03:23:04<rovar>read chapter 3 c++ metaprogramming it makes an incredibly powerful statement about the strength of the c++ type system
03:23:07<dmwit>amz: There's also iterate f x !! n
03:23:10<MyCatVerbs>edwardk: sooo... "because I can", then. Don't get me wrong, I personally believe that to be an excellent reason. :)
03:23:16<dmwit>amz: Which is probably the first thing I should have thought of. =P
03:23:16<randomity>monochrom: aspect-oriented programming is strange all by itself
03:23:36<rovar>the problem is the strong type system that you produce takes a crapload of code to get there. whereas haskell's is there from the start
03:23:40<dmwit>amz: If you're using sizes of 'n' big enough to give stack overflow, than may I suggest using something more sophisticated?
03:23:43<randomity>rovar: is this turing completeness? that's doesn't make it powerful. Brainfuck is not powerful.
03:23:45<Gracenotes>edwardk: and newtype List a = List (forall o. (a -> List a -> o) -> o -> o), sumList (List xs) = xs (\y ys -> y + sumList ys) 0
03:23:54<amz>dmwit: I'm accepting suggestions :)
03:23:56<dmwit>amz: Is f associative? If so, something similar to repeated squaring might be nice.
03:23:57<copumpkin>> (thrice thrice) (+1) $ 4
03:23:57<edwardk>MyCatVerbs: i have other reasons that i've been exploring, mostly to do with fooling the unpacker
03:23:59<lambdabot> 31
03:24:21<rovar>randomity: no.. not at all.. it creates a system whereby you can annotate values with units to ensure that they can be operated on.. i.e.
03:24:23<copumpkin>> iterate thrice (+1) $ 0
03:24:24<edwardk>Gracenotes: yeah thats a list monad as a right kan extension.
03:24:24<randomity>it's just soooo much work to define a parametrised type in C++. I need a separate template <typename T> on every single function!
03:24:25<lambdabot> Couldn't match expected type `a -> b'
03:24:29<amz>dmwit: no, it's a map that applies a "step" function to a list of objects, that return their next "step" (think of a bunch of objects in a simulation advancing in time)
03:24:41<rovar>you create 3.5 mass and 2 velocity.
03:24:43<Gracenotes>edwardk: category theory! noooooo :P
03:24:49<edwardk>Gracenotes: =)
03:24:52<MyCatVerbs>edwardk: that sounds innnteresting. More a topic for #-in-depth than here though, perhaps?
03:24:56<erikc`>rovar: f# has that and it doesnt suck in f# :)
03:24:56<rovar>you can't add them because they're not compatible.. but you can multiply them
03:24:58<randomity>rovar: oh, yeah, seen some of those. They're really nice, but they take sooooo much code to implement
03:25:03<randomity>the interface is beautiful though
03:25:03<SamB>rovar: but then it probably takes two pages of code to write what should take 1 line
03:25:08<edwardk>mycatverbs: perhaps
03:25:14<rovar>randomity, SamB: that's my point
03:25:14<randomity>there were a couple proposed for Boost, not sure if any ever got in
03:25:31<copumpkin>> iterate thrice (+1) <*> [0]
03:25:33<lambdabot> [1,3,9,27,81,243,729,2187,6561,19683,59049,177147,* Exception: stack overflow
03:25:44<SamB>99% of which is about types which you shouldn't even need to mention
03:25:52<rovar>my point is that it is possible.. the c++ type system can be great, but man is it a harsh mistress.
03:25:53<edwardk>hrmm
03:26:12<erikc`>without gc and type inferencing, it's a chore
03:26:23<rovar>and it's rather ironic that it order to utilize c
03:26:32<rovar>++ to its fullest, you need to know functional programming
03:26:40<edwardk>actually those fail to be right kan extensions
03:26:45<edwardk>just noticed that
03:26:45<randomity>ok, granted. Using C++, you can make a gorgeous interface to your types. I consider implementation simplicity just as important as interface simplicity though (I realise others don't) and I find it's rarely worth the internal ugliness of a nice C++ interface
03:26:45<rovar>hah
03:26:56<dmwit>amz: And iterate is giving stack overflow? If so, you're not doing enough forcing.
03:27:15<amz>this is my code:
03:27:16<amz>doSteps' x n = iterate f x !! n
03:27:16<amz> where f x = map (\y -> step y 1.5) x
03:27:16<MyCatVerbs>rovar: I found C++ template programming to be a great introduction to Haskell.
03:27:28<amz>I removed the seqs now
03:27:31<rovar>my friend describes c++ as coffee.. a lot of people drink coffee..it has a lot of redeeming qualities.. but the huge majority have to do crazy things to their coffee to make it halfway palletable
03:27:33<SamB>except of course that Haskell has types other than int
03:27:35<rovar>pallatable?
03:27:37<SamB>right?
03:28:35<randomity>rovar: I like black coffee :D
03:28:46<amz>I think that the problem might be with my "step" function, since my definition is recursive and very bizarre
03:28:51<amz>I couldn't figure out a better way to do it
03:29:12<Saizan>@hpaste
03:29:12<lambdabot>Haskell pastebin: http://hpaste.org/new
03:29:14<Saizan>amz ^^^
03:29:17<MyCatVerbs>rovar: once you've managed to get some not-completely-trivial computation to run in the template instantiation, switching to Haskell (where, by Church, you suddenly have actual features to play with!) feels like an enormous relief, and not any harder at all. :)
03:29:26<rovar>randomity: I take milk in mine, and I code in c++ for a living, and have maintained my sanity with the help of boost
03:29:44<MyCatVerbs>SamB: yes, Haskell has types other than int. That's a bloody good start. :)
03:29:48<amz>ok, hold on
03:30:15<amz>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5090
03:30:31<randomity>boost is amazing. It really shouldn't exist. So many really smart people have wasted so much thought designing and implementing amazing code when they could have just been popularising a better language (where the amazing feats they wished to perform were trivial)
03:30:34<amz>the idea is that I want a list of "entities", where each entity has a different behavior
03:30:39<amz>so they have different implementations of "step"
03:30:44<rovar>MyCatVerbs: I agree in general. I have been coding in c++ for 10 years and still can't get code to compile (much less run) on the 1st try.
03:30:45<amz>that move themselves to the next step
03:31:00<amz>they happen to both store a float, but that isn't really necessary, e.g. one could be storing a string
03:31:05<amz>[in fact, I should have done something like that]
03:31:08<rovar>in haskell.. it takes me some time to compile.. but once it does.. i don't even need to test it.. it just works
03:31:09<randomity>but still, boost is really, really good
03:31:23<amz>rovar: same here :)
03:31:24<rovar>randomity: yea.. a lot of smart people wasted a lot of effort on that :)
03:31:32<copumpkin>as good as possible given the shitty language it's implemented in
03:31:47<MyCatVerbs>rovar: just wait until you discover the (fix) combinator. We'll soon cure you of that little old "if it compiles, it probably works" idea. ;)
03:31:54<randomity>hehehe
03:32:02<rovar>boost.spirit.phoenix is effing *awesome* because it makes c++ functional :)
03:32:04<erikc`>randomity: amen, and a whole lot of compiler developers could have focused on things other than their frontends being accidental virtual machines
03:32:10<rovar>but boy is there a lot of crap in there
03:32:26<randomity>if it compiles in haskell, it won't produce the wrong answer. Divergence is possible.
03:32:41<SamB>randomity: unless it expresses the wrong question!
03:32:47<MonadBaastad>randomity: So, Boost is like having a crutch with a built-in rocket pack? ;p
03:32:48<copumpkin>> let addOne = (+1) in addOne 4
03:32:49<rovar>MyCatVerbs: so I just pass all of my functions in to "fix" and they're magically not broken+
03:32:50<lambdabot> 5
03:32:54<copumpkin>> let addOne = (+3) in addOne 4
03:32:56<randomity>MonadBaastad: :D :D :D oh yes.
03:32:56<lambdabot> 7
03:33:00<MyCatVerbs>rovar: quite the opposite, actually. :)
03:33:18<SamB>MonadBaastad: as in, you'll probably end up as a stain on the side of a cliff somewhere ?
03:33:24<MyCatVerbs>randomity: erk! atan2 won't magically catch your mistake if you pass it x and y backwards, causing all your angles to be calculated wrong. For example.
03:33:57<rovar>i worked on D for a while.. was very involved in working on the std libs.. again i put lots of effort into making the language into something it wasn't.. one day I gave up.. a month later I downloaded ghc
03:34:25<randomity>yeah, true. I'm just comparing my <notHaskell> code to my Haskell code. It seems difficult to write valid incorrect haskell code by accident, at least compared to other languages
03:34:39<SamB>randomity: well, yeah
03:34:46<SamB>compared to other languages
03:34:48<monochrom>Haha that's a great real story. "I was trying to design a sensible language... then I downloaded ghc."
03:35:06<SamB>at least you *probably* don't have a type error if your Haskell code all compiled ...
03:35:13<amz>Haskell looks so beautiful, I just can't figure how to do such simple stuff in it ;)
03:35:22<gwern>@remember monochrom I was trying to design a sensible language... then I downloaded ghc.
03:35:22<lambdabot>It is forever etched in my memory.
03:35:25<gwern>@flush
03:35:29<randomity>rovar: I never really got into D, it always seemed like it was suffering from the same disease C++ has. It seems to cherry-pick useful features from languages where they work well, without realising that usefullness does not combine additively
03:35:31<amz>I wonder if I'm even doing this the right way
03:36:03<jeffwheeler>amz: Haskell just takes practice and play
03:36:05<gwern>if it isn't a one-liner involving folds, ur doing it rong
03:36:08<SamB>randomity: in what sense does C++ do that ?
03:36:17<rovar>randomity: there was a laundry list of beefs with c++ which were very valid (mostly made by the boost contributors) D fixed those problems.. and made the syntax a little friendlier
03:36:50<randomity>yeah, and C++ was made by a going through a laundry list of features to add to C. I think at some point you have to redesign.
03:36:53<amz>haven't tried C#, but it looks pretty cool, except for the poor cross-platform support
03:36:57<Cale>Does D have proper functions?
03:37:03<gwern>amz: yeah, I think you're doing some of it wrong. like, I don't see the point of doDraw
03:37:17<rovar>but yea.. haskell has this grasp on the most fundamental constructs which make coding in any paradigm seem natural
03:37:30<amz>gwern: This is a design test... different objects could hypothetically have different "draws"
03:37:34<gwern>amz: eg. I don't see why you couldn't derive Show
03:37:37<amz>I should rewrite this a bit to make the purpose clearer
03:37:41<rovar>amz: D is basically a natively compiled c#
03:37:41<amz>hold on
03:37:54<gwern>amz: but isn't like, the perfect usecase for typeclasses?
03:38:14<SamB>rovar: wouldn't it make more sense to ... just compile C# natively ?
03:38:20<SamB>or better, just use C# ?
03:38:37<amz>typeclasses wouldn't work here, I need multiple different behaviors in the same list
03:38:50<rovar>Cale: D1 offers delegates, which keep their stack around so that they can be passed to other functions.. in D2, that stack is created on the heap, so that those delegates can be returned from functions
03:39:10<jmcarthur>Cale: by proper do you mean pure?
03:39:15<SamB>rovar: okay, that's a nice feature ;-)
03:39:18<randomity>by the way, what time is it for you all? I'm in Ireland, and it's 4.30 am. I intend to get up tomorrow, I know I'll be cursing #haskell...
03:39:19<Cale>jmcarthur: I mean first-class.
03:39:23<jmcarthur>ah
03:39:24<SamB>GNU C has the former but not the latter
03:39:26<Cale>Pure would be even better.
03:39:46<gwern>randomity: pushing midnight here
03:39:56<jmcarthur>you *can* make first class functions, but they are really just sugar for objects
03:40:02<Cale>rovar: Is the syntax for it nice, or something awkward?
03:40:18<SamB>randomity: apparantly I live in the same place as gwern ...
03:40:18<gwern>randomity: my fix for that sort of thing is to take a big dose of melatonin. it'll crush my mind into sleepiness so I can't help but go to bed
03:40:24<jmcarthur>Cale: actually, D seems to encourage purity a lot more than other imperative languages do
03:40:34<gwern>SamB: scary!
03:40:48<SamB>well, I mean, time-zone-wise
03:40:51<gwern>jmcarthur: indeed. doesn't it have keywords so you can tell the compiler when you are being pure?
03:41:04<jmcarthur>Cale: the delegate syntax is not anywhere near as nice as a simple lambda
03:41:11<SamB>gwern: another GNU C feature ...
03:41:11<jmcarthur>gwern: among other things
03:41:21<randomity>GNU C has an odd sort of first-class function. You can create nested functions, and you can pass them down and pass them up if they don't close over locals (basically, that which is trivial with stack frames)
03:41:25<SamB>except GNU C doesn't actually have the keywords ...
03:41:47<gwern>wonder what sort of C haskellers produce
03:41:48<randomity>gwern: oh, I'll have no problem sleeping. I'm half dead at the moment. It's just the strain of stopping irc...
03:41:51<jmcarthur>gwern: from what i've seen, it is typical to design data structures to be copy-on-write in D
03:42:07<SamB>yeah, but GNU C's nested functions don't get much use, since you never know when you're going to need a real closure ...
03:42:08<gwern>ACTION wonders whether haskell data structures are COW
03:42:26<rovar>actually... D's strings are immutable.. and are absolutely spot-on
03:42:30<gwern>wait, we don't really 'write'... hm. I guess the analogue would be sharing structure
03:42:35<randomity>well, there's no W, so COW doesn't make much sense
03:42:43<rovar>not only safer, but much more efficient than c++ or c style strings
03:42:49<jmcarthur>our "write" is "construct"
03:42:56<randomity>and sharing structure is common and usually explicit (x:z and y:z share a tail)
03:42:56<SamB>rovar: that's the same way Python does strings ;-)
03:43:04<jmcarthur>rovar: yeah, D gets strings nearly perfectly right
03:43:32<SamB>it's, like, one of 5 things python does totally right
03:43:38<gwern>is there any writeup on how d strings are so awesome?
03:43:42<SamB>ACTION doesn't have a clue what the other 4 are
03:43:45<rovar>if python were statically typed, i'd rather like it
03:43:53<randomity>rovar: there's a nice feature like that in Lua. Strings are immutable, and have a precomputed hashcode. Since the main operation is looking up a string (e.g. variable name) in a hashtable (e.g. local variable symbol table), it makes it really fast
03:43:59<SamB>rovar: that's a wierd thought
03:44:20<Saizan>amz: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5091
03:44:21<rovar>with some hindley milner type inferencing.. it could be done
03:44:37<rovar>and the syntax could remain unchanged
03:44:44<Cale>I don't understand why a language would bother to distinguish things in this funny way that D seems to have chosen with 'delegates' and 'functions'
03:44:44<gwern>I could swear I saw python type inference in haskell once...
03:44:45<Associat0r>boo
03:44:49<randomity>not really... loads of Python code relies on special names as interfaces
03:44:56<Cale>Associat0r: hello
03:45:07<Associat0r>I mean Boo Languge
03:45:07<jmcarthur>Cale: it is actually (frustratingly) common in OO languages
03:45:13<randomity>like "this function takes an object supporting these three names"
03:45:23<SamB>seems like you'd eliminate the entire point of using Python by doing HM-style type inference ...
03:45:40<rovar>boo is cool
03:45:46<rovar>i wish it weren't .net
03:46:06<Cale>How does Boo handle procedures/functions?
03:46:13<amz>Saizan: thanks, I'll take a look
03:46:13<jmcarthur>Cale: iirc, a "delegate" can be a closure, but a "function" cannot. somebody else will probably say i'm wrong though. it's been a while since i used such atrocious things
03:46:18<Associat0r>there are some other non .net python like experiments
03:46:18<randomity>hmmm, at night this channel grows fangs and turns into #anything-but-haskell. awesome.
03:46:54<amz>says that foldl' is not on scope
03:47:08<Ycros>rovar: also Cobra
03:47:13<Associat0r>yeah Cobra
03:47:20<rovar>jmcarthur: that's basically it... a delegate keeps a ptr to the stack on which it was created (e.g. a class instance) whereas a function ptr does not.. so you would make a delegate from a class method.. and a function ptr from a static method
03:47:24<Associat0r>Cale : in what way?
03:47:26<rovar>haven't looked at cobra
03:47:51<Cale>Associat0r: Well, that's sort of what we've been discussing -- how various languages handle functions/procedures.
03:47:53<Ycros>rovar: it's also inspired by Python, like boo, but supposedly better
03:47:58<rovar>also a delegate would be an inner function
03:48:05<Saizan>amz: see at the top, i've added import Data.List
03:48:10<gwern>randomity: even the #haskeller who is pure and programs aright / may chat off-topic when the conversation blossoms and the moon is bright
03:48:12<amz>ah
03:48:15<Ycros>rovar: personally I just can't wait for Python to get some nice speedups thanks to Google's unladen swallow project
03:48:37<Ycros>has anyone played with the Pure language?
03:49:04<Cale>jmcarthur: I'm not sure when you'd ever want a procedure definition *not* to close over the values of the variables that are in scope when it is defined. Is it that people think using a closure to store those values is too expensive?
03:49:28<erikc`>Cale: yes, it is
03:49:38<Cale>(We should show these people something like graph reduction ;)
03:50:00<amz>Saizan: still stack overflows for me :(
03:50:16<amz>let me paste an updated version, whose purpose should be clearer
03:50:18<Cale>erikc`: In what way?
03:50:28<randomity>gwern: *sheds a tear at the unrivalled beauty* :D
03:50:45<amz>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5092
03:50:50<erikc`>they think it's too expensive
03:51:12<Cale>It seems strange. Such a small price to pay for sanity.
03:51:39<erikc`>of course, c/c++ programmers not aware of their machine abi dont realize they've already dedicated a machine register to a pointer to a table of CAFs :P
03:51:43<erikc`>so all C functions are closures anyway
03:51:49<gwern>ACTION bows. gwern, inflicting humor on #haskell since 2007. I'll be here all week
03:51:54<erikc`>now i sound like conal :)
03:53:09<randomity>ok, now it is 5am. Goodnight #haskell, before I fall asleep on the keyboard
03:53:13<Cale>I wonder where the word 'delegate' comes from too..
03:53:13<MonadBaastad>ACTION thinks that "unladen swallow" smacks faintly of pr0n...
03:53:15<rovar>nite
03:53:25<rovar>haha
03:53:28<randomity>night
03:53:29<Cale>That seems like an awfully strange word for 'procedure'
03:54:01<dibblego>@where yaht
03:54:02<lambdabot>PDF: http://darcs.haskell.org/yaht/yaht.pdf Wikibook: http://en.wikibooks.org/wiki/Haskell/YAHT
03:54:24<erikc`>Cale: as far as i know microsoft introduced the term with .net
03:54:41<gwern>MonadBaastad: could be worse. they've could've picked tits or boobies as their bird of choice
03:55:10<MonadBaastad>gwern: Double-breasted chickadees? >;)
03:55:36<gwern>ACTION saw a fine tit the other day on wikipedia
03:55:43<Cale>erikc`: heh, it sounds like something a business person would come up with... "I'm not going to need a procedure to do this, I'll just delegate it."
03:55:59<dibblego>delegate is a C# keyword for emulating HOFs
03:56:14<gwern>DELEGATE procedure GIVING VOID
03:56:19<jmcarthur>Cale: i think it comes from OO speak. a delegate is basically an object that can be stored locally to determine how certain operations should be carried out. that is, it replaces local functionality with foreign functionality. kind of similar to a strategy
03:56:40<dibblego>@where lyah
03:56:40<lambdabot>www.learnyouahaskell.com
03:56:52<Cale>dibblego: I'm wondering about the etymology of it.
03:56:53<rovar>lyah++
03:56:54<jmcarthur>i've been running into a lot of crap with OO programming at work this week and am tired of design patterns crap though, so i'm done beyond this point
03:57:35<Cale>jmcarthur: Interesting... though I'm not sure exactly the way that sense relates to the fact that it captures the values of variables that are in scope where it's defined.
03:57:42<jmcarthur>basically, it's a fancy word for a concept that shouldn't be so fancy
03:57:52<Saizan>amz: updated with added strictness http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5093
03:58:12<jmcarthur>Cale: in implementation, C#'s and D's delegates are just objects that represent the closure with a method which invokes the "function"
03:58:28<MonadBaastad>Weird: http://en.wikipedia.org/wiki/Delegate_(.NET) looks like someone sat down and deliberately tried to make a clunky CPS system... :\
03:58:43<jmcarthur>one could say it is an abstraction leak to call it a delegate like that
03:58:57<Cale>Wait, what? Represent the closure?
03:59:09<jmcarthur>well, it *is* the closure, really
03:59:10<amz>Saizan: awesome, that works :)
03:59:15<amz>if only I knew why... :)
03:59:17<jmcarthur>it's hack
03:59:20<jmcarthur>*a hack
03:59:34<amz>but thanks a lot
03:59:34<Cale>Yeah, a closure is an implementation mechanism for a procedure, as far as my definitions go :)
03:59:38<jmcarthur>i'm not going to be able to explain it properly
03:59:39<amz>I'll study this black magic
03:59:46<Cale>But maybe I see what you mean
04:00:05<Saizan>amz: well, the point is to not construct huge thunks of strict functions, but evaluate the application of each function step by step
04:00:19<Cale>You have an object with a method for the code, and instance variables for the captured variables?
04:00:57<Saizan>amz: it's the same concept of foldl (+) 0 vs. foldl' (+) 0
04:01:07<Saizan>@wiki Stack Overflow
04:01:07<lambdabot>http://www.haskell.org/haskellwiki/Stack_Overflow
04:01:30<Saizan>http://www.haskell.org/haskellwiki/Stack_overflow <- actually
04:01:32<amz>this is still way above my level, I can barely code anything in Haskell, but I'll try to decypher it
04:01:36<Gracenotes>sans the capital o
04:01:43<Gracenotes>wiki titles are case sensitive... yeah you got it :)
04:01:52<Gracenotes>except for the first letter
04:02:13<jmcarthur>Cale: "Delegates to non-static nested functions contain two pieces of data: the pointer to the stack frame of the lexically enclosing function (called the frame pointer) and the address of the function. This is analogous to struct/class non-static member function delegates consisting of a this pointer and the address of the member function. Both forms of delegates are interchangeable, and are actually the same type"
04:02:45<Cale>okay
04:03:05<Cale>That's pretty much a closure, yeah.
04:03:25<jmcarthur>"A function pointer can point to a static nested function" ... "A delegate can be set to a non-static nested function"
04:05:21<erikc`>and since a non-static function is just a function with a hidden this parameter...they are the same thing :P
04:05:41<jmcarthur>D even has explicit lazy evaluation
04:06:18<erikc`>yea
04:06:43<erikc`>those features fall out naturally once you give in to garbage collection + heap allocation of stack frames :)
04:06:58<jmcarthur>yeah, but most imperative languages ignore such obvious ideas
04:07:21<jmcarthur>and D does not mandate garbage collection, either
04:07:28<jmcarthur>it can be manual, if you wish
04:08:29<erikc`>so you need to manually free your closures i guess
04:08:32<mmorrow_>D heap-allocates stack frames? does it have real callcc?
04:10:14<jmcarthur>you could probably do it with delegates, although i don't know whether it will optimize tail calls or just confuse the garbage collector or whatever
04:10:39<mmorrow_>ah, hmm
04:11:22<mmorrow_>so i guess you don't have access to the stack frames as if they were "just some closure" or something
04:12:09<Associat0r>anyone seen http://delight.sourceforge.net/ ?
04:12:50<jmcarthur>you can even get raw pointers to the stack frames if you want, i think
04:13:32<jmcarthur>but even without that, i think the closures are true closures... just hackish because it's done in OO-speak
04:13:50<mmorrow_>hmm, cool. i guess the only question then is whether stack frames are deallocated after a function returns unconditionally, or if they're gc'ed only if there're no live ptrs to them
04:13:57<jmcarthur>right
04:14:53<jmcarthur>i suspect it is the latter
04:15:00<Associat0r>http://www.bitc-lang.org/ does closures on the stack too without GC
04:15:06<mmorrow_>ACTION is reading http://www.digitalmars.com/d/2.0/memory.html
04:38:22<travisbrady>how can i do patterns in a case statement with ByteStrings? ala 'case x of "A" -> print "hey" "B" -> print "no"'
04:42:05<codebliss>@i getFile
04:42:05<lambdabot>Maybe you meant: id ignore index instances instances-importing irc-connect . ? @ v
04:42:19<codebliss>@src getFile
04:42:20<lambdabot>Source not found. The more you drive -- the dumber you get.
04:42:32<codebliss>@t getFile
04:42:33<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
04:42:47<codebliss>How does lambdabot do :t? XD
04:43:33<codebliss>Oh, it's readFile...
04:45:54<jimmyjazz14>is there a !! counterpart that works with Integer types?
04:48:01<Saizan>genericIndex
04:50:03<jimmyjazz14>thanks
04:51:22<dmwit>Yes! I now have what is essentially a very, very complicated way to draw a line across the screen. =P
05:03:08<amckinley>would anyone like to help me write a small chunk of the parser im working on? :)
05:18:20<A1kmm>Hey, has anyone managed to get uvector working with trunk?
05:18:26<A1kmm>(version of ghc)
05:20:23<dmwit>amckinley: hpaste.org, maybe?
05:22:55<amckinley>dmwit: actually ive got to run; hopefully ill be back later :) thanks though
05:29:25<A1kmm>Does anyone know what the following error message (from the latest darcs version of ghc): Data/Array/Vector/Prim/BUArr.hs:89:0:
05:29:27<A1kmm> Failed to load interface for `GHC.Prim':
05:30:05<A1kmm>Isn't GHC.Prim part of the wired-in ghc-prim package?
05:30:21<thoughtpolice>A1kmm: in ./ghc/libraries/ghc-prim/ghc-prim.cabal, you can see GHC.Prim is hidden by default with a flag
05:30:49<A1kmm>Ah... so packages need to explicitly enable it?
05:31:14<thoughtpolice>not sure
05:31:28<thoughtpolice>i would think there was a patch introduced which hides GHC.Prim by default
05:31:33<thoughtpolice>which isn't in the 6.10 branch
05:33:34<solrize_>@seen lemmih
05:33:35<lambdabot>lemmih is in #haskell. I don't know when lemmih last spoke.
05:33:41<solrize_>lemmih ?
05:34:13<solrize_>@seen thoughtpolice
05:34:13<lambdabot>thoughtpolice is in #haskell-blah, #haskell-in-depth, #ghc and #haskell. I last heard thoughtpolice speak 2m 40s ago.
05:34:23<solrize_>thoughtpolice ?
05:34:36<dmwit>You are SOL tonight.
05:34:40<solrize_>heh
05:34:44<solrize_>i had a dumb question about lhc
05:34:52<A1kmm>thoughpolice: flag include-ghc-prim {
05:34:54<A1kmm> Description: Include GHC.Prim in exposed-modules
05:34:56<A1kmm> default: False
05:34:57<A1kmm>}
05:35:37<Lemmih>solrize_: ?
05:36:44<Lemmih>GHC.Prim doesn't exist. It's only generated for documentation purposes.
05:36:47<solrize_>lemmih, yeah, i was wondering if lhc uses the same dictionary avoiding typeclass scheme as lhc
05:36:58<solrize_>i remember asking something about this before
05:37:06<solrize_>oops "same as ... jhc"
05:37:23<thoughtpolice>solrize_: ?
05:37:27<Lemmih>solrize_: Yes and no.
05:37:31<dmwit>Typeclasses without dictionaries, eh?
05:37:32<solrize_>'cause i remember that the jhc blurb explained that as why it used a fancy type system in its intermediate lang
05:37:35<solrize_>dmwit, yeah
05:37:39<A1kmm>Lemmih: uvector uses it, but it won't compile for trunk ghc.
05:37:52<solrize_>and ghc core's type system doesn't have the high powered capabilities
05:38:00<RyanT5000>is there a policy about advertising Haskell jobs in this chatroom?
05:38:03<Lemmih>solrize_: We use normal dictionaries but we can optimize them away.
05:38:21<Lemmih>solrize_: JHC takes a different approach and doesn't create the dictionaries in the first place.
05:38:26<Lemmih>solrize_: The end result is the same.
05:38:29<solrize_>hmm
05:38:31<solrize_>cool
05:38:41<dmwit>RyanT5000: It seems fine to me, though I'm not in any position of authority. You'll almost certainly get better response from haskell-cafe, though.
05:39:24<RyanT5000>dmwit: ah, that's a good point; i'll send something to that at some point
05:39:36<Lemmih>solrize_: Our approach requires a bit more CPU time but it is easier to work with. We had lots of trouble getting the dictionaries to work correctly in JHC.
05:39:44<RyanT5000>on the basis of that non-authoritative response, i'm going to go ahead and say it :P
05:39:52<solrize_>ryant5000 i think it's ok, since there are so few. putting it at -cafe will probably get it into HWN which is very visible
05:40:02<solrize_>ryant5000 :)
05:40:04<RyanT5000>solrize_: yeah, that's a good point
05:40:41<RyanT5000>i'm starting a game studio writing in haskell; email me at ryant5000@gmail.com if you're interested
05:41:14<solrize_>lemmih, interesting. i never understood that angle of jhc. but since you have the whole program right there it seems natural that you can specialize every function
05:41:25<dmwit>Whoa; have you got a game in mind already?
05:41:31<solrize_>game studio?!!! yow
05:41:31<RyanT5000>dmwit: yeah
05:41:38<dmwit>?yow!
05:41:38<lambdabot>You mean you don't want to watch WRESTLING from ATLANTA?
05:41:43<RyanT5000>solrize_: yep :)
05:41:48<solrize_>dmwit hee
05:41:53<RyanT5000>it'll be tough
05:42:06<RyanT5000>and i imagine we'll end up contributing to GHC quite a bit if we manage to survive
05:42:14<solrize_>ryant5000 did you ever see tim sweeney's presentation about game dev. languages?
05:42:19<RyanT5000>but i think it has a lot of potential - and Tim Sweeney backs me up
05:42:25<solrize_>hehe jinx
05:42:25<RyanT5000>solrize_: yup :)
05:42:29<RyanT5000>lol
05:42:32<Lemmih>A1kmm: Oh, sorry, I misunderstood. I don't know what the problem is.
05:42:41<dmwit>So you're going for the high-end games, then? (Not casual games.)
05:43:07<solrize_>you gonna program GPU's with haskell ?
05:43:18<solrize_>(the answer must be yes, haskell can do that)
05:43:23<RyanT5000>we're looking into everything
05:43:32<RyanT5000>porting to weird platforms or chips is a core part of our strategy
05:43:51<RyanT5000>(another core part is this chatroom and all the untapped talent it represents)
05:44:15<RyanT5000>(in my opinion, there's not enough demand for Haskell programmers)
05:44:22<solrize_>i've felt like haskell needs an internal low level DSL for micro-optimizing cpu intensive functions
05:44:42<dmwit>Harpy?
05:44:43<twb>Does GHC 6.10.3 include haskeline? That's what Debian seems to think.
05:44:51<solrize_>harpy = assembler, not what i had in mind :)
05:44:54<RyanT5000>twb: release notes say yes
05:45:03<Ycros>RyanT5000: are you starting a real game dev studio, ie. a business, or just like an indie one
05:45:31<RyanT5000>Ycros: it's a real game dev studio, although it won't be developing mainstream PC or big-box console titles (at least not in the short-term)
05:45:47<twb>RyanT5000: thanks.
05:45:54<RyanT5000>twb: np
05:46:07<RyanT5000>Ycros: we haven't totally worked out financing yet - in particular because the availability of Haskell talent is more or less an unknown quantity right now
05:46:11<solrize_>lemmih are you generating asm code or C?
05:46:51<Ycros>RyanT5000: financing is the important part :P
05:47:03<Ycros>RyanT5000: where are you located?
05:47:07<RyanT5000>i have a feeling that Haskell programmers are self-selected in interesting and useful ways, and that Haskell itself has a lot of potential (again, in line with Tim Sweeney's presentation), but it's hard to go to VC or other financing with just a gut feeling
05:47:33<RyanT5000>Ycros: you're right, financing is a huge deal; we have some - enough to possibly get one game out the door
05:47:39<solrize_>ryant5000, an anecdote, skydeck (company writing some kind of telecom related software in ocaml) used to advertise for python(?) programmers because they didn't want to scare people by mentioning ocaml. but once word got out they were actually using ocaml, the way i heard it, tons of fp nerds all wanted to work there.
05:47:44<RyanT5000>Ycros: we're in Boston, Massachusetts
05:48:05<RyanT5000>solrize_: huh, that's interesting
05:48:18<Ycros>RyanT5000: ah well, way too far away for me anyway :P
05:48:23<Lemmih>solrize_: Neither. Right now we're interpreting GRIN code. An LLVM backend will be added soonish.
05:48:55<RyanT5000>Ycros: ah, that's too bad
05:49:09<solrize_>hmm, i guess you've done CPS conversion already, so no issue with LVM not compiling tail recursion away
05:49:37<RyanT5000>Ycros: you sound like you have some experience with startups; is that the case?
05:50:48<Ycros>RyanT5000: Not really, but I hang around people who do the startup thing, I've also started a business some months ago and might be starting another soon :P
05:50:49<solrize_>ACTION worked at a game startup but am not enough of a haskell expert to qualify for a haskell startup and anyway already has a job :)
05:50:58<Lemmih>solrize_: We /will/ depend on llvm optimising tail recursive calls.
05:51:10<RyanT5000>Ycros: sounds good
05:51:15<solrize_>lemmih hmm they have fixed that (or will fix it)?
05:52:03<solrize_>lemmih can you add a compiler flag that makes Int arithmetic check for overflow and raise an exception?
05:52:20<RyanT5000>alright, well, i've got to head off, but if anyone's interested - or knows anyone who might be interested - in writing games in Haskell, my email is ryant5000@gmail.com
05:52:43<solrize_>ryant5000 i'm sure you'll get takers. there are already some haskell games including a FPS
05:52:43<Lemmih>solrize_: I don't see why not.
05:53:02<solrize_>lemmih cool, i think that would catch some bugs
05:53:27<solrize_>are you going to be able to use the existing ghc runtime for stuff like gc?
05:54:10<solrize_>is there much of a haskell->llvm interface currently?
05:54:51<solrize_>oh haha, i'm looking at the llvm release notes and it says they now support int overflow traps
06:11:20<halberd>what does it mean in type theory when they say "primitive non-canonical constant"? example: apply is the primitive non-canonical constant for the Pi-set
06:12:17<lispy>halberd: I can honestly say, I'm not sure
06:12:33<dmwit>helpful
06:25:40<halberd>I guess the canonical constants for a set are the constructors, and primitive simply means defined, so a primitive non-canonical constant would just be a defined constant that is not a constructor
06:27:34<halberd>and that operates on elements of the set
06:37:04<cads>hey, how's bsd for haskell?
06:39:35<MyCatVerbs>OpenBSD's fine. I haven't tried any of the others myself.
06:39:47<MyCatVerbs>I think FreeBSD's good too, but I couldn't tell you for certain.
06:46:16<cads>does openbsd come with a useable desktop configuration?
06:54:07<MyCatVerbs>cads: blowed if I can remember, but it does have a Hell of a good FAQ.
06:57:26<cads>MyCatVerbs: it seems very secure
06:57:48<MyCatVerbs>Well, they're almost paranoid enough. ^_^
07:03:00<lpjhjdh>so the haskell98 standard says "uniSymbol -> any Unicode symbol or punctuation" is there a more concrete definition of "any"?
07:03:44<dmwit>:t isSymbol
07:03:45<lambdabot>Char -> Bool
07:03:49<dmwit>:t isPunctuation
07:03:51<lambdabot>Char -> Bool
07:04:11<dmwit>> filter (liftM2 (||) isSymbol isPunctuation) ['\0'..]
07:04:12<lambdabot> "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\161\162\163\164\165\166\167\168\169\171...
07:04:46<dmwit>Depending on where this is used, that may or may not be correct.
07:05:03<lpjhjdh>I see, thanks.
07:05:08<dmwit>As you can see, some things like ", (, ) are in there.
07:05:50<dmwit>@, \, [, ], {, }, |, and ~ are also special...
07:05:50<lambdabot>Maybe you meant: . ? @ v
07:06:44<MyCatVerbs>dmwit: ~?
07:07:02<MyCatVerbs>I can't remember anywhere in Haskell's grammar where ~ is used?
07:07:03<lpjhjdh>hmm, so essentially anything not reserved?
07:07:20<dmwit>MyCatVerbs: lazy patterns
07:07:20<ivanm>@src partition
07:07:21<lambdabot>partition p xs = foldr (select p) ([],[]) xs
07:07:21<lambdabot> where select p x ~(ts,fs) | p x = (x:ts,fs)
07:07:21<lambdabot> | otherwise = (ts, x:fs)
07:07:24<ivanm>MyCatVerbs: ^^
07:07:36<ivanm>so it's not undefined
07:07:36<MyCatVerbs>dmwit: oh yes! I am full of forgetfullness and no caffeine.
07:07:54<lpjhjdh>@hoogle isSymbol
07:07:54<lambdabot>Data.Char isSymbol :: Char -> Bool
07:11:23<solrize_>does 6.8.2 not have data.binary? should i upgrade to what is it now, 6.10.3?
07:14:07<lpjhjdh>@hoogle alexGetChar
07:14:07<lambdabot>No results found
07:23:01<PetRat>I'm trying to understand the expression "join (*) 5". Apparently this has to do with the monad ((->) e).
07:23:27<PetRat>(*) :: Int -> Int -> Int
07:23:53<dmwit>yep
07:23:59<dmwit>:t join
07:24:00<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
07:24:18<PetRat>Apparently (*) is a monad and so is (5 *)?
07:24:22<dmwit>So, in the case of the (e ->) monad, join :: (e -> e -> a) -> (e -> a)
07:25:10<dmwit>i.e. given a function that expects two environments, return a function that takes only one environment and supplies two copies of it to the passed-in function.
07:25:28<dmwit>So (join (*)) is a function that takes one argument and puts it on both sides of the multiplication.
07:25:35<dmwit>join (*) 5 = 5 * 5
07:25:44<PetRat>I am still trying to work that out from my understanding of the definitions.
07:25:56<dmwit>?src join
07:25:56<lambdabot>join x = x >>= id
07:26:04<PetRat>join = do y <- x; v <- y; return v
07:26:12<dmwit>right
07:26:18<PetRat>what is x?
07:26:30<dmwit>uh
07:26:31<shachaf>join x = ...
07:26:32<dmwit>I think that's
07:26:34<dmwit>join x = ...
07:26:35<dmwit>yeah
07:26:40<shachaf>PetRat: Isn't that redundant, though?
07:26:46<shachaf>join x = do y <- x; y
07:27:05<dmwit>Damn, shachaf is fast. I was about to suggest that, too, but can't type nearly as quickly. =P
07:27:11<shachaf>PetRat: My advice: Look at the types instead of the implementations. At least at first.
07:27:35<shachaf>PetRat: They're simpler, and there's one obvious implementation for each.
07:27:38<PetRat>So join (*) = do y <- (*) ; y
07:27:42<shachaf>@src (->) >>=
07:27:42<lambdabot>Source not found.
07:27:47<shachaf>@src (->) (>>=)
07:27:48<lambdabot>f >>= k = \ r -> k (f r) r
07:27:49<PetRat>shachaf: I'm trying to do both.
07:28:14<shachaf>PetRat: Another bit of advice: Think of it in terms of join/fmap/return instead of (>>=)/return. :-)
07:28:50<dmwit>f >>= k = \r -> k (f r) r
07:28:57<dmwit>f >>= id = \r -> id (f r) r
07:29:03<PetRat>I'm looking at an exercise to define >>= in terms of fmap and join. Thinking about trying to do that. I just want to understand join (*) 5
07:29:04<dmwit>f >>= id = \r -> (f r) r
07:29:10<dmwit>f >>= id = \r -> f r r
07:29:16<Gracenotes>but nonetheless, >>= does make for some spiffy one-liners
07:29:18<dmwit>join f = f >>= id = \r -> f r r
07:29:37<dmwit>ACTION stops flooding
07:30:22<shachaf>PetRat: OK, those are two separate exercises.
07:30:36<shachaf>PetRat: As I said before, look at the types.
07:30:38<shachaf>@ty join
07:30:39<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
07:30:41<shachaf>@ty fmap
07:30:42<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
07:30:44<shachaf>@ty (>>=)
07:30:45<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
07:31:02<PetRat>Last night I worked out x >>= f = \e -> f (x e) e
07:31:29<dmwit>PetRat: Nice!
07:31:32<PetRat>join :: m (m a) -> m a
07:32:22<PetRat>so m (m a) is e -> (e -> a) ?
07:32:27<dmwit>Right.
07:32:37<PetRat>m a is e -> a
07:32:43<dmwit>Spot on.
07:32:58<shachaf>@ty flip (>>=) -- Hint: fmap is similar to flip (>>=).
07:32:58<lambdabot>forall (m :: * -> *) a b. (Monad m) => (a -> m b) -> m a -> m b
07:33:10<shachaf>(Now that I think about it, that isn't a very helpful hint. Ignore me. :-) )
07:33:49<PetRat>so join takes a function of two arguments and changes to a function of one argument. The specific implementation does that by supplying the one argument twice. I guess there's nothing else you CAN do, if you have only one argument for a function of two arguments. (Nothing else useful.)
07:33:54<zakwilson>I'm using a Mac for a few days. Is Fink or Darwinports a sane way to get GHC and the like?
07:34:05<dmwit>PetRat: exactly
07:34:52<shachaf>PetRat: You'll find that it's that way with just about all the (r ->) functions.
07:34:56<shachaf>For example:
07:34:57<shachaf>@ty return
07:34:58<lambdabot>forall a (m :: * -> *). (Monad m) => a -> m a
07:35:21<shachaf>a -> m a = a -> (r -> a)
07:35:32<shachaf>What's the most obvious way of accomplishing that? :-)
07:35:43<PetRat>I want to understand the implementation, though. join x = do y <- x; y. how is this expressed with >>=?
07:36:02<shachaf>PetRat: do is syntax sugar for >>=, remember.
07:36:05<PetRat>shachaf: \_ -> a?
07:36:11<shachaf>PetRat: Yep.
07:36:17<shachaf>Or rather, \a _ -> a
07:36:32<dmwit>?undo \x -> do { y <- x; y }
07:36:32<lambdabot>\ x -> x >>= \ y -> y
07:36:43<dmwit>The latter is just fancy notation for id.
07:36:46<dmwit>\x -> x >>= id
07:37:01<dmwit>You'll note the similarity to the Prelude:
07:37:03<dmwit>?src join
07:37:04<lambdabot>join x = x >>= id
07:37:04<dmwit>;-)
07:37:33<shachaf>@. pl undo join x = do { y <- x; y }
07:37:34<lambdabot>join = join
07:37:38<shachaf>Er, yes.
07:37:46<dmwit>hehehe
07:37:47<PetRat>join x = x >>= id ?
07:39:41<shachaf>PetRat: For any monad, yes. That's the Prelude's definition.
07:39:57<shachaf>You might find it clearer to start with join and fmap, though. :-)
07:40:09<kau>hello! Can you give me some pointers on "if then else" being desugared to arrowChoice?
07:40:49<kau>can't find it on google :(
07:41:35<dmwit>Have you looked at the papers on proc notation?
07:41:41<kau>no
07:41:43<dmwit>That's where I'd expect the details to be.
07:41:43<PetRat>okay so \e -> f (x e) e ==> \e -> id (e *) e ===> (e *) e ===> e * e
07:41:55<kau>i dont know proc notation ;)
07:42:24<kau>it's for defining new keywords?
07:42:33<dmwit>Uh, no, it's for using Arrows.
07:42:55<dmwit>It's a bit like do notation, but for Arrows, not Monads.
07:43:00<dmwit>And not as good as Wadler's notation. =)
07:43:17<dmwit>The Haskell wiki page on arrows should have links to papers about it.
07:44:27<kau>ok thanks i'll have a look
07:44:51<Saizan>the ghc manual also has it
07:45:28<Saizan>?type (|||)
07:45:29<lambdabot>forall (a :: * -> * -> *) b d c. (ArrowChoice a) => a b d -> a c d -> a (Either b c) d
07:45:56<Saizan>?type constA
07:45:57<lambdabot>Not in scope: `constA'
07:46:52<PetRat>So >>= implemented in terms of fmap and join. I think it's x >>= f = join $ fmap f x
07:47:39<Saizan>let constA a = arr (const a) in \t f -> arr (\x -> if x then Left () else Right ()) >>> (constA t ||| constA f)
07:47:46<Saizan>PetRat: right
07:47:56<shachaf>@ty \f m -> join (fmap f m) -- Yep.
07:47:57<lambdabot>forall a (m :: * -> *) a1. (Monad m, Functor m) => (a -> m a1) -> m a -> m a1
07:47:59<shachaf>Well, flipped, anyway.
07:49:20<PetRat>It's amazing to me that you can work out that definition by "following the types", as though you are ignoring implementation. But I guess the idea is that when any particular monad is implemented, the implementor follows the types and the monad laws, which is what guarantees my simple definition will always work. Is it something like that?
07:50:10<shachaf>PetRat: Yep. That's the whole point of having a Monad class.
07:50:19<Cale>PetRat: There are often not that many possibilities for implementation of a highly polymorphic type.
07:50:30<dmwit>Actually, in a lot of cases, you can prove rigorously that all truly polymorphic implementations that matches a particular type will be identical.
07:50:43<dmwit>s/matches/match/
07:52:42<Cale>As another example, consider the type (a -> b) -> [a] -> [b], the type of map. What functions have this type? Well, it's not just map, but we can say that every other function which has that type produces a list consisting of elements produced by passing elements of the given list to the given function.
07:53:17<Cale>This makes it really hard to mess up your implementation and still get the type to match. You basically have to be trying.
07:53:53<Cale>Often the implementation with the nicest properties, the one you really want, will also be the simplest one as well.
07:54:31<PetRat>Cale: what if you implement map' f xs = [f (head xs)] . Is that "trying to mess it up?"
07:55:44<dmwit>Yep, about the best you can say is that the behavior of a function matching that type will depend only on the length of the list.
07:55:56<dmwit>However, there's still a lot you can make rigorous.
07:55:56<Cale>Well, I suppose it's possible that you're not trying to mess up there if you actually don't know the language very well.
07:56:12<Cale>dmwit: And the permutation of the elements given.
07:56:20<Cale>(and duplicates)
07:56:22<dmwit>Cale: No, it can't depend on that.
07:56:27<dmwit>Not at that type.
07:56:43<Cale>oh, I see what you're saying
07:56:45<PetRat>Cale: I mean "trying" more in the sense of, failing to observe basic principles.
07:57:16<solrize_>map' f xs = []
07:57:21<solrize_>doesn't depend on length xs :)
07:57:24<Cale>dmwit: I accidentally misinterpreted which list you were talking about
07:57:34<dmwit>solrize_: Sure it does.
07:57:48<dmwit>solrize_: In fact, it doesn't depend on anything *but* the length of xs.
07:57:48<MyCatVerbs>solrize_: is too polymorphic, has type a -> b -> [c].
07:58:03<solrize_>hmm ok
07:58:03<Cale>dmwit: It gives the same result regardless of xs though...
07:58:06<MyCatVerbs>forall a b c., even.
07:58:19<dmwit>Cale: Yep, I know.
07:58:43<dmwit>solrize_: Or, another way to put it is: saying that a thing depends "only on the length of the list" does not imply that it definitely does depend on the length of the list.
07:58:45<Cale>So that one doesn't even depend on the length of xs, it depends on nothing...
07:59:15<PetRat>There's a term like the "most general type"... something about the most general type that is not too general.
07:59:18<dmwit>solrize_: So the behavior of map' depends only on the length of the list... and not even on that. =)
07:59:25<dmwit>PetRat: "principal"
08:00:35<PetRat>Beginners often think that foldr :: (a -> a -> a) -> a -> [a]
08:00:56<dmwit>Maybe you meant (a -> a -> a) -> [a] -> a?
08:01:12<Cale>Or (a -> a -> a) -> a -> [a] -> a
08:01:12<dmwit>:t buildr
08:01:13<lambdabot>Not in scope: `buildr'
08:01:20<PetRat>Cale : you said it
08:01:42<PetRat>but it is actually something like (b -> a -> b) -> b -> [a] -> b
08:02:04<Cale>(a -> b -> b) -> b -> [a] -> b
08:02:14<Cale>(similar)
08:02:35<dmwit>:t foldl -- maybe what PetRat was thinking of
08:02:36<lambdabot>forall a b. (a -> b -> a) -> a -> [b] -> a
08:02:41<PetRat>Oh I see. Yes I tr to think of the supplied "starting" value as going on the right, for foldr
08:03:23<Cale>For foldr f z, it's best to think of f as a replacement for (:) and z as a replacement for []
08:03:39<PetRat>dmwit: I was thinking of foldr but just forgetting that the supplied value "goes on the right" of the operator.
08:04:02<Cale>PetRat: Have you seen my diagrams?
08:04:11<PetRat>Stupid mibbit changes all (:) to smileys.
08:04:11<Cale>http://cale.yi.org/index.php/Fold_Diagrams
08:04:36<PetRat>Cale: I got 404 error on that link.
08:04:36<Cale>Does it change (:[]) into a robot monkey?
08:04:42<Cale>hmm
08:05:17<Cale>99.247.248.73
08:05:34<Cale>oh
08:05:38<Cale>I might know
08:05:46<Cale>Maybe the router switched us around again :P
08:05:58<PetRat>Cale: I saw the diagrams on the Wikipedia page.
08:06:09<ivanm>Cale: a windows message? :s
08:06:41<ivanm>I take it that's you singing/playing rather than providing illegal music for the RIAA to find?
08:07:41<Cale_>There we are. Any better?
08:09:02<ivanm>awww.... there's no oops message anymore :(
08:09:16<Cale>heh, that was from my dad's computer, I think
08:10:19<ivanm>it's not just that you've been gaming?
08:11:07<PetRat>Nice diagrams.
08:11:39<Cale>Nope, my machine doesn't have windows on it.
08:12:53<Cale>PetRat: actually, I did make the diagrams on Wikipedia as well
08:12:54<FunctorSalad_>how is scanr formed?
08:13:06<Cale>@src scanr
08:13:07<lambdabot>scanr _ q0 [] = [q0]
08:13:07<lambdabot>scanr f q0 (x:xs) = f x q : qs
08:13:07<lambdabot> where qs@(q:_) = scanr f q0 xs
08:13:41<FunctorSalad_>hmm it just yields all the intermediate values of the foldr?
08:13:47<ivanm>yup
08:13:58<Cale>yeah, starting with the whole thing
08:14:08<Cale>> scanr (+) 0 [1,2,3,4,5]
08:14:10<lambdabot> [15,14,12,9,5,0]
08:14:32<Cale>> scanr (+) 0 [1,10,100,1000,10000]
08:14:34<lambdabot> [11111,11110,11100,11000,10000,0]
08:15:04<Cale>> scanr f z [1,2,3,4,5]
08:15:06<lambdabot> [f 1 (f 2 (f 3 (f 4 (f 5 z)))),f 2 (f 3 (f 4 (f 5 z))),f 3 (f 4 (f 5 z)),f ...
08:15:39<dmwit>It is one of the mysteries of laziness that foldr is preferable to foldl, but scanl is preferable to scanr.
08:16:05<dmwit>They say the even the initiate must ponder this each time, before he recalls why.
08:16:07<FunctorSalad_>except where foldl' is preferable? :)
08:16:27<dmwit>Well, of course. ;-)
08:16:45<dmwit>But this temple is strictly lazy.
08:17:03<Cale>> map (take 5) . scanr (:) [] $ [1..]
08:17:05<lambdabot> [[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9],[6,7,8,9,10],[...
08:17:54<Cale>Sometimes even scanr is nice :)
08:18:19<PetRat>dmwit: I've noticed that anything I "learned" today will probably be mysterious tomorrow. Certain exercises I've worked about four or five times now and I still have to ponder it.
08:18:33<dmwit>PetRat: It's normal, don't worry.
08:18:35<PetRat>Eventually will be second nature, though.
08:18:46<dmwit>After 40 or 50 times, you'll only think briefly.
08:18:57<Cale>> foldl (flip (:)) [] [1,2,3,4,5]
08:18:59<lambdabot> [5,4,3,2,1]
08:19:00<dmwit>And next year, you'll wonder what was so mysterious. =)
08:19:38<Cale>I think the diagram sort of makes clear why scanl is nice compared to foldl
08:20:04<PetRat>dmwit: That's the sense I get. This stuff fits together naturally. It only seems difficult to the imperative programmer because one has to go back to a very early stage of development. We forget how much work it took before imperative programming was second nature.
08:20:39<dmwit>One of those Google guys has a nice essay called "Learn Programming in Seven Years" that rants against the "Learn Programming in Seven Days" series of books.
08:20:46<dmwit>Norvig
08:21:01<dmwit>PetRat: Yes, exactly.
08:21:50<Gracenotes>it was 10 years, iirc
08:22:19<PetRat>An adult who has some kind of movement difficulties like pain, stiffness, balance problems, etc., can feel like they barely function. But look at a baby waving its arms and legs around, and the great accomplishment for a baby is bringing its fist to its mouth without a lot of wasted effort. We have come a long way.
08:23:55<PetRat>Yes it was learn programming in 10 years. If you go to borders, there are a slew of books called "Learn SQL in 24 hours," "Learn SQL in 10 days," maybe other variants. I forget the publisher but they have numerous titles like that.
08:27:35<PetRat>> id (5 *) 5
08:27:36<lambdabot> 25
08:28:09<PetRat>I like how initially "id (5 *) 5" looks wrong because id takes only one argument.
08:30:45<shachaf>PetRat: All functions take only one argument.
08:31:12<shachaf>Would you prefer "($) (5 *) 5"?
08:33:43<tibbe>any windows user out there that can verify that network-2.2.1.2 build (i.e. do "cabal update" followed by "cabal upgrade network")?
08:36:43<Gracenotes>PetRat: you might say (id (5*)) 5...
08:37:07<Gracenotes>> id id id id id id id id id id id id (*5) 5
08:37:08<lambdabot> 25
08:37:48<Cale>Anything which returns a result of an arbitrary type can appear to take an arbitrary number of parameters
08:39:07<ziman>:t const undefined 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
08:39:08<lambdabot>forall t. t
08:41:07<Cale>> foldr (.) id [(*2),(+3),(*5)] 10
08:41:10<lambdabot> 106
08:48:10<dibblego>@src replicateM
08:48:11<lambdabot>replicateM n x = sequence (replicate n x)
09:15:02<dibblego>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5099#a5099 where am I screwing up?
09:18:42<doserj>dibblego: value always succeeds without consuming input
09:19:51<dibblego>ah yeah I think I want \x -> satisfy(== x)
09:19:57<dibblego>thanks
09:20:59<doserj>that makes value and satisfy mutually recursive, though :)
09:21:17<dibblego>no, I won't change value
09:21:40<dibblego>I'm just not using the right function (I need another function with the same sig)
09:21:46<doserj>ah, ok
11:04:06<nisse>Hi all.
11:04:28<nisse>I've been studying Haskell for a while now.
11:04:36<Tobsan>great :)
11:04:45<nisse>I'm in a point where I start to understand laziness and the typesystem
11:04:59<nisse>and the purity :)
11:06:01<PeakerWork>nisse: after understanding it, I had trouble seeing what I had trouble understanding :-)
11:06:03<PeakerWork>Its so simple :)
11:06:19<nisse>And I've started to realize that Haskell is _really_ different language than "traditional" languages
11:06:33<nisse>(algol based)
11:06:45<tetha>you can use Monoid in a sensible way in a program... that certainly is different :)
11:06:55<PeakerWork>Laziness does not run as deep into my brain as other stuff, now I just see it as an implicit memoizing lambda around everything :()
11:07:45<nisse>The more I understand the Haskell philosophy the more I realize that other languages are just ... wrong
11:08:23<tetha>I would not call it wrong, I would call it simpler
11:08:55<dibblego>I call it wrong and excessively complex and not simple enough
11:09:09<nisse>tetha: Well like comparing JS to Basic.
11:09:18<nisse>dibblego: !
11:09:39<tetha>dibblego: hm. yes, you are right, simple and difficult are the wrong terms, even though I do not know better terms
11:09:56<dibblego>nisse, yes? I compounded your statement with conjunction, I hope you don't mind
11:09:58<PeakerWork>tetha: what's simpler, other languages?
11:10:17<nisse>dibblego: You said what I was trying to say :)
11:10:27<tetha>PeakerWork: I would argue that "just using a string" instead of thinking of monoids requires a smaller initial brain effort
11:10:30<nisse>dibblego: Kinda like crystallized
11:10:45<tetha>PeakerWork: certainly, once you understood everything, monoids are simpler and much more flexible
11:11:40<nisse>So is there some area of computing where Haskell is less practical than some strict language?
11:11:52<IntergalacticOwl>The initial effort barrier is a problem for average programmers though.
11:12:11<tetha>IntergalacticOwl: that is my point :)
11:13:03<dibblego>nisse, it is not about lazy language versus strict -- it is about which is the default -- for the general case, lazy is the correct default
11:13:36<nisse>dibblego: well, the in some langs the laziness is kind of hidden
11:13:47<IntergalacticOwl>I can't say too much since I'm still learning Haskell, but I do not think that I would even be able to start explaining it to anyone I know irl.
11:14:25<Botje>it's easier to express what you want to do
11:14:33<Botje>without all that mucking around with iterators or indexes
11:16:49<nisse>dibblego: Haskell seems to be too good to be true.
11:17:06<nisse>dibblego: Is there some horrible catch that I've perhaps missed?
11:17:18<dibblego>not really
11:17:44<IntergalacticOwl>It is in general pretty amazing so far
11:18:42<IntergalacticOwl>Maybe one of the catches is convincing your employer to let you use it for work though
11:19:23<thirsteh>and that's probably gonna be harder than learning the language :-)
11:19:28<thirsteh>for now...
11:20:41<IntergalacticOwl>Last I was employed, I had to learn Visual Basic .NET on the job, haha
11:21:34<solrize>the main catches seem to be space leaks, and the complexity of nesting monads
11:22:20<zachk>and cabal doesnt work so great on windows haskell
11:22:33<zachk>but frag does compile and run
11:22:40<Baughn>Nah, that's a catch with windows, not with haskell
11:23:10<ivanm>what does the new LHC do?
11:23:13<nisse>solrize: can you elaborate?
11:23:16<ray>a catch with haskell is similar to one that many language communities have
11:23:22<ray>they're too attached to UNIAX ;)
11:23:30<Baughn>ivanm: ..LHC? Not the collider?
11:23:34<ivanm>ray: *shrug* I have no problem with that ;-)
11:23:41<ivanm>Baughn: no, Lemmih's LHC
11:23:42<ivanm>;-)
11:23:55<ray>well, it's not so bad with haskell
11:23:58<ray>avoid success and all
11:24:20<ray>large haskell collider
11:24:25<IntergalacticOwl>I've been having trouble getting Cabal to work on debian, actually. Bootstrap.sh ate all my memory linking something and then hours later, spat out errors.
11:24:33<ray>that's what monad transformers use under the hood
11:24:50<ray>if it's debian, maybe you're missing key libraries
11:25:36<ray>you might have to install more of the packages with names like libghc6-*-dev
11:27:14<IntergalacticOwl>I made sure I had network and parsec
11:28:25<ivanm>IntergalacticOwl: are you talking about Cabal or Cabal-Install?
11:28:41<ivanm>ACTION notices dcoutts conveniently left when questions about Cabal came up... >_>
11:28:57<IntergalacticOwl>cabal-install sorry
11:32:49<Saizan>IntergalacticOwl: long linking times are not unknown for ghc
11:33:05<IntergalacticOwl>I see
11:34:04<Baughn>IntergalacticOwl: Shouldn't be /that/ long, but if you're running out of memory..
11:34:19<Saizan>depends on how much memory you have, i guess
11:35:46<Baughn>Mm. If I'm reading this right, linking GHC takes about 2GB.
11:36:28<Saizan>he's linking cabal-install though
11:37:03<PeakerWork>ACTION finally understood why djinn is a theorem prover :)
11:37:21<mux>does hackage use "cabal haddock" to generate the documentation?
11:37:22<PeakerWork>it could be awesome to have background @djinn'ing in my code editor that proves my code using some heuristics while I edit it
11:39:30<ivanm>mux: not sure if hackage uses cabal-install
11:39:47<ivanm>but it would be using cabal-the-library most probably in some way to call haddock
11:41:14<mux>I'm looking for some C macro that I could use to know this is haddock generating documentation so that I can avoid having some code #ifdef'ed out
11:42:14<Saizan>since 2.0 haddock doesn't define anything like that
11:42:16<mux>ACTION reads Distribution/Simple/PreProcess.hs
11:42:37<ivanm>Saizan: yes it does
11:42:45<ivanm>I just saw it in the haddock docs the other day
11:43:07<ivanm>mux: somewhere around here: http://www.haskell.org/haddock/doc/html/module-attributes.html
11:43:09<Saizan>the documentation might be outdated
11:44:02<mux>I don't see anything with those attributes that could help
11:44:06<Saizan>Haddock does not
11:44:08<Saizan>define any cpp macros at all (unless GHC defines any by default).
11:44:20<mux>that would be Cabal's job anyways
11:44:24<Saizan>in an email from haddock's maintainer :)
11:44:32<mux>it's cabal that does the preprocessing
11:45:23<Saizan>mux: that's not entirely true in practice
11:45:45<mux>indeed, I know see that the preprocessors are passed to preprocessModule
11:45:50<ivanm>Saizan: ahhh, I missed that mux wanted it to be CPP
11:46:13<mux>not really CPP, but this is a .hsc file so it has CPP macros too
11:47:11<Saizan>unless you've CPP in the extensions there won't be a separate cpp pass
11:47:27<mux>I mean that hs2c does that
12:17:08<jeff_s_>when I "import Data.ByteString.Char8 as B" and I call an unqualified function like "getContents", it's annoying that ghc warns me about a conflict between Prelude and ...Char8. Is there a way I can import something like BytesString but not have to prefix every Prelude function with "Prelude"?
12:17:37<Baughn>jeff_s_: import Prelude hiding (foo,bar)
12:17:58<Baughn>jeff_s_: Or, do you mean having both getContents imported at the same time?
12:18:19<Baughn>..that would be what typeclasses are for. We could probably use more of them.
12:18:27<jeff_s_>I want to be able to write ByteString.getContents and getContents, where the unqualified name is Prelude
12:18:55<Baughn>jeff_s_: So, import qualified Data.ByteString.Char8 as ByteString?
12:19:08<jeff_s_>Maybe I'm missing some haskell style though. What I'm looking for is waht I'm used to from ML.
12:19:26<jeff_s_>I imported it qualified but I get the same problem :\
12:19:50<jeff_s_>Ambiguous occurrence `tail'
12:19:51<jeff_s_>It could refer to either `Prelude.tail', imported from Prelude
12:19:51<jeff_s_> or `B.tail', imported from Data.ByteString.Char8 at 2.
12:20:14<Baughn>jeff_s_: What's you r/exact/ import line?
12:20:21<doserj>jeff_s_: there is a difference between "import M as B" and "import qualified M as B"
12:20:27<jeff_s_>OH
12:20:30<jeff_s_>duh, thanks
12:21:20<jeff_s_>ok ya, that was exactly what I wanted. Thanks!
12:23:54<ivanm>doserj: is there any time where import unqualified with an alias is useful?
12:24:11<Baughn>jeff_s_: You can also have multiple import lines, eg. to import type names unqualified
12:25:38<doserj>ivanm: I don't think I ever used that
12:26:16<ivanm>I wonder if there is ever use for it
12:26:26<Baughn>I've never seen it used anywhere
12:26:42<ivanm>unless you have only one or two clashes, and can't be bothered doing P.blah for all functions, whereas you can do so for those that _do_ clash
12:35:58<saml>data (->) a b -- how should i understand this?
12:36:02<saml>> 1 -> 2
12:36:05<lambdabot> <no location info>: parse error on input `->'
12:36:20<Saizan>(->) is a type constructor there
12:36:56<saml>ah i think i get it now
12:37:00<athos>@type a >- b
12:37:01<lambdabot>Not in scope: `>-'
12:37:04<athos>@type a -> b
12:37:05<lambdabot>parse error on input `->'
12:37:13<saml>@kind (->)
12:37:15<lambdabot>?? -> ? -> *
12:37:17<athos>:)
12:39:57<saml>> (succ >>> succ) 0
12:39:59<lambdabot> 2
12:40:28<tombom>@kind (>>>)
12:40:29<lambdabot>Not in scope: type variable `>>>'
12:40:46<tombom>@type (>>>)
12:40:47<lambdabot>forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a c d -> a b d
12:41:11<saml>A class for categories. id and (.) must form a monoid.
12:41:26<saml>wtf is monid
12:43:09<EvilTerran>a monoid is a set with an associative binary operation, and an element that is a left- and right-identity element of that operation
12:43:32<EvilTerran>ish.
12:43:32<MyCatVerbs>saml: a Monoid is a type that you can glue two of them together (mappend), and for which there is an identity element (mempty).
12:44:01<MyCatVerbs>EvilTerran: please don't tack "ish" onto correct definitions. It makes people nervous. ;P
12:44:17<Botje>they should be!
12:44:43<ivanm>EvilTerran: "operationish"?
12:44:45<athos>> [1] `mappend` [2]
12:44:46<EvilTerran>MyCatVerbs, it was to indicate my own non-confidence in the accuracy
12:44:47<lambdabot> [1,2]
12:44:58<athos>> [1] `mappend` mempty
12:45:00<lambdabot> [1]
12:45:21<ivanm>> mempty `mappend` mempty
12:45:22<ivanm>;-)
12:45:22<lambdabot> ()
12:45:25<MyCatVerbs>EvilTerran: oh, well. *checks*. Yes, you were correct.
12:45:29<ivanm>:o it has a default instance? :o
12:45:38<ivanm>@type mempty `mappend` mempty
12:45:39<lambdabot>forall a. (Monoid a) => a
12:45:46<saml>., >>>, mappend.. they sound all similar
12:45:50<ivanm>why did lambdabot default to ()?
12:45:54<ivanm>@type (>>>)
12:45:55<lambdabot>forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a c d -> a b d
12:46:04<MyCatVerbs>ivanm: No. () is an instance of Monoid. So if you don't give any type whatsoever beyond (Monoid m, Show m), then the type inferrer may guess ().
12:46:09<ivanm>saml: >>> uses different types
12:46:22<ivanm>MyCatVerbs: yes, but I was wondering why lambdabot defaulted to it rather than complaining
12:46:25<saml>can we unify all of those composition stuff?
12:46:35<ivanm>AFAIK, only Integral and Floating have default type
12:46:37<ivanm>*types
12:46:41<Saizan>saml: a Category is a parametrized Monoid, roughly
12:46:43<ivanm>saml: see the Typeclassopedia
12:46:47<EvilTerran>ivanm, extended defaulting is a ghc extension
12:46:55<Saizan>saml: so it's expected :)
12:46:55<ivanm>Saizan: and a Monad is a Monoid in the Category of Endofunctors?
12:46:57<ivanm>;-)
12:46:58<marcot>What should I use to generate a .cabal file? Is there a library like haskell-src for Cabal?
12:47:01<ivanm>EvilTerran: ahhh
12:47:02<MyCatVerbs>ivanm: *checks*, GHCi does too.
12:47:04<EvilTerran>@check \x y -> x == y -- all things are equal!
12:47:05<lambdabot> "OK, passed 500 tests."
12:47:07<ivanm>that I didn't know about
12:47:11<Botje>marcot: mkcabal
12:47:14<Saizan>ivanm: sure, what's funny about that?
12:47:18<ivanm>Botje: it's dead
12:47:22<Botje>uh?
12:47:23<ivanm>and doesn't build with new ghc, etc. :(
12:47:31<Botje>oh
12:47:35<ivanm>Botje: mkcabal is dead, dons told me he wasn't working on it anymore
12:47:43<Botje>i used mkcabal for my thesis and it worked fine
12:47:45<MyCatVerbs>I thought everybody just copied someone else's cabal file and altered it?
12:47:46<ivanm>Saizan: didn't you read that blog post?
12:47:47<Botje>but that was 6.8
12:48:00<ivanm>Botje: yeah, doesn't like new exceptions IIRC
12:48:20<marcot>I don't have a problem about generating it, I just want a library to makes thing easier if there is one already.
12:48:42<marcot>So I could generate a Tree instead of a String.
12:49:02<ivanm>marcot: ummm... what does a Tree have anything to do with a .cabal file?
12:49:03<Saizan>Cabal has functions for parsing and prettyprinting it
12:49:08<yaxu>ACTION gets his new haskell music thingie working
12:49:22<yaxu>ready for a gig in the science museum tonight..
12:49:31<Saizan>look for PackageDescription, or maybe GenericPackageDescription
12:49:39<marcot>Saizan: ok, thanks, I'll take a look.
12:49:49<marcot>Saizan: I was in doubt about so many Cabal types..
12:50:07<ivanm>is there a default function I can use to check if a character is within A-Za-z0-9+_.-] ?
12:50:19<ivanm>or just use isAlpha + checks for the four characters?
12:50:19<Saizan>marcot: there's a small guide to cabal's codebase on the trac wiki
12:50:25<ivanm>s/characters/symbols/
12:50:34<ivanm>(that square bracket shouldn't be there)
12:50:35<EvilTerran>ivanm, i'd use isAlpha and `elem`
12:50:50<ivanm>EvilTerran: elem rather than explicitly doing so?
12:51:08<EvilTerran>\c -> isAlpha c || c `elem` "+_.-"
12:51:14<ivanm>*nod*
12:51:27<EvilTerran>snappier than writing it out explicitly
12:51:30<ivanm>does ghc unroll static elems?
12:52:06<marcot>Saizan: good to know, I'm reading it. Thanks.
12:52:16<marcot>ivanm: The Tree is the parsed file.
12:52:16<EvilTerran>ivanm, oy, no premature optimisation! :P
12:52:41<ivanm>EvilTerran: heh
12:53:04<ivanm>marcot: ummmm.... you're trying to programmatically generate the .cabal file?
12:53:09<ivanm>I still don't see how it's a tree...
12:53:48<marcot>marcot: Yes. Maybe not a Tree, but a Map.
12:53:57<ivanm>marcot: stop talking to yourself! :p
12:54:06<ivanm>but a Map would make more sense than a Tree
12:54:27<marcot>ivanm: in that context it made sense to talk to my self... =P
12:54:32<ivanm>heh
12:54:41<ivanm>that's the first sign of madness, you know...
13:00:26<xian>I am going through the tcopedia right now and I was trying to come up with an instance declaration of Pointed for ((->) e). What I've got now is pure y = \x -> y Is this correct?
13:02:19<BONUS>yeah
13:02:36<saml>it is. . . well, I'll let you work it out. (Just follow the types!)
13:03:22<BONUS>yeah for any of those (functor, pointed, applicative, monad) just write out what the type would be for the particular instance
13:03:27<BONUS>and then it's pretty easy to implement it
13:12:06<ivanm>is there any "simple" way I can implement the following rule to implement a "parsing" function (or type "ReadS String") ?
13:12:18<ivanm>"A package name may contain any of the characters [A-Za-z0-9+_-]. It must not begin with a hyphen, and must not end in a hyphen followed by one or more digits."
13:12:52<mlysgaard>ivan Regexp?
13:12:57<ivanm>in particular, I'm not sure how to do the not-ending-in-hyphen-followed-via-digits bit
13:13:03<ivanm>mlysgaard: I'd rather not
13:13:56<ivanm>trying to keep the deps to a minimum
13:14:31<mlysgaard>ivanm: Explain to me what you wan't to parse once again? An example
13:14:39<ivanm>exactly what that rule says
13:15:22<Berengal>State machine?
13:15:37<ivanm>ummm... what?
13:15:47<ivanm>I'm after simple String stuff if possible ;-)
13:16:21<ivanm>ACTION could just parse it without that final constraint and then reverse it and remove the final digits, etc. ...
13:16:23<Berengal>A bunch of mutually recursive functions, each representing a state in a state machine, and each state parsing a single char or accepting
13:16:52<Berengal>But that's just regexps without the library
13:17:07<ivanm>*nod*
13:17:16<MyCatVerbs>Berengal: no, that's LL(1) without the library. :)
13:17:52<Berengal>MyCatVerbs: Details :P
13:18:17<EvilTerran>ivanm, i'd be inclined to use parsec, tbh
13:18:25<ivanm>hmmmm.... I might just keep applying break (== '-'), and dropping the rest if it's an integer
13:18:28<ivanm>EvilTerran: no deps
13:18:36<ivanm>*I don't want to have any other deps
13:19:44<mlysgaard>ivanm: What you wan't to do is to get a pacage name from a package, like: "gnome-20.0219e0.02" would become "gnome"?
13:19:47<MyCatVerbs>Berengal: well, not *quite*, you need to carry more state than that, but yes you can implement an LR(1) or LL(1) using a big bouncy pile of continuations to represent the parsing tables.
13:19:49<FunctorSal>ivanm: not ( last ( group ( map isDigit str ) ) && last ( last ( group ( map (=='-') ) ) ) )
13:19:53<FunctorSal>;o
13:19:59<ivanm>mlysgaard: no, in this case it would be the whole thing
13:20:06<ivanm>FunctorSal: :o
13:20:14<ivanm>ACTION tries to work out wtf that does
13:20:19<FunctorSal>> group ( map isDigit "fooo!!99a1" )
13:20:20<lambdabot> [[False,False,False,False,False,False],[True,True],[False],[True]]
13:20:25<ivanm>mlysgaard: since the 'e' there makes it legit
13:20:33<FunctorSal>hmm, still need to collapse the groups
13:21:31<FunctorSal>ivanm: also, isAlphaNum from Data.Char
13:21:40<ivanm>yeah
13:21:42<mlysgaard>ivanm: Ok, but if it's "gnome-2.10.14892" would be parsed "gnome"?
13:22:03<FunctorSal>let legal c = isAlphaNum c || elem c "+_-" in all legal str
13:22:29<ivanm>mlysgaard: well, '.' isn't allowed, so it wouldn't include anything after the .
13:22:30<ivanm>but yes
13:22:34<FunctorSal>of course peformance won't be greatt
13:22:44<ivanm>FunctorSal: yeah, I've got that
13:22:45<MyCatVerbs>legal = liftM2 (||) isAlphaNum (flip elem "+_-")
13:23:01<ivanm>it's making sure it doesn't end in "-<number>" that's the problem
13:23:21<doserj>> not . all isDigit . fst . break (=='-') . reverse $ "blah-2"
13:23:23<lambdabot> False
13:23:47<FunctorSal>:o
13:24:05<ivanm>bugger... I'm parsing a bunch of different components; some things I'm allowed '.', others aren't :@
13:24:27<ivanm>so I have to have two seperate Char -> Bool functions, one which allowes '.' and the other which doesn't
13:26:07<mlysgaard>By the way, what's the options in graphical toolkits when working in haskell?
13:26:25<ivanm>gtk2hs, wxhaskell
13:26:37<ivanm>there's qt bindings, but haven't heard much about them in a while
13:26:43<ray>opengl, for a wider definition of "graphical toolkits" than the one you probably mean
13:29:50<mlysgaard>Hmm, well, I'd like to draw mathematical expressions, and edit them in real time. Quite unusual.
13:30:11<mauke>oh, a text editor?
13:30:17<FunctorSal>ftgl? ;)
13:30:47<FunctorSal>would be a bit of a pain to do subscripts etc. manually though
13:30:52<mlysgaard>Well, it would need to support all kinds of strange math symbols
13:31:07<FunctorSal>more than are in unicode?
13:31:33<mlysgaard>No, i think unicode would work
13:31:53<FunctorSal>(table 33 and 34)
13:31:56<EvilTerran>mlysgaard, ah, that's really not that unusual. i think most maths/compsci students want that :)
13:31:57<mlysgaard>but arbitrary sub/superscript
13:32:13<mlysgaard>Hehe ;)
13:32:38<EvilTerran>ACTION does, anyway
13:32:52<FunctorSal>mlysgaard, are you trying to make an editor that has some (possibly incomplete) understanding of semantics?
13:33:25<ivanm>mlysgaard: auctex + previewlatex ;-)
13:33:30<EvilTerran>ACTION would take it further, into full-blown shiney-graphics proof-assistant territory
13:33:44<ivanm>EvilTerran: "shiny"?
13:33:53<mlysgaard>Well, yeah. I wold like to make an editor that could edit symbolic expressions in real time. Looking like latex formulas
13:34:13<FunctorSal>EvilTerran: believe it or not, I've started some 3d commutative diagrams thing with specular arrows ;o
13:34:28<ivanm>whizzytex IIRC has something like this (though it's more like it draws the preview in real time)
13:35:02<Saizan>and bidirectional conversion between diagrams and equations for CT
13:35:11<EvilTerran>FunctorSal, ooo
13:35:46<FunctorSal>I'm not sure what to use as underlying logic though :-(
13:36:13<FunctorSal>writing a complete logic toolkit with unification and stuff from scratch seems a bit daunting
13:36:37<EvilTerran>it is, i've tried =/
13:38:19<FunctorSal>maybe the first-order theory of the category of sets would be a fitting foundation
13:38:47<mlysgaard>Well, what my goal is to make some sort of digital mathematical blackboard. Anyone tried the HP 40gs calculators they have this function
13:41:03<jbauman>mlysgaard, a CAS like mathematica?
13:42:57<mlysgaard>Well, im just a high scool student so i'm just fooling around. Made some symbolic math types and some simple simplify functions and i'd like to make a good interface to it.
13:43:20<mlysgaard>jbauman: But in a essence a CAS, just wery simple
13:48:59<wli>I got burned trying to de-nest radical expressions.
13:49:23<wli>The polynomial factorization methods turned out to be beyond my power.
13:50:18<jacobian>Is it correct to say that inf=inr(inf) is the limit point of the monad nu X . 1 + X
13:51:11<wli>I never got far enough to try to compute integral bases for radical extension rings.
13:52:54<marcot>@hoogle String -> ReadP a -> a
13:52:55<lambdabot>Did you mean: String -> ReadP a a -> a /count=20
13:52:55<lambdabot>Debug.Trace trace :: String -> a -> a
13:52:55<lambdabot>Distribution.ParseUtils field :: String -> (a -> Doc) -> ReadP a a -> FieldDescr a
13:53:22<EvilTerran>ACTION feebly pokes at the sizable write-up he really needs to get done
13:53:25<marcot>How can I get the parsed result of a ReadP? Do I have to convert it to ReadS?
13:53:41<EvilTerran>marcot, i believe that's whatthe docs suggest, yeah
13:53:53<marcot>EvilTerran: ok, thanks.
13:54:21<EvilTerran>"Converts a parser into a Haskell ReadS-style function. This is the main way in which you can "run" a ReadP parser: the expanded type is readP_to_S :: ReadP a -> String -> [(a,String)]"
13:56:32<sayyestolife>hello
13:56:47<sayyestolife>Isn't there some site for haskell "snippets"?
13:57:14<EvilTerran>hpaste.org ?
13:57:35<FunctorSal>I can make a substitution idempotent by composing it with itself until it becomes stable, right?
13:58:06<FunctorSal>(premature optimization be damned ;))
13:58:15<sayyestolife>EvilTerran I'm thinking more in the terms of http://www.djangosnippets.org, where only "useful" stuff gets posted
13:58:26<sayyestolife>not some temporary paste
13:58:52<EvilTerran>oh right
13:59:01<doserj>*cough* useful snippets end up on hackage *cough*
13:59:18<EvilTerran>i think the norm is to write a blog post and link it on reddit
13:59:36<sayyestolife>EvilTerran hmm.. okay
14:00:01<sayyestolife>but I'm thinking about something more like almost wikilike
14:00:18<EvilTerran>i don't think that particular niche has been filled yet
14:00:35<EvilTerran>although some of the haskellwiki pages are effectively useful code snippets
14:08:09<sayyestolife>EvilTerran okay thanks!
14:22:01<tibbe>I was playing around with the Haddock CSS a bit: http://johantibell.com/haddock.png (design stolen from all over the place)
14:26:52<xian>Is there any easy way to overwrite instance declarations in case ghc is complaining that there is more than one for a specific type? (I'm playing around with typeclasses at the moment, so I get this quite often)
14:28:32<EvilTerran>xian, instances are global, unfortunately; it's a limitation of the typesystem
14:29:05<EvilTerran>the semantics would have to be changed substantially to allow local instances, as i understand it
14:29:17<EvilTerran>xian, although you could write your instances for a newtype-wrapped version of the type
14:29:56<xian>Yeah, that seems like a good idea. But I couldn't use functions defined on the original type then, could I?
14:30:23<EvilTerran>"newtype MyInt = MyI Int deriving (<whatever classes you want derived>); instance Ord MyInt where ...", say
14:30:45<EvilTerran>xian, well, you could use the deriving mechanism to get instances of Eq, Ord, Read, Show etc for free,
14:34:01<Philonous>Concurrent programming in haskell really is fun, (at least compared to C or Java). Maybe that should be emphasised when advertising haskell.
14:34:15<xian>What I mean is that in the above case I couldn't call functions defined specifically on Int even though MyInt is basically the same as Int.
14:35:53<EvilTerran>xian, yeah, you'd have to add/remove the newtype's constructor if you wanted to do that
14:36:21<Jedai>xian: No you couldn't, on the other hand if you want to use your type exactly like an Int except on some very rare occasion, maybe you should just create some new functions rather than try to modify the current ones
14:36:55<ray>generalized newtype deriving would let you get instances of anything the actual type's an instance of for free
14:37:10<Jedai>xian: also one thing that is useful on newtypes is that you can "derive" any typeclass that was instancied for the original type, even the one that can't be derived usually
14:37:12<EvilTerran>ray, but you'd still be stuck on functions that aren't class methods
14:37:28<ray>yeah, functions that aren't class methods are such a pain
14:37:40<ray>general types ftw
14:37:48<Fred320>@pl \x z -> x ++ y:z
14:37:49<lambdabot>(. (y :)) . (++)
14:38:09<ray>also, polymorphic functions, not just methods
14:39:19<EvilTerran>true, i meant classwise polymorphic functions
14:43:53<CalJohn>I'm starting a new project, but Setup insists that the dependancy bencode is missing, but I am sure it is installed
14:44:06<CalJohn>do i need to add .cabal to the path or something?
14:44:58<mauke>no, you need to list your dependencies in your cabal file
14:45:12<mauke>wait, hmm
14:45:19<mauke>what's the exact error message?
14:45:25<ksf>quite OT, but can someone point me to a good book leading up to SICM?
14:46:39<CalJohn>mauke: "at least the following dependancies are missing: bencode -any"
14:46:53<CalJohn>mauke: i have listed them in my cabal file
14:47:00<mauke>yes
14:47:13<mauke>what does 'ghc-pkg list bencode' say?
14:47:13<lilac>ksf: you mean SICP?
14:47:14<lambdabot>lilac: You have 3 new messages. '/msg lambdabot @messages' to read them.
14:47:24<ksf>nope, SICM.
14:47:32<CalJohn>lilac: no, the newish scheme book for classical mech
14:47:32<ksf>http://mitpress.mit.edu/SICM
14:47:55<ksf>...if you need something leading up to SICM, you're in trouble.
14:47:59<CalJohn>mauke: /usr/lib/ghc-6.8.2/package.conf:
14:48:00<CalJohn>/home/cal/.ghc/i386-linux-6.8.2/package.conf: bencode-0.3
14:48:02<ksf>s/sicm/sicp
14:48:12<lilac>damn you sussman!
14:48:20<mauke>CalJohn: try Setup configure --user
14:48:37<CalJohn>mauke: seems to work fine, why?
14:48:46<doserj>CalJohn: or just cabal install
14:48:55<mauke>you installed bencode as a user package
14:49:07<mauke>a system package can't depend on a user package
14:49:19<mauke>so you need to build your new project as a user package too
14:49:49<CalJohn>mauke: i see, thankyou
14:56:57<ksf>ACTION wonders why he spent years at school studying stuff that was already obsolete in 1750.
14:57:15<mauke>... latin?
14:57:26<ksf>newtonian mechanics.
14:57:49<p_l>ksf: because for a big part of the time, they are good enough approximation?
14:58:27<p_l>ACTION thought that first lesson in physics was "if you can, approximate"
14:58:45<ksf>so I thought, but it figures that around 1750, better formalisms were introduced that capture the same range of phenomena, and those are the same formalisms that are used for relativity and quantum mechanics.
14:59:20<p_l>ksf: but are you going to use them while dealing with the same range as newtonian mechanics do?
14:59:29<p_l>as in "what is easier"
15:00:22<ksf>no idea, I was never able to figure out why my newtonian calculations were wrong, and don't grok lagrange yet.
15:01:07<wli>The calc of variations is big.
15:01:26<EvilTerran>and scary!
15:02:28<p_l>there are whole computationally heavy areas in physics/engineering that don't care about quantum mechanics or relativity, for the simple reason they deal with "relatively" low speeds in macroscale :)
15:03:02<wli>Yeah, Newtonian mechanics are by no means obsolete.
15:04:22<p_l>ACTION recalls how "HOWTO for ANSYS clusters, by scientist to scientist" noticed everyone "keep CFD guys out, they *always* eat all processing power, no matter how much there is"
15:05:10<ksf>tbh, I'm just attracted to the idea of just grokking a few lines of scheme to understand stuff, as opposed to figuring out the flaws in a particular incarnation of "standard notation".
15:05:43<gwern>ksf: you sound like the Structure & Interpretation of Classical Mechanics book :)
15:06:00<ksf>ACTION doesn't think it's the reader's job to sort the writer's thoughts.
15:07:00<ksf>...or figure out arguments by abstract hand-waving.
15:11:20<ksf>...according to wikipedia, lagrange gets rid of a lot of constraints you have to solve.
15:11:53<wli>Take the Lagrangian, Luke.
15:14:24<Flugaren>Does anyone here have any experience with HList?
15:26:36<marcot>Where can I get an example of TH [d| |]?
15:28:58<EvilTerran>, [d| len [] = 0; len (x:xs) = 1 + len xs |]
15:28:59<lunabot> FunD len [Clause [ConP [] []] (NormalB (LitE (IntegerL 0))) [],Clause [In...
15:34:34<acieroid>hi
15:36:58<acieroid>is there some function like System.getEnv, but for setting a env's variable ?
15:37:15<marcot>EvilTerran: but what should I so with it? I have f = [d| len [] = 0; len (x:xs) = 1 + len xs |]; f :: Language.Haskell.TH.Syntax.Q [Language.Haskell.TH.Syntax.Dec] . Now how can I use it?
15:37:31<QtPlaty[HireMe]>acieroid: You can't set an enviroment verable in the Posix model
15:37:58<QtPlaty[HireMe]>Well programs can't anyway.
15:38:04<acieroid>hmm
15:38:19<acieroid>how a shell can change variables so ?
15:39:10<QtPlaty[HireMe]>acieroid: The shell can change variables because the variables are part of the shell. The programs that are spawned by the shell can't change the enviroment vars of there perents.
15:39:28<acieroid>ok
15:40:05<acieroid>and, how the shell passes his environment to his child processes ?
15:40:40<QtPlaty[HireMe]>acieroid: Its an argument to the exec call it makes IIRC
15:41:09<EvilTerran>marcot, writing "$f" in a list of defintions would be the same as writing "len [] = 0; len (x:xs) = 1 + len xs"
15:41:29<doserj>acieroid: there is System.Posix.Env
15:41:43<acieroid>hmm, I'll look at that, thanks
15:51:07<marcot>EvilTerran: Where do I use a list of definitions? That's what I'm not understanding.
15:51:32<EvilTerran>marcot, the top-level of a module
15:52:33<doserj>or inside a let or where block
15:52:45<EvilTerran>marcot, if you want to use TH in where or let clauses, i'd suggest using [|...|] and writing "someName = $(...)", rather than including the "someName =" in a TH construction
15:52:57<EvilTerran>doserj, can you? lunabot doesn't seem to like it, at least
15:53:20<marcot>EvilTerran: My goal is to write a instance using TH.
15:53:22<EvilTerran>, let $([d| x = () |]) in ()
15:53:23<lunabot> luna: parse error on input `in'
15:53:57<doserj>hmm
15:54:26<EvilTerran>doserj, [d|...|] includes data, instance, etc declerations, so doesn't strike me as appropriate for let/where clauses
15:56:46<doserj>true, [d|..|] only does top-level declarations, not arbitrary declarations
15:57:44<EvilTerran>?where derive
15:57:44<lambdabot>http://www.cs.york.ac.uk/fp/darcs/derive
16:01:52<Deewiant>Gah, has anybody managed to compile Catch?
16:04:37<TomMD>Deewiant: I used catch a little back when it was new and Niel still worked on yhc. Haven't touched it since.
16:05:20<TomMD>Deewiant: It sounded like Neil did some initial work to bring Catch to GHC but hes time is all taken up by his day job now.
16:05:24<TomMD>@seen ndm
16:05:25<lambdabot>I haven't seen ndm.
16:06:29<Deewiant>Yes, I suppose I should have added "recently" to my query... I'm getting type errors in Catch's use of the Yhc core lib
16:06:33<dons>i'd love to see an analysis framework for ghc core
16:06:40<dons>so we can write catch and other things.
16:06:49<dons>i mean, they have CiL et al for C code. so why no lib for haskell analysis?
16:06:50<Deewiant>I don't mind the fact that it uses Yhc, compiling Yhc was the easy bit :-P
16:06:59<pejo>I think Neil was considering using external core output from GHC for Catch. But not sure how much time he has on his hands now with the daytime job.
16:07:00<dons>well, it makes it less useful for real code
16:07:09<mauke>preflex: seen ndm
16:07:10<preflex> ndm was last seen on #haskell 12 days, 5 hours, 50 minutes and 30 seconds ago, saying: plus with current compiler technology, it would be slower
16:07:17<dons>i'd just like a description of the analysis, so we could reimplement it
16:07:49<Deewiant>I'd just like these two programs by the same author to compile against each other :-P
16:07:52<pejo>dons, have you looked at the catch paper?
16:08:03<dons>TomMD: know much about separation logic?
16:08:05<dons>pejo: yes.
16:08:26<pejo>dons, didn't he describe the analysis there?
16:08:53<dons>I don't recall a formal description, but I might be wrong.
16:09:23<dons>I'm wary of the hand wavy use of the term "proof" around ad hoc analysis
16:10:36<pejo>dons, I think you need to assemble all the figures.
16:10:59<dons>yes, it looks like there's a fair bit of material now. much more than when I used catch on xmonad back in the day.
16:11:02<pejo>(Not making any claims about the proof, I'm guessing you want it mechanized).
16:11:13<dons>well, i just want to know what the underlying theory is.
16:12:05<dons>and a characterisation of what it finds, and what it won't, and why.
16:12:20<pejo>dons, what would the underlying theory be for "Assemble a bunch of constraints according to the semantics, and prove that you can't get a pattern mismatch"?
16:12:24<dons>of course, any static analysis that finds a bug we didn't spot is useful.
16:13:09<dons>pejo: so its some kind of symbolic interpretation? the code is evaluated, symbolically, yielding constraints on types, that are used to refine the types at pattern match time.
16:13:13<mmorrow_>dons: a standardized (external) "core" language (compiler-indep) for haskell would be awesome
16:13:14<pejo>dons, I've been thinking about characterisations for what Supero can remove, but it's far from trivial. Even if you accept pen and paper proofs.
16:13:16<Deewiant>So I take it nobody has any idea of the newest Yhc version that the latest Catch accepts? (Or, likewise, the newest Catch version that compiles against the latest Yhc)
16:13:39<dons>or is it a kind of type inference?
16:14:16<mmorrow_>there's a core-erlang pkg on hackage with a similar thing for that
16:14:58<pejo>dons, how many existing analyses do you know of that characterises what it can find and can't find, and prove it?
16:15:40<dons>pejo: i'm at a conference this week that's full of such things :)
16:15:58<dons>but yes, there's a scale in the static analysis world from formal stuff to ad hoc 'lint'-like tools
16:16:00<mmorrow_>links?
16:16:05<dan>does anyone know if there's a way to add a path to the search path where ghci looks for files to :load?
16:16:17<mmorrow_>dan: it's relative to your pwd
16:16:20<pejo>dons, small disclaimer: I'm in no way an expert on catch. I'd just like it to work for GHC. We know it's not complete, but I think it would be useful.
16:16:22<dons>mmorrow_: i'll dig around to see if something's online.
16:16:28<dons>pejo: agreed!
16:16:41<dons>it was very useful for xmonad.
16:16:48<dons>and we need more tools like this.
16:16:54<mmorrow_>dons: excellent
16:16:57<dan>mmorrow_: Is there anyway to make a relative import?
16:17:06<pejo>dons, the tools that people actually *use* are far closer to Lint than what the researchers are working on I think.
16:17:06<dan>import mysubdir/mymodule
16:17:44<mmorrow_>:m + Asdf.Qwerty.Jkl ====> ./Asdf/Qwerty/Jkl.hs
16:17:57<mmorrow_>err, sorry :l
16:18:08<dons>pejo: yep.
16:18:20<pejo>dons, (I know Galois does crazy stuff and proves stuff with Isabelle/HOL, but that's an exception, just like the Airbus stuff).
16:18:45<dan>i just don't know what is the correct way to set up a haskell workspace. Do I have to put all my modules which I am importing in a single dir?...
16:19:32<dons>pejo: right, but we are a community that should be precise when using words like 'proof'
16:20:16<pejo>dons, even as a community we disagree on what a proof means. Some want constuctive proofs, ..
16:21:31<pejo>dons, have to run. Let's get back to this later. I have a couple of more questions about your statements. ;)
16:21:37<dons>just stating what formal system is used to produce the proof, is all. if it is 'a haskell program that does some analysis' , that's fine.
16:22:04<gwern>maybe we could just agree that anything more rigorous than quickcheck is a proof
16:22:06<marcot>EvilTerran: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5100#a5100
16:22:32<dons>gwern: no, there's clear notions of soundness and completeness. this is something we can be formal about.
16:22:35<marcot>EvilTerran: I still don't get how can I use Dec in TH. I'm searching about this, but I could not find any start point.
16:23:06<paper_cc>dan: If you don't use hierachical modules, then yes (except library modules - that are searched automatically).
16:23:51<paper_cc>marcot: you should define f in a different module, as it says
16:25:31<marcot>paper_cc: and how can I use the definition inside f in the module which imports it?
16:26:01<marcot>paper_cc: Do you know where can I find a use of Dec?
16:26:17<paper_cc>marcot: $f I think
16:26:57<marcot>paper_cc: ok, I think it worked. Why is there a restriction to use it in the same module?
16:28:09<paper_cc>marcot: it isn't only for Dec (also for quasiquoting). the reason for the restriction is that TH is a single-pass thing I think
16:28:26<marcot>paper_cc: ok.. Thanks. =)
16:32:24<dan>paper_cc: thank you
16:34:06<paper_cc>marcot: the deriveShow example at the very end of http://www.haskell.org/bz/thdoc.htm does generate declarations
16:37:35<marcot>paper_cc: Thanks, I haven't seen that.
16:43:36<marcot>Is there a way for a Cabal package to produces more than one library?
16:44:24<tibbe__>when can you actually sign up for icfp?
16:48:51<PeakerWork>are there SSL wrappers for Haskell?
16:49:23<PeakerWork>HsOpenSSL/hopenssl on hackage -- which do I choose, hmm
16:52:10<dan>is there a natural way to define types in haskell which have value limitations on them? Say, a list of ascending numbers? I don't want to give it a data constructor from just a list, because then i would have to throw some sort of exception if a mismatching list is given in the constructor
16:52:31<ray>tibbe__: at least one of the previous contests had you sign up by submitting your solution
16:52:47<kpreid>dan: no
16:52:50<tibbe__>ray: the conference, not the competition ;)
16:53:01<ray>there's a conference?
16:53:03<ray>:)
16:53:03<augustss>dan: not without dependent types
16:53:07<kpreid>dan: all you can do is write a type which does can't represent the values
16:53:41<paper_cc>ACTION is interested
16:54:04<PeakerWork>dan: hey :-) its called "subtypes", I believe, and Haskell doesn't have them directly. But you can use a representation of your own which can only be interpreted in correct ways.. For example, use a list of positive integers (Word8, for example) and have each represent the delta rather than the value
16:54:05<paper_cc>augustuss: what can one do with TypeFamilies?
16:54:26<burp_>is there some environment variable or other easy way for additional library paths ghc(i) should use?
16:54:29<paper_cc>s/augustuss/augustss/, sorry
16:54:46<burp_>so I don't have to type ghci -lgsl -latlas -lcblas -llapack -lf77blas -L./mylocallibs/lib
16:55:38<dan>PeakerWork: Interesting...
16:55:41<augustss>paper_cc: not in a general way
16:55:42<mmorrow_>alias ghci1337='.....'
16:56:11<mmorrow_>GHCILEET='...'; $GHCILEET
16:56:39<dan>how about if i want a list of unique values?
16:56:43<dan>as a type
16:56:58<mauke>Set
17:00:36<dan>how about if i want a list of 2-tuples, where the fst values are all unique (equal to their own Set), with no limitation on the snd values? is there any way to make a data type for that list in a way that doesn't let anyone construct a malformed one?
17:00:53<lilac>Data.Map?
17:01:13<lilac>basically, these restrictions are enforced by construction in haskell
17:01:30<lilac>you define an abstract data type and only provide operations which maintain whichever invariant you want
17:02:35<bo0ts__>Hi, noob question: I use $ ghci 2>&1 | HsColour -tty for coloured output in ghci put I always gets the linebreaks wrong which is quite annoying.
17:02:42<bo0ts__>Is there any workaround?
17:02:47<dan>Data.Map is just another way of saying "take your regular list of 2-tuples, and if you have som repeating fst values, join them up together" - which is NOT what i want
17:03:13<Beelsebob>bo0ts__: awesome idea... no idea how to solve it though :(
17:03:27<bo0ts__>Beelsebob: The wiki told me to do so ;>
17:03:32<lilac>dan: dan join them up together?
17:03:37<lilac>-dan
17:03:57<lilac>Data.Map is usually right-biased; new things override old things (iirc)
17:04:25<lilac>unless you want the type checker to notice if you try to add the same key twice, i'm not sure what else you could want from it
17:04:42<bo0ts__>Beelsebob: And I just confirmed that it happens with xterm as well. So aint a emulator problem.
17:05:25<dan>lilac: I'm guessing the type checker can't do this for Data.Map - and so this isn't a good solution for my problem
17:06:25<lilac>dan: if you want to statically check that there aren't duplicate keys, i think you could do that with something like oleg's HList
17:07:24<lilac>bo0ts__: by "gets the linebreaks wrong", what do you mean? it seems to be sorta-wroking for me
17:08:13<bo0ts__>Well, if I have a syntax error "Prelude>" will be on the same line as the last output.
17:08:29<bo0ts__>lilac: It's rather: The last linebreak is missing.
17:09:14<PeakerWork>dan: how can you prove at compile-time that all run-time values you'll give to the map are unique?
17:09:32<PeakerWork>dan: if they are otherwise arbitrary?
17:09:37<lilac>bo0ts__: interesting. i'm trying this on a ghci without readline support, maybe that's the issue?
17:10:29<bo0ts__>lilac: I'm using ghci from arch testing repositories.
17:10:46<bo0ts__>lilac: Do I need to recompile to disable readine?
17:10:48<nominolo>@seen MarcWeber
17:10:49<lambdabot>I saw MarcWeber leaving #haskell 4m 3d 7h 54m 11s ago, and .
17:12:59<lilac>bo0ts__: i'm not sure that'd be step forwards :)
17:13:05<lilac>ghci without readline is painful
17:13:48<mauke>cat | ghci
17:14:04<copumpkin>meow
17:16:58<dan>lilac: Thank you, will check that out
17:17:01<bo0ts__>lilac: No, coloured ghci for me :< I'm going back to ruby! ; )
17:17:04<Cale>bo0ts__: If you're using 6.10.1 or 6.10.2 it probably uses editline which is terrible but isn't GPLed. 6.10.3 uses haskeline which is decent and again BSD licensed.
17:17:26<Cale>Coloured?
17:17:38<copumpkin>a repl with syntax highlighting :o how would that work?
17:17:44<lament>beautifully
17:17:48<Twey>Slowly :-P
17:17:50<copumpkin>I want!
17:18:12<eivuokko>Coloured envious of haskell features. Naturally ghci doesn't need to be envious.
17:18:51<bo0ts__>Cale: Not much of a difference anyway. It was just the output.
17:19:11<Cale>Oh, I would have imagined it would just be the input.
17:19:28<Twey>The input would make more sense.
17:19:33<eivuokko>Indeed.
17:19:34<Twey>Why, the output may not even be Haskell code!
17:20:36<lilac>hooray, "cat | ghci 2>&1 | HsColour -tty" works pretty well
17:20:58<Twey>But cat has no readline
17:21:06<lilac>nor does my ghci
17:21:14<Twey>Ah :-P
17:22:09<Cale>http://www.smbc-comics.com/ -- ahaha, today's is good :)
17:22:35<bo0ts__>lilac: Hm, and it corrupts tab completion.
17:22:54<Twey>Hahaha, Cale
17:23:58<lilac>bo0ts__: hmm, tab completion in ghci would be nice...
17:24:10<Cale>ghci normally has tab completion
17:24:13<lilac>ACTION still walking uphill backwards barefoot in the snow
17:24:23<lilac>Cale: see above re no readline ;-)
17:24:34<lilac>my ghci doesn't even have working backspace
17:24:38<Cale>readline is also unnecessary for it to work ;)
17:24:46<Cale>You're using one of the editline versions
17:24:52<Cale>Get 6.10.3
17:24:52<bo0ts__>lilac: Another "feature" cat broke xD
17:24:56<nominolo>anyone know how to get the current process ID in Haskell? I want to write a deamon.
17:25:00<Gracenotes>rlwrap
17:25:09<lilac>Cale: 6.10.1 not good enough? :(
17:25:10<Gracenotes>mehbeh
17:25:13<Cale>lilac: Right.
17:25:27<Cale>lilac: 6.10.1 and 6.10.2 used editline which is crap
17:25:28<lilac>@hoogle processID
17:25:29<lambdabot>System.Posix.Types type ProcessID = CPid
17:25:37<lilac>@hoogle IO ProcessID
17:25:37<lambdabot>Did you mean: :: IO ProcessID /count=20
17:25:37<lambdabot>No results found
17:25:40<mauke>lilac: 6.10.{1,2} are better if you patch and compile them yourself
17:25:43<Twey>System.IO.Posix.getProcessID
17:25:50<Twey>Er
17:25:53<Twey>System.Posix.getProcessID
17:25:54<Twey>Rather
17:25:59<Cale>mauke: But don't bother doing that. Just get 6.10.3 :)
17:26:02<mauke>lilac: 6.10.3 is not entirely broken (like editline) but still inferior to readline
17:26:11<Cale>In what way?
17:26:19<Cale>It works perfectly.
17:26:19<mauke>mappings
17:26:21<wli>ACTION hasn't bothered upgrading.
17:26:24<copumpkin>it doen't have RMS' stamp of approval on it
17:26:37<mauke>Cale: its history works completely differently
17:26:40<lilac>ACTION fails to understand how editline can be so bad
17:27:21<wli>vi keybindings ... woops it doesn't do those, does it?
17:27:35<Cale>lilac: I fail to understand that as well. It has a number of shameful bugs in it. You can bind the delete key, but even then it doesn't work properly
17:27:35<Twey>It is not as nice as readline, indeed
17:27:38<PeakerWork>Does Network.Socket / Network.BSD expose me to byte-ordering issues?
17:27:46<lilac>people actually *use* vi keybindings in line editors?
17:27:51<mauke>"\C-[[A": history-search-backward
17:27:52<Twey>Of course not
17:27:58<PeakerWork>I am getting connection refused when I try to connect to a port that I know is open, using Network.Socket.connect with (PortNum ..) constructor
17:28:04<Twey>:-P
17:28:05<wli>ACTION uses vi keybindings.
17:28:12<Twey>ACTION uses emacs keybindings
17:28:15<mauke>^ you can't do that with haskeline, not even by writing custom Haskell code
17:28:28<Cale>PeakerWork: Don't use the constructor
17:28:31<lilac>ACTION uses emacs keybindings in zsh but edits in vim
17:28:35<Cale>er...
17:28:37<PeakerWork>Cale: how do I use Network.Socket.connect?
17:28:39<Twey>ACTION thinks lilac is bonkers
17:28:42<Twey>:-P
17:28:55<PeakerWork>Cale: It wants a SockAddr -- whose SockAddrInet constructor wants a PortNumber
17:29:13<mauke>PeakerWork: yes. do not use the PortNum constructor.
17:29:18<dmwit>PortNumber is an instance of Num.
17:29:20<Cale>Just use numeric literals for values of type PortNumber
17:29:41<Cale>It's intended to take care of the byte ordering for you.
17:29:43<PeakerWork>ah, I see, thanks
17:29:52<PeakerWork>shouldn't expose the constructor then, IMO
17:31:17<Cale>Interestingly, the haddock documentation for the network library doesn't seem to mention the constructor anymore.
17:31:47<Cale>Oh, it does in Network.Socket
17:32:32<lilac>Twey: i have emacs keybindings set up for ex mode in vim...
17:32:48<frankks>@src ($)
17:32:48<lambdabot>f $ x = f x
17:32:55<lilac>($) = id
17:33:07<frankks>hm?
17:33:35<Cale>frankks: Basically, the important thing about $ is that it has very low precedence
17:33:39<Gracenotes>($) f x = f x
17:34:03<Cale>frankks: Which means that if you have an expression like foo . bar . baz $ x + y
17:34:14<Cale>It means the same as (foo . bar . baz) (x + y)
17:34:32<Twey>> (+1)
17:34:33<lambdabot> Overlapping instances for Show (a -> a)
17:34:33<lambdabot> arising from a use of `s...
17:34:35<Twey>> (+1) 3
17:34:37<lambdabot> 4
17:34:39<lilac>... because it means the same as (foo . bar . baz) $ (x + y)
17:34:42<Twey>> id (+1)
17:34:43<lambdabot> Overlapping instances for Show (a -> a)
17:34:43<lambdabot> arising from a use of `s...
17:34:44<Twey>> id (+1) 3
17:34:46<lambdabot> 4
17:34:51<Twey>> (+1) `id` 3
17:34:52<lambdabot> 4
17:34:54<Twey>> (+1) $ 3
17:34:55<lambdabot> 4
17:34:58<Twey>Like so.
17:34:58<frankks>i see
17:35:21<Twey>Where id (+1) 3 means (id (+1)) 3, of course, like all function application in Haskell
17:35:26<lilac>($) takes the function on its left hand side, does nothing to it, and then applies it to the value on its right hand side
17:36:09<frankks>i'm just using it in the sense of length $ function [(string),(string),string)]
17:36:25<frankks>ah ok
17:36:25<Twey>ACTION nods.
17:36:30<frankks>sorry just read what you write
17:36:31<frankks>wrote
17:37:30<Gracenotes>yeah, a simple way to think about it is in terms of replacing parens
17:38:23<lilac>> let ($) = id in (4$)
17:38:25<lambdabot> 4
17:38:32<lilac>> let ($) = id in length $ [1,2,3]
17:38:33<lambdabot> 3
17:38:58<frankks>surely
17:39:03<frankks>> length [1,2,3]
17:39:05<lambdabot> 3
17:39:08<frankks> produces the same result
17:39:16<frankks>so.. what's the need?
17:39:40<Gracenotes>> filter odd $ map (^2) [1..]
17:39:41<lambdabot> [1,9,25,49,81,121,169,225,289,361,441,529,625,729,841,961,1089,1225,1369,15...
17:39:54<Gracenotes>> filter odd map (^2) [1..]
17:39:56<lambdabot> Couldn't match expected type `[a]'
17:40:04<mmorrow_>, zipWith id (fmap (*) [0..]) (repeat 2)
17:40:06<lunabot> [0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50...
17:40:19<frankks>so it allows you to apply a function to a value which hasn't yet been determined?
17:40:33<frankks>so f $ f value
17:40:36<Gracenotes>well. It's a lazy language.. technically all values haven't been determined :)
17:40:43<Gracenotes>it's a way to avoid parens
17:40:46<mmorrow_>since functions are values, you can apply functions to other functions/values to get yet more functions
17:40:47<Gracenotes>in practice
17:40:55<frankks>k
17:40:56<Gracenotes>normally you'd write the above like, filter odd (map (^2) [1..])
17:41:32<mmorrow_>@type (filter . odd . fmap (^2))
17:41:34<lambdabot> Couldn't match expected type `a -> Bool'
17:41:34<lambdabot> against inferred type `Bool'
17:41:34<lambdabot> Probable cause: `.' is applied to too many arguments
17:41:43<mmorrow_>@type (filter odd . fmap (^2))
17:41:45<lambdabot>forall a. (Integral a) => [a] -> [a]
17:42:41<mmorrow_>@type [($),id]
17:42:43<lambdabot>forall a b. [(a -> b) -> a -> b]
17:43:05<Raevel>that was cool, somehow
17:43:29<mmorrow_>unite!
17:43:29<Gracenotes>IT ALWAYS IS
17:43:36<lilac>> map (sum . map snd) . groupBy (on(==)fst) . map (head &&& length) . sort $ words "four frolicking foxes flitted feverishly through the furrow"
17:43:38<lambdabot> [42,10]
17:43:54<frankks>@src (\)
17:43:55<lambdabot>Source not found. Are you on drugs?
17:44:06<Berengal>What's the complexity of nub?
17:44:18<lilac>@src nub
17:44:19<lambdabot>nub = nubBy (==)
17:44:21<lilac>@src nubBy
17:44:21<lambdabot>nubBy eq [] = []
17:44:22<lambdabot>nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs)
17:44:22<Gracenotes>
17:44:29<Gracenotes>nub is somewhat inefficient
17:44:29<lilac>Berengal: hideous.
17:44:38<lilac>Berengal: (it's quadratic)
17:44:45<Berengal>O(n^2) looks like
17:45:03<Berengal>So assuming I want a sorted nubbed list, map head. group . sort is the way to go, right?
17:45:16<Gracenotes>well...
17:45:16<lilac>Berengal: yep.
17:45:18<Gracenotes>@src groupBy
17:45:19<lambdabot>groupBy _ [] = []
17:45:19<lambdabot>groupBy eq (x:xs) = (x:ys) : groupBy eq zs
17:45:19<lambdabot> where (ys,zs) = span (eq x) xs
17:45:31<Gracenotes>hm. better, it seems.
17:45:37<pejo>lilac, is that how it's implemented in the Prelude as well?
17:45:58<lilac>pejo: i believe so.
17:46:08<lilac>(or at least something equivalent)
17:46:27<Berengal>Or are sets the way to go?
17:46:28<tombom>why is it implemented like that if it's so bad
17:46:45<frankks>@src (\\)
17:46:46<lambdabot>(\\) = foldl (flip delete)
17:46:54<mmorrow_>> let histo = sortBy (flip compare `on` snd) . Map.toList . (\m -> let n = fromIntegral (Map.size m) in Map.map (\x -> fromIntegral x / n) m) . foldl' (\m a -> Map.insertWith' (+) a 1 m) mempty in histo "four frolicking foxes flitted feverishly through the furrow"
17:46:56<lambdabot> [(' ',0.35),('f',0.3),('r',0.3),('e',0.25),('o',0.25),('h',0.2),('i',0.2),(...
17:47:02<lilac>pejo: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html
17:47:24<Berengal>tombom: I assume it's because nub preserves order
17:47:29<copumpkin>zomg histo! zygohistomorphic prepromorphism?
17:47:35<mmorrow_>the r's snuck in there unnoticed
17:47:39<lilac>tombom: nub preserves order and doesn't require a (<)
17:47:50<mmorrow_>at the expense of O(n^2)
17:48:01<Gracenotes>real nubBy, coming through
17:48:04<tombom>are thanks
17:48:09<tombom>*ah oops
17:48:24<Gracenotes>nubBy eq l = nubBy' l []
17:48:26<Gracenotes> where nubBy' [] _ = []
17:48:28<Gracenotes> nubBy' (y:ys) xs | elem_by eq y xs = nubBy' ys xs
17:48:30<Gracenotes> | otherwise = y : nubBy' ys (y:xs)
17:48:31<Gracenotes>elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool (sort of an 'or' for two parameters)
17:48:44<mmorrow_>Berengal: i'd do Set.fromList . Set.toList probably
17:48:51<mmorrow_>err
17:49:01<mmorrow_>Set.toList . Set.fromList
17:49:03<Berengal>mmorrow_: Reverse those
17:49:06<mmorrow_>heh
17:49:12<lilac>Gracenotes: still quadratic though
17:49:15<Gracenotes>the real nubBy is.. .still
17:49:17<Gracenotes>yeah
17:49:21<Berengal>Yeah, that should work fine. Doesn't look as impressive though :P
17:49:45<Gracenotes>lilac: it might be possible to make a more fine-tuned version that's O(n)
17:49:57<copumpkin>nope
17:50:01<lilac>not for a general datatype
17:50:03<Gracenotes>...maybe. If you have an accumulator of the variable-to-be-compared-to?
17:50:03<Berengal>Gracenotes: I believe O(n) requires a sorted list
17:50:04<copumpkin>unless you know something beforehand
17:50:12<Gracenotes>value that is
17:50:40<frankks>O(n) is an unsorted list I think. Because it's possible you will have to look at every element to find what you're searching for
17:50:54<copumpkin>frankks: that's just for finding one element though
17:51:18<frankks>(didn't read it in context. oops.)
17:51:19<copumpkin>if you're searching for n elements, you get O(n^2)
17:51:27<Berengal>Well, if there's only a few values in the type being nubbed, such as Ordering, you could get O(n)...
17:51:53<Gracenotes>maybe I'm thinking of a different algorithm from the one actually implement
17:51:57<Gracenotes>ed
17:51:57<copumpkin>if you assume a hashtable is O(1), and everything is hashable, then maybe
17:52:29<Gracenotes>but, for instance, nubBy (==) [1,2,3,4,3,2,2]. You just check adjacent elements, and if you find a run, keep following it and continue at the end
17:52:39<lilac>> const 0 M.fromList
17:52:41<lambdabot> /tmp/4852686047885518090:70:44: Not in scope: `M.fromList'
17:52:42<lilac>@type M.fromList
17:52:44<lambdabot>forall k a. (Ord k) => [(k, a)] -> M.Map k a
17:52:45<lilac>:(
17:52:48<Gracenotes>Map.
17:52:52<tibbe_>I was playing around a bit with the Haddock CSS: http://johantibell.com/haddock/Network-Socket-ByteString.html
17:52:55<copumpkin>Gracenotes: that wouldn't work?
17:52:59<tibbe_>tibbe_: pretty much stolen from Google
17:52:59<Twey>Gracenotes: I think nubBy checks previous elements
17:53:03<tibbe_>but I find it pretty
17:53:14<Twey>> nub [1, 2, 1]
17:53:15<lambdabot> [1,2]
17:53:17<lilac>Gracenotes: that returns [1,2,3,4] not [1,2,3,4,3,2]
17:53:23<Gracenotes>oh. that sucks
17:53:39<Gracenotes>but no other way to do it of course.
17:53:40<copumpkin>if you have an ord, you can do it in nlogn time with map head . group . sort
17:53:41<Berengal>nubBy does a filter on the remaining list
17:53:46<Gracenotes>groupBy is more lenient
17:54:08<Gracenotes>argh. they're not complements at all
17:54:26<copumpkin>tibbe_: I like it, but the header looks ugly, and that lambda in the upper right corner in particular must go
17:54:33<copumpkin>tibbe_: but the body of the text looks nice
17:54:50<tibbe_>copumpkin: it's the standard heading, I didn't do anything to that part
17:54:57<FunctorSalad_>maybe nub has rewrite rules for the common cases
17:54:59<copumpkin>tibbe_: yeah :) exactly
17:54:59<FunctorSalad_>?
17:55:11<copumpkin>I'd definitely support replacing the default haddock css with the one you made
17:55:21<copumpkin>FunctorSalad_: not as far as I've seen
17:55:38<Gracenotes>:⍵
17:55:47<mauke>ω̈
17:55:52<FunctorSalad_>copumpkin: hmm, I seemed to remember something about the sort-based nub not being faster after all in some simple example
17:55:57<FunctorSalad_>but not sure
17:56:06<copumpkin>it wouldn't be safe to do a nub replace any Ord instance's nub with a map head . group . sort
17:56:12<copumpkin>because one isn't lazy
17:56:22<mauke>> nub [2,1]
17:56:23<lambdabot> [2,1]
17:56:29<FunctorSalad_>oh
17:56:31<copumpkin>oh, and also it doesn't maintain order :P
17:56:40<FunctorSalad_>hmm ok
17:56:52<copumpkin>but the nub can lazily consume the entire list too
17:56:52<Gracenotes>╳╳╳╳╳╳╳╳╳╳
17:57:06<mauke>> nub [0..]
17:57:07<lambdabot> [0,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,...
17:57:12<Hunner>What in the world are those?
17:57:19<lilac>> map ($"four frolicking foxes flitted feverishly through the furrow") [nub, fmap snd . toList . fromList . fmap (snd &&& fst) . toList . fromList . flip zip [0,-1..] . reverse]
17:57:19<mauke>U+2573 (e2 95 b3): BOX DRAWINGS LIGHT DIAGONAL CROSS [╳]
17:57:20<lambdabot> Not in scope: `toList'Not in scope: `fromList'Not in scope: `toList'Not in ...
17:57:58<copumpkin>tibbe_: one minor point is that I feel the type signature of a function could be separated more from the text describing it... it's noticeable with your recvFrom function
17:58:02<Gracenotes>> nub [0..] !! 100000
17:58:14<tibbe_>copumpkin: I agree
17:58:18<lambdabot> thread killed
17:58:27<tibbe_>copumpkin: didn't do anything there either, the markup really needs to be cleaned up
17:58:32<copumpkin>yeah :)
17:58:38<tibbe_>copumpkin: it's pretty gruesome
17:58:39<Berengal>Gracenotes: Welcome to O(n^2)
17:58:51<copumpkin>> nub [0..] !! 100
17:58:53<lambdabot> 100
17:58:54<copumpkin>whee!
17:58:55<Gracenotes>well. I had to try out some values in ghci
17:58:57<copumpkin>I win
17:58:58<lilac>@type map snd . M.toList . M.fromList . map (snd &&& fst) . M.toList . M.fromList . flip zip [0,-1..] . reverse]
17:59:00<lambdabot>parse error on input `]'
17:59:01<lilac>17:57 < mauke> U+2573 (e2 95 b3): BOX DRAWINGS LIGHT DIAGONAL CROSS [╳]
17:59:04<FunctorSalad_>fasterNub = go mempty where { go seen (x:xs) | member x seen = go xs; go seen (x:xs) = x:(go (insert x seen) xs); go _ [] = [] }
17:59:05<Gracenotes>the rest of them didn't grow so fast >_>
17:59:17<lilac>gah damn copy-past grr
17:59:20<copumpkin>lol
17:59:20<FunctorSalad_>that would be lazy and preserve order I think, copumpkin
17:59:25<Gracenotes>FunctorSalad_: good point
17:59:39<lilac>@type map snd . M.toList . M.fromList . map (snd &&& fst) . M.toList . M.fromList . flip zip [0,-1..] . reverse
17:59:41<lambdabot>forall a. (Ord a) => [a] -> [a]
17:59:41<copumpkin>> let fasterNub = go mempty where { go seen (x:xs) | member x seen = go xs; go seen (x:xs) = x:(go (insert x seen) xs); go _ [] = [] } in fasterNub [0..]
17:59:42<lilac>^^ faster nub
17:59:43<lambdabot> Not in scope: `member'
17:59:44<Gracenotes>er, implementation, too.
17:59:51<Gracenotes>Set.
17:59:52<FunctorSalad_>err the mempty is supposed to be a Data.Set btw ;)
17:59:54<Gracenotes>dot
18:00:07<copumpkin>> let fasterNub = go Set.mempty where { go seen (x:xs) | Set.member x seen = go xs; go seen (x:xs) = x:(go (Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..]
18:00:08<lambdabot> Failed to load interface for `Set':
18:00:08<lambdabot> Use -v to see a list of the ...
18:00:20<copumpkin>FunctorSalad_: if it's Data.Set, it'd be n log n again though
18:00:23<FunctorSalad_>hmm lambda doesn't have Set? :(
18:00:23<copumpkin>but I guess better than sort
18:00:24<Gracenotes>or... Data.Set.
18:00:30<Berengal>@type S.toList
18:00:31<lambdabot>forall a. S.Set a -> [a]
18:00:43<copumpkin>I hate that @type has a different namespace setup than >
18:00:44<lilac>Cale! Data.Set and Data.Map aren't working in lambdabot! ;-(
18:00:46<Gracenotes>namespaces for Sets and Maps and ByteStrings are effed up
18:00:59<dons>why?
18:00:59<copumpkin>> let fasterNub = go Data.Set.mempty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..]
18:01:02<lambdabot> Not in scope: `Data.Set.mempty'
18:01:04<Gracenotes>and anything else that's qualified in L.js
18:01:06<Gracenotes>*hs
18:01:07<FunctorSalad_>mempty is in Monoid...
18:01:10<copumpkin>> let fasterNub = go mempty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..]
18:01:11<lambdabot> Add a type signature
18:01:12<lilac>> const True Data.Map.fromList
18:01:12<copumpkin>yeah, I realized that :P
18:01:13<lambdabot> /tmp/4946381460955546030:70:43: Not in scope: `Data.Map.fromList'
18:01:16<Cale>lilac: 本当に?まったく…
18:01:17<FunctorSalad_>I think there's also Data.Set.empty
18:01:34<mauke>> M.fromList []
18:01:35<lambdabot> /tmp/513599841387006425:70:32: Not in scope: `M.fromList'
18:01:36<copumpkin>> let fasterNub = go Data.Set.empty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] :: [Int]
18:01:37<lambdabot> Couldn't match expected type `[t]' against inferred type `S.Set t'
18:01:38<Cale>> let fasterNub = go mempty where { go seen (x:xs) | S.member x seen = go xs; go seen (x:xs) = x:(go (S.insert x seen) xs); go _ [] = [] } in fasterNub [0..]
18:01:40<lambdabot> Add a type signature
18:01:43<mauke>my emperor!
18:01:44<copumpkin>I give up :)
18:01:45<Berengal>Data.Set is called S, Data.Map is called M, simple as that
18:01:51<Gracenotes>ugh. more screwed up than usual?
18:01:55<Cale>> S.empty
18:01:55<copumpkin>Berengal: except if you ask for @type
18:01:57<lambdabot> /tmp/521710655770533761:70:32: Not in scope: `S.empty'
18:01:59<Cale>...
18:02:00<Cale>hmm
18:02:11<Gracenotes>> Set.empty
18:02:12<lambdabot> fromList []
18:02:14<Gracenotes>> Data.Set.empty
18:02:15<lambdabot> /tmp/2311465051563539008:70:32: Not in scope: `Data.Set.empty'
18:02:17<Gracenotes>wha
18:02:25<FunctorSalad_>whoa
18:02:34<copumpkin>> let fasterNub = go Set.empty where { go seen (x:xs) | Set.member x seen = go xs; go seen (x:xs) = x:(go (Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] :: [Int]
18:02:35<lambdabot> Couldn't match expected type `[t]' against inferred type `S.Set t'
18:02:39<FunctorSalad_>@let emptySet = S.empty
18:02:40<lambdabot> Defined.
18:02:42<FunctorSalad_>yay
18:02:42<copumpkin>okay, not my fault
18:03:02<FunctorSalad_>@let insertSet = S.insert
18:03:03<lambdabot> Defined.
18:03:11<FunctorSalad_>@let memberSet = S.member
18:03:12<lambdabot> Defined.
18:03:13<copumpkin>this is ugly
18:03:17<FunctorSalad_>=)
18:03:24<lilac>> Map.fromList []
18:03:26<lambdabot> fromList []
18:03:27<Gracenotes>hm. I don't see where the type error is.
18:03:44<Gracenotes>Oh! the recursive case for Set.member x seen doesn't have enough params
18:04:00<FunctorSalad_>sorry
18:04:00<lilac>@check \xs -> (map snd . Map.toList . Map.fromList . map (snd &&& fst) . Map.toList . Map.fromList . flip zip [0,-1..] . reverse) xs == nub xs
18:04:02<lambdabot> "OK, passed 500 tests."
18:04:08<lilac>yay, fast nub success
18:04:24<lilac>@hoogle (a, b) -> (b, a)
18:04:25<lambdabot>System.Random randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g)
18:04:25<lambdabot>Control.Arrow (^<<) :: Arrow a => (c -> d) -> a b c -> a b d
18:04:25<lambdabot>Control.Arrow (<<<) :: Arrow a => a c d -> a b c -> a b d
18:04:27<Gracenotes>Set is sorta fine... too...
18:04:34<copumpkin>> (map snd . Map.toList . Map.fromList . map (snd &&& fst) . Map.toList . Map.fromList . flip zip [0,-1..] . reverse) [0..]
18:04:47<copumpkin>tsk tsk :)
18:04:51<lilac>copumpkin: ;-)
18:04:54<Gracenotes> Thread keeled
18:04:57<lambdabot> thread killed
18:04:59<copumpkin>don't keel!
18:05:13<lilac>ACTION is clearly inadequately lazy
18:06:05<FunctorSalad_>@let fasterNub = go emptySet where { go seen (x:xs) | memberSet x seen = go seen xs; go seen (x:xs) = x:(go (insertSet x seen) xs); go _ [] = [] }
18:06:19<Gracenotes>Defined. . ... . .(>)
18:06:25<FunctorSalad_>hehe
18:06:25<Gracenotes>still. lots of GC overhead from the more "efficient" nubs
18:06:34<Gracenotes>that is the constant!
18:06:55<Fred320>@src foldr
18:07:03<Cale>> Set.empty
18:07:13<FunctorSalad_>lambdabot has gone home?
18:07:16<Cale>Oh, what did you do!?
18:07:18<Cale>hehe
18:07:35<copumpkin>ACTION strokes lambdabot
18:07:39<Cale>Probably just have to wait, it'll come back.
18:07:53<Cale>It was running for months unattended.
18:08:03<Gracenotes>ACTION tickles lambdabot
18:08:20<lilac>copumpkin: interim pumpkinbot time?
18:08:38<copumpkin>I can bring him (her?) in if you think I should
18:08:56<lilac>copumpkin: i feel cold and lonely without a lambdabot here
18:09:26<FunctorSalad_>Gracenotes: any better idea with respect to GC?
18:09:47<Gracenotes>uh. binary heaps with mutable arrays? :)
18:09:49<copumpkin>lambdabot authentication is so sophisticated ;)
18:10:04<Gracenotes>Haskell is a heavily GC'd language any way you put it...
18:10:25<lilac>> Set.empty
18:10:26<pumpkinbot> Failed to load interface for `Set':
18:10:26<pumpkinbot> Use -v to see a list of the ...
18:10:31<copumpkin>lol
18:10:37<copumpkin>> S.empty
18:10:38<pumpkinbot> mueval: Prelude.read: no parse
18:10:41<copumpkin>fail
18:10:45<Raevel>copumpkin: hah, i had to do the exact same thing earlier
18:10:46<lilac>> fail "fail!"
18:10:47<pumpkinbot> No instance for (Show (m a))
18:10:47<pumpkinbot> arising from a use of `show' at <in...
18:10:50<FunctorSalad_>> fix fail
18:10:52<pumpkinbot> ""
18:10:58<copumpkin>wow, it really fails
18:11:03<lilac>lol
18:11:21<FunctorSalad_>oh, list monad
18:11:22<copumpkin>no Data.Set for you!
18:11:57<lilac>well that's no fun at all
18:12:05<copumpkin>:(
18:12:05<ray>no set monad for you
18:12:11<copumpkin>rmonad!
18:12:20<copumpkin>maybe I'll get RMonad on my bot
18:12:43<copumpkin>> text "Segmentation fault"
18:12:45<pumpkinbot> Segmentation fault
18:12:53<ray>> text "thread killed"
18:12:54<pumpkinbot> thread killed
18:12:56<copumpkin>wow, my lambdabot barfs every time someone sends a message
18:13:00<copumpkin>not only to it
18:13:06<copumpkin>Main: caught (and ignoring) too few bytes. Failed reading at byte position 8
18:13:07<Gracenotes>lol
18:13:12<copumpkin>that's what it says every time anyone says anything
18:13:24<Gracenotes>CATCH THIS, PUMPYBOT!
18:13:36<copumpkin>just a sec
18:14:11<copumpkin>how is it that screen's keys are always so messed up
18:14:48<FunctorSalad_>is there some simple way to make stuff clickable in an opengl scene?
18:14:53<FunctorSalad_>:(
18:15:09<lambdabot> Defined.
18:15:09<lambdabot>foldr f z [] = z
18:15:09<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
18:15:11<lambdabot> mueval: Prelude.read: no parse
18:15:12<lambdabot> mueval: GhcException mkTopLevEnv: not a hom...
18:15:14<lambdabot> Terminated
18:15:21<FunctorSalad_>I think I'll make "clickability centers" and see which center is closest to the line clicked on
18:15:37<FunctorSalad_>sounds way easier than calculating the intersection with actual geometry
18:15:56<Gracenotes>> "hello thar"
18:15:58<lambdabot> "hello thar"
18:16:03<lilac>@type map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty)
18:16:04<lambdabot>Couldn't find qualified module.
18:16:20<lilac>@type map fst . filter (not . uncurry S.member) . (zip `ap` scanl (flip S.insert) S.empty)
18:16:21<lambdabot>forall b. (Ord b) => [b] -> [b]
18:16:36<lilac>@check \xs -> map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ xs == nub xs
18:16:37<lambdabot> Couldn't match expected type `[b]' against inferred type `Bool'
18:16:49<lilac>@check \xs -> (map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ xs) == nub xs
18:16:50<lambdabot> "OK, passed 500 tests."
18:17:01<lilac>> map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) [0..]
18:17:02<lambdabot> Couldn't match expected type `a -> [(a1, S.Set a1)]'
18:17:08<lilac>> map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ [0..]
18:17:10<lambdabot> [0,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,...
18:17:12<lilac>hooray
18:17:34<lilac>@hoogle scanl'
18:17:35<lambdabot>No results found
18:20:07<Fred320>@src fold
18:20:07<lambdabot>Source not found. Where did you learn to type?
18:20:09<Fred320>@src foldl
18:20:09<lambdabot>foldl f z [] = z
18:20:10<lambdabot>foldl f z (x:xs) = foldl f (f z x) xs
18:20:13<lilac>FunctorSalad_: render each of your objects in turn (nearest first) offscreen onto a pbuffer, then check to see if the depth buffer is set at the clicked point
18:20:19<lilac>*ducks*
18:20:45<lilac>@type let fasterNub = map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) in fasterNub
18:20:46<lambdabot>Couldn't find qualified module.
18:21:20<FunctorSalad_>hmm I'd have to look up "pbuffer"
18:21:37<ray>it's short for pteriffic buffer
18:22:19<Fred320>@src foldr
18:22:19<lambdabot>foldr f z [] = z
18:22:20<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
18:27:45<Cale>Fred320: A good way to think about how foldr f z works is that it replaces each (:) in the list with f and the [] at the end with z
18:28:08<Fred320>thanks... i just wrote my own folds for exercise and wanted to compare to the original
18:28:13<Cale>:)
18:28:58<Fred320>i had a hard time understanding the difference between left and right fold at first, but that was only because the first examples produce a t form a list of t, and the often it does not matter which fold you choose
18:29:03<Cale>foldr has the rather nice property that after each recursive step, the next thing to evaluate is always f, so if f doesn't need its second parameter, the foldr never continues
18:29:06<Fred320>for example fold (+) 0 [1,2,3]
18:29:38<Fred320>and foldl has the nice property of being tail recursive :)
18:29:44<Cale>Whereas foldl always just calls itself selfishly until it reaches the end of the list. So it will never work on infinite lists.
18:30:23<tetha>hm, this is fun on a very strange level. I started with removing redundancy and now Im implementing symbolic simplications with neutral and absorbing elements
18:30:41<zoheb>@pl (\x -> if (x > 0) then fact (x-1) else 1
18:30:42<lambdabot>(line 1, column 41):
18:30:42<lambdabot>unexpected end of input
18:30:42<lambdabot>expecting digit, variable, "(", operator or ")"
18:30:45<zoheb>@pl (\x -> if (x > 0) then fact (x-1) else 1)
18:30:46<lambdabot>flip (liftM2 if' (> 0) (fact . subtract 1)) 1
18:30:49<tetha>(in some hobby-expression-evaluator, that is)
18:31:07<zoheb>@type liftM2
18:31:08<lambdabot>forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
18:31:25<Cale>The tail recursiveness of foldl can be a useful property to exploit, but since lazy evaluation doesn't use a stack in the same way as the evaluators for most strict languages use one, it's less critical.
18:31:30<Fred320>Cale: the fold really clicked for me with rev = foldl (flip (:)) []
18:31:34<Cale>yeah :)
18:32:01<Fred320>and of course app xs ys = foldr (:) ys xs
18:32:37<Fred320>> foldr (:) "world!" "hello "
18:32:38<lambdabot> "hello world!"
18:32:51<Cale>The occasional trouble with foldl is when you give it a function that can't build something immediately using its second parameter. It can build up a very large expression before giving it any chance to be evaluated.
18:32:53<zoheb>@pl (\x -> if (x > 0) then x*fact (x-1) else 1)
18:32:53<lambdabot>flip (liftM2 if' (> 0) (ap (*) (fact . subtract 1))) 1
18:32:54<Cale>For example...
18:32:58<Cale>foldl (+) 0 [1,2,3]
18:33:04<Cale>-> foldl (+) (0+1) [2,3]
18:33:09<Cale>-> foldl (+) ((0+1)+2) [3]
18:33:14<Cale>-> foldl (+) (((0+1)+2)+3) []
18:33:19<Cale>-> ((0+1)+2)+3
18:33:27<Fred320>That's what foldl' is for, right?
18:33:30<Cale>Yeah
18:33:39<Cale>Those steps I just showed didn't use any stack.
18:34:14<FunctorSalad_>is whnf the thing seq forces?
18:34:15<Cale>But now, evaluating this result will require the stack, because (...) + 3 can't immediately result in something
18:34:20<Cale>FunctorSalad_: yes
18:34:48<FunctorSalad_>hmm
18:34:55<Fred320>@src reverse
18:34:55<lambdabot>reverse = foldl (flip (:)) []
18:34:59<Cale>FunctorSalad_: WHNF means evaluate up to determining the top-level constructor, and if you just have a lambda, leave it alone.
18:35:22<FunctorSalad_>I see
18:35:40<Cale>(that is, don't start evaluating inside it)
18:37:02<Wraithan>Ooo, a local code get together and they have a haskell session
18:37:07<Wraithan>Think I will go attend that
18:37:07<Cale>Fred320: So, (...) + 3 will get pushed on the stack, and then (...) + 2, and then we'll reach (0+1) which will evaluate, and we'll start coming back up.
18:37:11<Wraithan>http://portlandcodecamp.org/sessions.aspx?tag=Haskell
18:37:18<zoheb>@type liftM2 if'
18:37:19<lambdabot>Not in scope: `if''
18:38:00<Cale>Fred320: If the list was very long, this might blow up the stack, so foldl' solves the problem by forcing the evaluation of the accumulating parameter on each step.
18:38:11<Fred320>@src foldl'
18:38:12<lambdabot>foldl' f a [] = a
18:38:12<lambdabot>foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
18:38:12<Cale>That way, the expression never gets very large
18:38:26<Fred320>thanks
18:38:33<Cale>foldl' (+) 0 [1,2,3]
18:38:41<zoheb>@type liftM2 if'
18:38:42<lambdabot>Not in scope: `if''
18:38:46<Cale>-> let y = 0 + 1 in foldl' (+) y [1,2,3]
18:38:50<Cale>oops
18:38:57<Cale>-> let y = 0 + 1 in y `seq` foldl' (+) y [1,2,3] -- rather
18:39:08<zoheb>@type liftM2 (\x y z -> if x then y else z)
18:39:09<Cale>-> let y = 1 in foldl' (+) y [1,2,3]
18:39:09<lambdabot>forall a2 (m :: * -> *). (Monad m) => m Bool -> m a2 -> m (a2 -> a2)
18:39:22<Fred320>you mwean [2,3]
18:39:24<Cale>damn, I'm making mistakes ;)
18:39:25<Cale>yes
18:39:30<Fred320>i get it ;)
18:39:42<Cale>But yeah, it'll evaluate the 0+1 before recursing
18:39:56<Cale>and then the 1+2, and then the 3+3
18:40:08<Cale>so that by the time it's done, the 6 will already be evaluated
18:40:13<zoheb>@type liftM2 (\x y z -> if x then y else z) True
18:40:14<lambdabot> Couldn't match expected type `m Bool' against inferred type `Bool'
18:40:14<lambdabot> In the second argument of `liftM2', namely `True'
18:40:18<Cale>> foldl (+) 0 [1..1000000]
18:40:21<lambdabot> * Exception: stack overflow
18:40:23<Cale>> foldl' (+) 0 [1..1000000]
18:40:25<lambdabot> 500000500000
18:40:29<zoheb>@type liftM2 (\x y z -> if x then y else z) (Just True)
18:40:30<lambdabot>forall a2. Maybe a2 -> Maybe (a2 -> a2)
18:40:33<Cale>It can make a difference :)
18:40:56<zoheb>@type ap
18:40:57<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
18:40:58<stroan>@src foldl'
18:40:59<lambdabot>foldl' f a [] = a
18:40:59<lambdabot>foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
18:41:57<zoheb>@type liftM2 (\x y z -> if x then y else z) (> 0)
18:41:58<lambdabot>forall a2 a. (Ord a, Num a) => (a -> a2) -> a -> a2 -> a2
18:42:42<paper_cc>is it possible to define an alias for a type context? (for example, I want to write (IsKeyType k) instead of (Ord k, Typeable k))
18:42:56<FunctorSalad_>paper_cc: it's a proposal :(
18:43:10<FunctorSalad_>paper_cc: a workaround is CPP
18:43:11<zoheb>Is -> a Monad?
18:43:20<paper_cc>zoheb: no
18:43:23<ray>((->) e) is
18:43:39<zoheb>ray what does that mean?
18:43:56<ray>functions from some type e
18:43:56<zoheb>I am trying to make sense of the following
18:44:01<paper_cc>FunctorSalad: :-/
18:44:05<zoheb>@type liftM2 (\x y z -> if x then y else z)
18:44:06<lambdabot>forall a2 (m :: * -> *). (Monad m) => m Bool -> m a2 -> m (a2 -> a2)
18:44:16<zoheb>@type liftM2 (\x y z -> if x then y else z) (> 0)
18:44:17<lambdabot>forall a2 a. (Ord a, Num a) => (a -> a2) -> a -> a2 -> a2
18:44:35<zoheb>Am I using the ((->) e) monad here?
18:44:47<FunctorSalad_>we need some agreed syntax for type meta-variables
18:44:53<paper_cc>zoheb: yes
18:45:07<paper_cc>FunctorSalad_: type meta-variables == ?
18:45:08<FunctorSalad_>(->) E is a monad for every type E
18:45:18<ray>yeah, (> 0) is your m Bool there
18:45:25<ray>in this case, m Bool is e -> Bool
18:45:44<zoheb>ok
18:45:54<FunctorSalad_>hmm
18:45:56<frankks>@src (\\)
18:45:57<lambdabot>(\\) = foldl (flip delete)
18:46:12<FunctorSalad_>I'm a bit confuse
18:46:26<ray>i'm a confusion bit
18:47:14<FunctorSalad_>so do we really mean the monad that maps some type A to the polymorphic type e -> A?
18:47:27<kpreid>confusionBit <- [(False)..]
18:47:38<FunctorSalad_>that type would be a bit pointless
18:48:07<paper_cc>FunctorSalad_: to a *monomorphic* type E -> A for some fixed E
18:48:20<FunctorSalad_>paper_cc: right, that's the ambiguity I meant
18:48:29<paper_cc>aha =)
18:48:29<Cale>FunctorSalad_: No, for *each* e, (->) e is a monad.
18:48:43<Cale>right
18:48:54<paper_cc>@quote fugue
18:48:55<lambdabot>monochrom says: Welcome to #haskell, where your questions are answered in contrapuntal fugues.
18:48:55<FunctorSalad_>Cale: that's what I was trying to say with "e is a meta-variable"
18:49:03<FunctorSalad_>since a type variable makes polymorphic types...
18:49:12<zoheb>I can't find source definitions for the ((->),e) Monad, is it built into the compiler?
18:49:27<copumpkin>control.monad.instances
18:49:34<ray>they have this silly Reader thing
18:49:36<paper_cc>zoheb: no. essentially ((->) e) is the same as (Reader e)
18:49:37<Cale>lol, there's a video here of a top US starcraft player playing in 26 poker games at once.
18:49:41<frankks>could anyone explain what flip delete 'basically' does?
18:49:45<Cale>They accused him of using bots.
18:50:06<ray>a top starcraft player? only 26 poker games?
18:50:10<copumpkin>:t delete
18:50:12<lambdabot>forall a. (Eq a) => a -> [a] -> [a]
18:50:12<Cale>ray: Well, US.
18:50:19<copumpkin>> delete 2 [1..10]
18:50:21<paper_cc>frankks: well, (flip delete) is the same as delete, but with arguments flipped =)
18:50:21<lambdabot> [1,3,4,5,6,7,8,9,10]
18:50:25<Cale>ray: Probably the korean guys could do 100 ;)
18:50:28<copumpkin>> flip delete [1..10] 2
18:50:30<lambdabot> [1,3,4,5,6,7,8,9,10]
18:50:45<ray>a top korean starcraft player could play 26 poker games at once while also playing starcraft
18:50:50<Cale>haha
18:51:04<copumpkin>:t foldr delete
18:51:05<lambdabot>forall a. (Eq a) => [a] -> [a] -> [a]
18:51:11<tetha>Cale: a korean starcraft player could play so many poker games that joining them takes longer than the first poker game! ;)
18:51:14<copumpkin>that's a useful function :P
18:51:37<copumpkin>> foldr delete [] [1..10]
18:51:38<copumpkin>mmm
18:51:38<lambdabot> []
18:51:39<copumpkin>:P
18:51:55<Cale>> foldr delete [1..10] [2,4,7]
18:51:57<lambdabot> [1,3,5,6,8,9,10]
18:52:05<FunctorSalad_>I guess the difference is between (pseudo-haskell) "forall e. instance Monad (\a -> e -> a)" and "instance Monad (\a -> forall e. e -> a)"
18:52:13<gwern>anyone familiar with this error in cabal?
18:52:14<gwern>Preprocessing library HaskellForMaths-0.1...
18:52:14<gwern>c:\Program Files\GnuWin32\bin\tar.exe: Cannot fork: Function not implemented
18:52:15<gwern>c:\Program Files\GnuWin32\bin\tar.exe: Error is not recoverable: exiting now
18:52:19<gwern>(sdist)
18:52:19<Cale>FunctorSalad_: yeah
18:52:35<gwern>no dcoutts is not here!
18:52:47<Cale>gwern: Looks like you have a broken implementation of posix
18:53:10<paper_cc>gwern: maybe you should use Cygwin?
18:53:17<gwern>Cale: oh, it's not me. I'm not on windows thank goodness. but I was wondering if tar was installed at all, but I guess that doesn't match
18:55:22<PetRat>test
18:56:03<PetRat>I'm working some exercises in typeclassopedia. One of them is implementing liftM in terms of >>= and return. I get liftM g x = x >>= return . g ?
18:56:32<Cale>yep
18:56:47<Cale>:t \g x -> x >>= return . g
18:56:48<lambdabot>forall a b (m :: * -> *). (Monad m) => (a -> b) -> m a -> m b
18:57:33<Cale>It's prettier in terms of =<< and return
18:57:40<Cale>return . g =<< x
18:57:43<edwardk>@seen saizan
18:57:44<lambdabot>saizan is in #haskell-in-depth, #ghc, #haskell-soc, #haskell-blah, #haskell-overflow, #haskell.it and #haskell. I don't know when saizan last spoke.
18:58:20<byorgey>@pl \g x -> x >>= return . g
18:58:21<lambdabot>fmap
18:58:34<ray>tee hee
18:58:55<byorgey>nice! I didn't realize that @pl knows all monads are functors =)
18:59:29<PetRat>Cale: because it says intuitively "return (inject) the result of applying g to x"?
18:59:37<SamB>it does, in fact, know things that Haskell 98 does not know :-(
18:59:41<edwardk>byorgey: i suppose it could say 'liftM' to be a little more correct
18:59:55<Cale>PetRat: That it applies g to the result of executing x
18:59:56<byorgey>it could.
19:00:20<frankks> have a variable a, which is a list if strings [(string),(string),(string)] etc, and a variable t which is, ([(string),(string),(string)..],[[(string),(string),(string)..]]) - and the expression (a\\(fst t)). I understand it outputs what I want it to, but I can't work out exactly what \\ is doing. Can anyone explain?
19:00:26<Cale>PetRat: In do-notation, it'd be liftM g x = do v <- x; return (g v)
19:00:26<frankks>(sorry for wall of text..)
19:00:37<SamB>but this way, @pl helps us find library bugs
19:00:54<Cale>frankks: \\ is list subtraction
19:01:07<byorgey>frankks: well, if t is a pair of two lists, then fst t is the first of the two lists
19:01:23<Cale>> "mississippi" \\ "miss piggy"
19:01:23<frankks>so it's subtracting the first element from the list t ?
19:01:25<lambdabot> "ssipi"
19:01:32<byorgey>oh, you're asking about \\ in particular. sorry =)
19:01:55<Cale>It removes elements of the second list from the first list.
19:02:04<byorgey>but only one of each.
19:02:07<byorgey>> [1,1,1] \\ [1]
19:02:08<Cale>right
19:02:09<lambdabot> [1,1]
19:02:15<Cale>> [1,1,1] \\ [1,1]
19:02:17<lambdabot> [1]
19:02:24<edwardk>oh, nice, i was thinking about an iterative deepening monad for a toy parser and found that Sebastian Fischer already wrote one.
19:02:37<frankks>ok thanks chaps
19:03:20<gwern>iterative deepening? == breadth-first?
19:04:05<tetha>gwern: limited depth first with increasing limit
19:04:11<edwardk>iterative deepening is depth-first-search to a fixed bound that you keep increasing as you go, starting from 1. so you get the traversal of BFS, with the space efficiency of DFS at the cost of retraversing stuff near the root
19:04:30<gwern>hm. interesting compromise
19:04:41<edwardk>if your branching factor is high you get a huge space win in exchange for a small recomputation cost.
19:05:03<edwardk>i.e. 10-11% extra computation for a branching factor of 10 but huge asymptotic space wins
19:06:04<edwardk>its commonly used in little chess engines, etc. because it combines really really nicely with MTD-f
19:08:23<paper_cc>is it possible to write a Map with keys of type (forall a. Boxed a => Box a), provided that (Boxed a) => (Ord a)?
19:08:46<copumpkin>how would it compare keys of different types?
19:09:14<edwardk>i basically had the strange idea of trying to see if i can improve the asymptotics of a weird parser by treating it like a game, either of parser against string or more likely of parsing top down vs. bottom up cutting off possible parses
19:09:48<gwern>go go game semantics?
19:10:01<edwardk>or much more simply parsing left to right and right to left simultaneously and pruning parses that conflict as i walk left to right and right to left towards the center
19:10:32<paper_cc>copumpkin: yes, it can't do that directly. Not specifically a Map, but a mapping type
19:10:49<copumpkin>I mean, for any mapping type
19:10:54<copumpkin>how would that happen?
19:10:56<paper_cc>ACTION found TypeRep -> IO Int
19:10:58<PetRat>Okay, next exercise is implement ap in terms of >>= and return. (I'm going to use liftM because I already did.) ap x y = x >>= \g -> liftM g y ??
19:11:22<PetRat>:t x >>= \g -> liftM g y
19:11:23<lambdabot> Couldn't match expected type `m a' against inferred type `Expr'
19:11:23<lambdabot> In the first argument of `(>>=)', namely `x'
19:11:23<paper_cc>copumpkin: I forgot :( (Boxed a) => Typeable a
19:11:46<dmwit>:t \x y -> x >>= \g -> liftM g y
19:11:48<lambdabot>forall (m :: * -> *) a1 b. (Monad m) => m (a1 -> b) -> m a1 -> m b
19:11:52<PetRat>:t \x y -> x >>= \g -> liftM g y
19:11:54<lambdabot>forall (m :: * -> *) a1 b. (Monad m) => m (a1 -> b) -> m a1 -> m b
19:12:27<PetRat>So the types match, which in monad land pretty much guarantees the implementation is correct, no?
19:14:29<frankks>> [2,3,4] \\ [4]
19:14:31<lambdabot> [2,3]
19:14:47<frankks>> [4,3,2] \\ [4]
19:14:49<lambdabot> [3,2]
19:15:36<Athas``>How widespread is Template Haskell in practice?
19:16:52<sjanssen>Athas``: it's not used incredibly frequently, but is used in some projects
19:20:12<paper_cc>copumpkin: so, is it impossible to use TypeReps as keys? (show for TypeRep seems inefficient)
19:21:24<copumpkin>paper_cc: so you'd compare the types of the keys and then their values if their types were equal?
19:21:59<paper_cc>copumpkin: yes, but there doesn't seem to be a stable key for TypeReps
19:23:17<copumpkin>paper_cc: I don't see why you shouldn't be able to use it though
19:23:33<copumpkin>the ordering of the keys is meaningless but should be enough for you to build a map
19:23:40<copumpkin>you can probably unsafePerformIO it too
19:23:48<copumpkin>that typeRepKey function, that is
19:24:40<copumpkin>its implementation just returns a value into IO
19:24:47<paper_cc>copumpkin: the docs say that it isn't guaranteed to be persistent across multiple program executions.
19:24:48<paper_cc>oh
19:24:54<paper_cc>ACTION looks up
19:24:57<copumpkin>well yeah, but neither is your Map
19:26:38<paper_cc>copumpkin: my Map represents a persistent cache and is marshalled between program executions
19:26:50<copumpkin>oh
19:28:43<PetRat>Okay, next exercise is implement sequence in terms of >>= and return (and liftM). How about seq' [] = return [] ;;; seq' (x:xs) = x >>= \y -> liftM (y:) (seq' xs) ???
19:29:34<PetRat>Is copumkin and pumkin be the same person?
19:30:05<jacobian>self dual?
19:30:07<Zao>I'd say it's his dual :P
19:30:53<copumpkin>yeah, I'm pumpkin's dual
19:31:00<copumpkin>(-core macbook pro)
19:31:39<jacobian>wow, that's a pretty complicated pun
19:32:11<copumpkin>lol, that wasn't why I started using it
19:32:29<copumpkin>it was poking fun at all the co- terms that get thrown around in this community :)
19:33:04<Zao>I'd say it's cofun.
19:34:01<PetRat>Can I use lambdabot to check my work in the above definition of sequence? how do I ask it for the type of a recursive function?
19:37:21<PetRat>:t \g xs -> sequence $ map g xs
19:37:22<lambdabot>forall (m :: * -> *) a a1. (Monad m) => (a1 -> m a) -> [a1] -> m [a]
19:40:08<copumpkin>has anyone made a SQL monad? basically a little DSL that is isomorphic to SQL?
19:40:41<Beelsebob>I thought about making something like that
19:40:54<Beelsebob>then got deep into "how can I make Haskell check my sql statements are type safe"
19:41:00<Beelsebob>and got bored
19:41:31<copumpkin>lol
19:43:39<sjanssen>copumpkin: haskelldb has one, I think?
19:46:14<copumpkin>I see
19:48:50<koeien>this is like HaskellDB, but that has bitrotted
19:49:30<Heffalump>copumpkin: SQL isn't really a monad
19:49:52<Heffalump>ACTION has done some work on a SQL DSL using associated type synonyms, but it's rather incomplete
19:51:09<monadic_kid>Heffalump: query comphrensions is probably what you want to look at
19:52:20<Heffalump>monadic_kid: as in the Wadler/SPJ paper?
19:56:02<voker57__>can i see usage examples of Text.JSON or RJson somewhere?
19:56:11<voker57__>like some app that uses on of those
19:56:55<voker57__>in google people tend to write JSON parsers themselves
19:57:39<edwardk>ACTION has a json parser in javascript already, its called eval ;)
19:58:22<voker57__>eh... is that #javascript?
19:58:32<gwern>voker57__: well, you could download all of hackage, untar it all, and grep for the package names :)
19:59:13<edwardk>voker57__: i tried talking in #javascript for a while, but they give me even more grief than the folks around here when I start talking about comonads.
19:59:26<Raevel>:-D
19:59:30<gwern>edwardk: they don'
19:59:36<gwern>t even being to have the background
19:59:59<gwern>so I don't really blame them. if someone came here chattering in lojban about epigram, we'd probably give them grief too
20:00:15<edwardk>i've seen a couple of javascript "monadic" parser combinator libraries and monad implementations.
20:00:16<Raevel>edwardk: maybe they'll listen after you rewrite their script so confirm stops no worky:ing
20:00:33<edwardk>gwern: nah i think there are at least 4-5 people on here that understand lojban ;)
20:00:39<Twey>.i zo'o mi se cinri la .epigram.
20:00:47<gwern>surely there can't be that many?
20:00:52<Twey>Think so
20:00:59<Heffalump>ACTION would still like to see a useful abstraction provided by comonads
20:01:00<Twey>There's a fairly substantial overlap between the communities
20:01:04<gwern>@seen
20:01:11<gwern>@users
20:01:12<edwardk>i've had several discussions on here about it with various folks
20:01:12<lambdabot>Maximum users seen in #haskell: 658, currently: 644 (97.9%), active: 23 (3.6%)
20:01:33<Twey>edwardk: eval() parses considerably more than JSON
20:01:36<edwardk>Heffalump: i trip over cofree comonads all over the place.
20:01:39<gwern>wait, if there are 23 active users, and 1 has claimed lojban knowledge, then I should infer that...
20:01:47<gwern>> 658 * (1/23)
20:01:49<lambdabot> 28.608695652173914
20:01:53<Twey>That's a fair few people
20:01:59<gwern>28 lojban users? -_-
20:02:02<edwardk>Twey: sure. and that was said slightly tongue in cheek. i understand the security reasons, etc. but its also hard to argue with parsing 50-100x faster ;)
20:02:08<Twey>gwern: Point six!
20:02:10<Raevel>more like 29!
20:02:35<gwern>Twey: sure, we'll count the headless armless torso in the corner over there
20:02:45<Twey>edwardk: Well, it is possible to do a check for valid JSON first, then apply eval() for the actual parsing
20:02:52<Twey>Don't know how worthwhile that is, though
20:02:59<Heffalump>edwardk: can you give an example of some generic code that is useful over such structures?
20:03:01<Twey>gwern: *grin*
20:04:36<edwardk>Heffalump: i have some comonadic cellular automata code around here somewhere, i use the cofree comonad for incremental folds, in particular i use it to annotate tree structures (applicatives) with sharing information in a reasonably safe manner
20:05:52<edwardk>Heffalump: g_cata is defined for any comonad you can find distributive laws for, there are a bunch of those which give rise to destructive half of Control.Morphism.* in category-extras
20:06:27<edwardk>i use those mostly as an aid for my thought patterns when i'm trying to figure out if a particular fold-like function can even exist
20:07:41<TomMD>Are there rational trig functions in prelude somewhere?
20:08:03<roconnor>rational trig functions? Like spread?
20:08:07<edwardk>another use i've had for them, which feeds back to the cofree comonad as fixed-point + incremental fold is for dealing with attribute grammars
20:08:22<TomMD>sin, cos, etc
20:08:36<roconnor>are those called rational trig functions?
20:08:38<edwardk>tomMD: like CORDIC versions of the traditional trig functions?
20:08:38<roconnor>anyhow
20:08:45<roconnor>> sin(pi/2)
20:08:46<TomMD>Rational being 'Ratio Integer'
20:08:47<lambdabot> 1.0
20:08:55<TomMD>> sin (pi / 2) :: Rational
20:08:56<lambdabot> No instance for (Floating Rational)
20:08:56<lambdabot> arising from a use of `pi' a...
20:09:02<TomMD>> sin (toRational pi / 2) :: Rational
20:09:03<lambdabot> No instance for (Floating Rational)
20:09:03<lambdabot> arising from a use of `sin' ...
20:09:06<Heffalump>edwardk: I guess I'd have to see some code to understand properly, but thanks
20:09:09<edwardk>tomMD: the problem is when do you stop. thats kind of the definition of Real vs. Rational ;)
20:09:20<roconnor>TomMD: you cannot get more transcendtal that trig functions.
20:09:39<edwardk>Heffalump: http://comonad.com/ my last post on incremental folds uses a cofree comonad, it just doesn't bother to call attention to it very much
20:09:48<roconnor>The defining property of real numbers is practically that you can do sin and cos in them.
20:10:09<joeally>What is the difference between LHC and GHC
20:10:13<TomMD>Damn reals
20:10:17<joeally>should I stick with GHC
20:10:25<TomMD>joeally: GHC is usable as a full compiler - so yes
20:10:33<joeally>okay
20:10:35<roconnor>well, the result of sin and cos are real numbers, You can easily pass them rational numbers.
20:10:36<TomMD>joeally: LHC has became a backend to GHC.
20:10:40<joeally>oh
20:10:43<roconnor>> sin (fromRational (5/2))
20:10:44<lambdabot> 0.5984721441039565
20:10:49<joeally>TomMD:thanks
20:10:57<TomMD>roconnor: Yes, I understand - I'll just have to do much conversion. Thanks.
20:11:02<Twey>What's LHC?
20:11:05<Twey>First I've heard of that one
20:11:10<Philippa>edwardk: what's the quick definition of 'cofree'? I'm not quite sure why, but I'm having trouble picturing it
20:11:16<TomMD>Twey: LHC used to be a JHC fork
20:11:28<roconnor>TomMD: please say that you only require rational inputs to these.
20:11:34<TomMD>Twey: LHC is now being redefined as a GRIN optimizing backend for GHC.
20:11:45<edwardk>Philippa: newtype Cofree f a = Cofree { runCofree :: (a, f (Cofree f a)) }
20:11:47<roconnor>TomMD: what are you doing anyways?
20:11:48<TomMD>roconnor: I only require rational inputs and outputs.
20:12:02<Twey>Aha
20:12:04<roconnor>TomMD: you aren't going to get rational outputs out of trig functions.
20:12:12<Heffalump>edwardk: is any f a valid parameter there?
20:12:18<TomMD>roconnor: Its for a GPS library. Double will do, but I figured people who want more accuracy might use Rational and people who don't care can make a very simple conversion.
20:12:23<inimino>Large Haskell Collider?
20:12:27<roconnor>TomMD: certainly not for rational inputs.
20:12:28<Lemmih>Twey: It's the Luxurious Haskell Compiler. A highly optimising backend for GHC.
20:12:34<edwardk>Heffalump: unlike Codensity/Density you need f to be a Functor.
20:12:40<TomMD>roconnor: Yes, I understand.
20:12:44<roconnor>TomMD: people who want more accuracy use CReal :P
20:12:51<roconnor>> cos (10^100) :: CReal
20:12:52<lambdabot> -0.9280819050746553434561946437769559281832
20:12:59<roconnor>> cos (10^100) -- :(
20:13:00<lambdabot> -0.9994551172253643
20:13:11<TomMD>roconnor: I keep hearing CReal, but I'm not clear on its properties. Is it a 128bit float or some such?
20:13:12<Heffalump>TomMD: I have some random bits and pieces of GPS code, btw. I'd be interested in seeing what you're doing.
20:13:13<edwardk>since you have to fmap (fmap a) to drill into f (Cofree f a) -- for fmap purposes
20:13:20<Philippa>edwardk: that's a cofree comonad rather than a cofree object in general, no?
20:13:27<roconnor>TomMD: nope, it is infinite precision.
20:13:36<TomMD>Heffalump: I proposed the basic API on haskell-proposals reddit a bit ago.
20:13:37<edwardk>Philippa: as i understand the world, yes.
20:13:47<Heffalump>TomMD: yeah, I saw that. Didn't get round to commenting.
20:13:51<TomMD>Heffalump: I'll cabalize / upload to hackage /blog when I finish.
20:13:59<roconnor>TomMD: there is an arbitrary precision floating point library out there too.
20:14:13<Heffalump>most of what I have is code to talk to the two sources of GPS data I have
20:14:39<TomMD>roconnor: I'll use CReal then - it sound like just the ticket (so long as people can convert to Fractional a as they desire)
20:14:49<roconnor>TomMD: In theory you don't need real numbers to do geometry
20:14:58<TomMD>Heffalump: I'm doing GPS computations (heading, distance, vectors)
20:15:04<roconnor>TomMD: be aware that CReals is potentially slow
20:15:08<Heffalump>TomMD: what's the point in using more precision that the data you'll be working with?
20:15:09<TomMD>speed... trail smoothing (to eliminate invalid points)
20:15:12<Heffalump>just use Double and be done with it..
20:15:32<TomMD>Heffalump: It all depends the precision of what people work with I suppose.
20:15:44<Philippa>edwardk: I meant cofreeness in general - I think I've got a grasp on what it is to be 'free', though I wouldn't want to put it into words while I'm feeling dopey
20:15:50<roconnor>CReals could be 1000x slower that Double. Maybe more?
20:15:58<Philippa>at least, not if there's any penalty for inaccuracy :-)
20:16:00<TomMD>But rational was overkill, I admit. Without an Earth model that uses height, I probably don't need double.
20:16:01<Heffalump>I haven't worked it out, but I'd expect Double to be several orders of magnitude more precise than GPS.
20:16:19<edwardk>Philippa: i.e. as in 'left adjoint to a forgetful functor'?
20:16:32<TomMD>Heffalump: Its more just becuase I figured this could get used by systems that have rationals in other sections, so I'd just remain consistent with what I thought was the best type.
20:16:43<Philippa>edwardk: I tend to think of it as "all syntax, no semantics", but yes
20:17:08<Heffalump>I'd say Double is the best type. Rational is pretty inefficient too.
20:17:34<Heffalump>unless you think there's a significant likelihood of FP roundoff problems
20:17:34<TomMD>Its an easy change - mostly I'll just change my type X = Rational to type X = Double in a couple spots.
20:17:58<TomMD>Heffalump: One FP round off problem is more than too much.
20:18:10<TomMD>@google patriot missle failure
20:18:11<lambdabot>http://www.ima.umn.edu/~arnold/disasters/patriot.html
20:18:11<lambdabot>Title: The Patriot Missile Failure
20:18:42<Heffalump>overloading the entire library on the type might also be feasible
20:18:55<Heffalump>looking at your proposal, why is Coordinate a type class but Vector not?
20:19:13<TomMD>I'm wary of too many typeclasses, but I will consider it.
20:19:46<roconnor>TomMD: FP round off is usually only a problem when accumulating values, which you may or may not be doing here.
20:20:14<Heffalump>there's rarely a reason to accumulate values with a GPS, because you get brought back to reality by the next point
20:20:23<roconnor>TomMD: the sort of it is that, CReal is slow exactly when FP round off is problematic.
20:20:39<Heffalump>I tend to agree about overloading on that being too many typeclasses.
20:21:15<TomMD>I'm going to switch it to Double for now but give it more thought before uploading / doing anything complex.
20:22:16<h0tzenpl0tz>does anyone know the exact scrabble-rules? i wonder if i may complete multiple side-by-side words like " foo bar " with "XXfooXbarXXXXX". would this be an allowed move?
20:22:58<Beelsebob>h0tzenpl0tz: all letters must be placed in a single line
20:23:05<Beelsebob>and make up one word along that line
20:23:13<roconnor>h0tzenpl0tz: what are the X's?
20:23:14<Beelsebob>they may also make other words intersecting with it
20:23:24<Beelsebob>but no more than one word on that line
20:23:26<h0tzenpl0tz>the x is a tile from my rack
20:23:44<Philippa>if you can find a word in the dictionary that fits that pattern, yes
20:23:52<Beelsebob>h0tzenpl0tz: yes, that's an allowed move then, if foo bar were already on the board
20:24:10<Twey>h0tzenpl0tz: You can only place a word side-by-side if each letter makes a word horizontally
20:24:17<Philippa>talking of which, is fubar an allowable word under current rules?
20:24:35<Beelsebob>Philippa: depends what country you're playing in
20:24:45<Twey>E.G. you can't have foo\nbar because ‘fb’, and ‘oa’ aren't words
20:24:56<roconnor>Rumour has it that the top Scrabble player is a Chinese man who doesn't speak English.
20:25:02<Twey>Beelsebob: There's an international English Scrabble dictionary
20:25:02<Philippa>Beelsebob: different rules, or different dictionary of choice?
20:25:12<Twey>Which is generally held to be the standard
20:25:26<Beelsebob>Twey: yeh, but that doesn't stop people playing by different dictionaries in different countries
20:25:54<h0tzenpl0tz>thank you all
20:26:09<Philippa>Beelsebob: including, of course, the cat dictionary
20:26:14<h0tzenpl0tz>thats pretty disgusting to implement :(
20:26:18<h0tzenpl0tz>over & out
20:26:22<Beelsebob>h0tzenpl0tz: not at all
20:26:25<Beelsebob>that's easy to implement
20:26:33<h0tzenpl0tz>i wouldnt know how
20:26:53<Beelsebob>3 conditions must hold... all letters must be in a line; all letters must form a complete word along that line; and all combinations they form must be words
20:27:00<Philippa>Beelsebob: I think h0tzenpl0tz means for an AI player? It's easy to validate the move...
20:27:01<Beelsebob>each of those is easy to implement
20:27:14<Beelsebob>Philippa: oh, yeh, for AI it may be harder
20:27:21<h0tzenpl0tz>indeed ;)
20:27:30<h0tzenpl0tz>thanks nevertheless
20:27:34<Beelsebob>ACTION would suspect for a scrabble AI you might need to have an algorithm for spotting places to play
20:27:38<Beelsebob>before coming up with words
20:27:48<sinelaw>@djinn a->a->a
20:27:50<Beelsebob>i.e. a heuristic search of places it wants letters to land
20:27:50<lambdabot>f _ a = a
20:28:13<h0tzenpl0tz>yeah that works but it doesnt connect multiple side-by-side words :(
20:28:16<h0tzenpl0tz>tryin harder...
20:28:24<Beelsebob>hehe, fun
20:28:49<Philippa>h0tzenpl0tz: look for all 1-letter, 2-letter etc plays. Squares first, then the dictionary bash
20:29:22<Philippa>the point being to calculate the connections made with each play so you've got your validation burdens
20:29:58<Beelsebob>Philippa: I would expect you can significantly narrow down your options by doing things like "I have a z, I want it on the tripple letter, this means I can grep the dictionary for z..a.h" etc
20:30:36<h0tzenpl0tz>build a dictionary before that allows these patterns efficiently :)
20:30:40<Philippa>Beelsebob: *nod*. But I leave that to people who're good at AI, you can rearrange the problem at will once you know what it looks like :-)
20:31:21<Beelsebob>true
20:41:30<Philonous>Is there a way to kill external processes once the programm invoking them gets shut down?
20:43:24<vininim_>gosh, importing parsec qualified is not a good idea if you want to use the operators
20:43:36<PeakerWork>Philonous: I think normally processes get a SIGHUP in Unix when their parent process dies
20:43:52<PeakerWork>Philonous: You can also keep a pipe between the parent and the children, and the children can die when they hit EOF on that pipe
20:44:25<Tobsan>PeakerWork: you can also do runCommand with some kind of pkill if you want to do it the ugly way
20:44:28<Philonous>I was incoking from inside a haskell thread and it kept running when I killed the haskell process
20:44:31<Philonous>invoking*
20:44:52<marcot>vininim_: qualified operators are not very nice.
20:47:20<PeakerWork>vininim_: Use: import Blah((*), (|||), ...)
20:47:34<PeakerWork>Its nicer than having to guess where operators come from
20:47:43<PeakerWork>(not qualified operators, but explicitly named operators)
20:47:54<aempirei>lol
20:49:44<vininim_>marcot: hello \o
20:49:51<camio>How did the new #haskell-in-depth come about?
20:51:41<Heffalump>camio: reduce traffic volume on here
20:53:51<camio>Juding from the traffic there, it doesn't seem like it took of a significant chunk of traffic away so far.
20:54:09<camio>s/ of//
20:56:26<camio>Maybe the confusion of having two channels would induce someone to just leave. That could reduce traffic :)
20:56:49<Heffalump>it does allow slower paced discussions on there, too
20:56:55<Heffalump>I think it's worked fairly well
20:57:15<marcot>vininim_: /j #haskell.pt
20:57:44<camio>cool
21:06:55<lament>what's a pretty way to find, in a sorted list of numbers, the greatest number (if it exists) s.t. the list contains 6 numbers in a row including that one?
21:07:23<Heffalump>6 numbers the same>
21:07:24<Heffalump>?
21:07:34<Philippa>in sequence
21:07:39<lament>no, in a row, like 4,5,6,7,8,9
21:07:44<mxc>well, already sorted
21:07:46<Philippa>eg 1234567 would yield 7
21:07:48<lament>yes
21:07:49<Heffalump>oh, right
21:07:51<mxc>so like 1,2,2,2,2,2,4,5 would return 2?
21:07:52<solrize_>groupBy
21:07:54<solrize_>:t groupBy
21:07:55<lambdabot>forall a. (a -> a -> Bool) -> [a] -> [[a]]
21:08:07<lament>mxc: sorted, no duplicates
21:08:31<mm_freak>lament: how about taking the last element? or the first
21:08:35<mm_freak>if the list is sorted
21:08:37<Heffalump>I'd calculate successive differences, then map (take 6) . tails
21:08:37<lament>> group by (\x y -> y = x + 1) [1,2,3,4,5,6,7,9,10]
21:08:38<lambdabot> <no location info>: parse error on input `='
21:08:42<lament>> group by (\x y -> y == x + 1) [1,2,3,4,5,6,7,9,10]
21:08:44<lambdabot> Not in scope: `by'
21:08:47<lament>> groupBy (\x y -> y == x + 1) [1,2,3,4,5,6,7,9,10]
21:08:49<lambdabot> [[1,2],[3,4],[5,6],[7],[9,10]]
21:08:54<Heffalump>then filter by all (==1)
21:09:02<mm_freak>> last . sort $ [3,5,1,7,4,4]
21:09:03<lambdabot> 7
21:09:08<Philippa>lament: accumulate "consecutive numbers" and "biggest number where consecutive >= 6"?
21:09:25<Heffalump>that finds you the sequences but doesn't tell you what they actually were, so zip with the original numbers at some point before the filter
21:09:30<Philippa>(which also means accumulating last number)
21:09:30<Heffalump>and then just take the last
21:09:44<camio>lament: What do those numbers represent? Why are they in sorted order in the first place?
21:09:44<solrize_>> groupBy (==) $ zipWith (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..]
21:09:46<lambdabot> [[0],[2,2],[3,3,3,3,3,3,3],[4],[18]]
21:09:46<Philippa>admittedly that's a really imperative way of doing it :-)
21:10:18<lament>solrize_: oo
21:10:18<solrize_>> last $ filter ((>=6) . length) $ groupBy (==) $ zipWith (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..]
21:10:20<lambdabot> [3,3,3,3,3,3,3]
21:10:25<mm_freak>i don't get it, what's the difficulty of extracting the largest element of an already-sorted list?
21:10:48<lament>mm_freak: given [1,2,3,4,5,6,8] the functions should return 6.
21:10:55<lament>*function
21:11:05<Heffalump>mm_freak: the last element with a particular property
21:11:11<lament>(or rather Just 6 since there may not be an answer)
21:11:11<Heffalump>identifying the property is the tricky bit
21:11:15<mm_freak>in what sense is 6 larger than 8?
21:11:24<lament>in none.
21:11:30<Heffalump>mm_freak: 8 isn't part of a sequence
21:11:38<Philippa>last . last . filter (longEnough) . groupBy (isOneGreaterThan) ?
21:11:39<mm_freak>ah, ok, in sequence
21:11:44<Philippa>with the predicates filled in?
21:12:15<solrize_>> last $ filter ((>=6) . length) $ groupBy \(a,b) -> (a-b == 1) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..]
21:12:16<lambdabot> <no location info>: parse error on input `\'
21:12:37<solrize_>> last $ filter ((>=6) . length) $ groupBy (\(a,b) -> a-b == 1) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..]
21:12:38<lambdabot> Couldn't match expected type `(t, t) -> Bool'
21:12:49<solrize_>> last $ filter ((>=6) . length) $ groupBy (\(a,b) -> (a-b == 1)) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..]
21:12:50<lambdabot> Couldn't match expected type `(t, t) -> Bool'
21:12:57<solrize_>hmm. well you get the idea
21:14:25<lament>groupBy takes two arguments
21:15:12<lament>> groupBy (\(a,b) (c,d) -> (a-b == c-d)) $ zip (-) [1,2,3,4,5,6,7,9] [1..]
21:15:13<lambdabot> Couldn't match expected type `[a]'
21:15:42<lament>(i meant the predicate to groupBy)
21:16:40<mm_freak>lament: at which point do you consider numbers "in sequence"? at least two consequtive numbers?
21:17:03<mm_freak>s/q/c/
21:17:23<lament>yes
21:17:41<lament>so the largest number in a sequence of at least 6 consecutive numbers
21:17:51<mm_freak>at least 6, ok
21:18:59<Heffalump>TomMD: my GPS stuff is here if you are interested: http://urchin.earth.li/darcs/ganesh/gps/
21:19:21<mm_freak>groupBy would work nicely if it compared with the preceding element, not with the first element of a group
21:19:25<mm_freak>that's very annoying
21:19:39<mm_freak>> groupBy (\x y -> y == x+1) [1,2,3,5,6,7,8,9,11,13,14,15]
21:19:40<lambdabot> [[1,2],[3],[5,6],[7,8],[9],[11],[13,14],[15]]
21:20:01<mm_freak>i'd write an own version of groupBy and use it
21:20:36<mm_freak>then just apply: maximum . map last . filter ((>6) . length)
21:21:08<centrinia>Uh, why isn't [5,6,7,8,9] in a group?
21:21:31<mm_freak>centrinia: because groupBy compares each element with 5, not with the preceding element
21:21:41<mm_freak>i.e. with the first group member
21:22:33<mm_freak>uhm yeah, and replace >6 by >=6 =)
21:33:04<lament>> (fst . last . last) $ filter ((>=6) . length) $ groupBy (\(a,b) (c,d) -> a-b == c-d) $ zip [1,2,3,4,5,6,7,9,11,12,13,14,15,16,20] [1..]
21:33:05<lambdabot> 16
21:33:09<lament>this works. But i did ask for a pretty way :)
21:33:13<TomMD>Is there a package with a Binary instance for Double that people have agreed on?
21:37:06<dons>Data.Binary comes with instances for Double
21:37:11<dons>just not ieee ones, haskell ones.
21:40:45<byorgey>http://haskell.org/haskellwiki/Hac_%CF%86
21:41:08<byorgey>Hackathon in Philadelphia! sign up now, limited space! ;)
21:41:34<skorpan>someone please tell me what is HP? haskell platform?
21:41:38<skorpan>or haskell prime?
21:41:49<Lemmih>Hit points?
21:41:51<c_wraith>possibly Harry Potter. kids these days...
21:41:57<skorpan>...
21:42:14<Vq^>HP Sauce?
21:42:15<eivuokko>skorpan, I am afraid the quality of answers is dependent on additional context you can give.
21:42:22<byorgey>skorpan: probably Haskell Platform. Haskell prime is usually abbreviated Haskell' .
21:42:42<skorpan>eivuokko: the context is the mailing list.
21:42:58<Philonous>Hewlett Packard?
21:43:19<skorpan>okay, so let's assume it's the haskell platform. what *is* the haskell platform? new hackage? new cabal?
21:43:35<eivuokko>Standard set of tools.
21:43:43<Vq^>Horsepower?
21:43:49<Zao>http://www.haskell.org/haskellwiki/Haskell_Platform <- that'a'thing
21:43:50<dons>go upenn http://www.haskell.org/haskellwiki/Hac_φ
21:43:55<skorpan>kind of haskell stdlib?
21:44:06<dons>skorpan: kinda a haskell extended stdlib
21:44:10<dons>like super extended
21:44:33<Zao>dons: I've heard that escaping URLs helps with communicating.
21:44:38<roconnor>``The platform prevents you from picking and choosing the best Haskell libraries and tools to use for a task.
21:44:40<xs>why is a rose tree called a rose tree, and who named it thus?
21:44:46<Zao>Unless you intended to link to "Hac Æ"
21:44:49<skorpan>so this is supposed to replace the thousands of haskell libraries in arch's repos?
21:44:54<dons>roconnor: i don't think that's a quote
21:45:06<dons>skorpan: no.
21:45:30<roconnor>close enough
21:45:31<gwern>skorpan: the platform is just an organizational idea
21:45:51<Zao>http://www.haskell.org/haskellwiki/Hac_%CF%86 <- clever use of phi though :)
21:45:53<gwern>to use a WP metaphor: the platform is a category; all the articles remain as before
21:45:55<dons>roconnor: why?
21:46:12<skorpan>gwern: that's a metaphor i can understand
21:46:20<dons>if you want to pick and choose, install the platform, then fire up cabal-install
21:46:23<skorpan>and hackage is a supercategory of haskell platform?
21:46:24<Philonous>Is there a package for command line options parsing?
21:46:29<gwern>ACTION is obscurely pleased
21:46:34<gwern>skorpan: hackage is Special:Allpages
21:46:41<skorpan>yeah, cool :)
21:46:45<gwern>(because if it's not on hackage it doesn't exist!)
21:47:03<dons>Philonous: in the base library
21:47:11<roconnor>dons: exactly. so why platform.
21:47:20<Philonous>thanks dons
21:47:41<skorpan>will there always be exactly one version of each package in HP?
21:47:43<roconnor>... actually the platform makes sense given that cabal cannot properly track version interfaces.
21:48:07<roconnor>I'd rather see cabal fixed, but I suppose that is a much more difficult task.
21:48:57<dons>roconnor: for people who don't use cabal-install
21:49:01<skorpan>on a completely unrelated topic: when will darcs cease to be the norm for haskell projects?
21:49:16<dons>and who don't want the latest version of everything
21:49:19<gwern>skorpan: hopefully never
21:49:23<dons>skorpan: 2020?
21:49:24<skorpan>dons: the yi project ;P
21:49:30<dons>git has a small inroad, but that's it
21:49:39<Zao>dons: People who want to use previous versions due to source incompatibilities?
21:49:40<skorpan>dons: but that's only because new versions tend to break other packages
21:49:57<Zao>ACTION shakes a fist at people who make breaking changes in subminor version bumps.
21:50:02<roconnor>and new versions only break packages because cabal doesn't track version interfaces properly.
21:50:04<Zao>Yes vector-space, I'm looking at you.
21:50:13<dons>no, a lot of users who don't hang out on #haskell don't want every minor version, or to choose the cutting edge of everything
21:50:14<roconnor>well, I guess not "only", but largely
21:50:16<dons>i.e. industrial users
21:50:27<PeakerWork>git is pretty cool -- if someone wrote a sane UI around it, and added some more meta-data to rebases, it would have all of darcs' advantages, and I think even without it its already preferable
21:50:30<dons>who just want a stable set that builds stable things for years, without having to do research
21:50:35<dons>these people generally don't hang out here.
21:50:38<dons>so you need both
21:50:48<dons>a cutting edge set for developers (hackage), and a stable base for everyone else
21:51:12<gwern>PeakerWork: I am moderately sure that git doesn't have all of darcs's patch manipulation stuff
21:51:12<roconnor>dons: you could be right, but I'm still skeptical.
21:51:31<dons>that's fine. there's already been 1000s of downloads :)
21:51:39<roconnor>yep
21:51:40<roconnor>:)
21:51:41<gwern>(release early, release often!)
21:51:54<roconnor>entrenching the mtl for life :P
21:52:08<dons>the other thing is to ensure that the platform is on every system
21:52:08<PeakerWork>gwern: I think it can relatively easy have them in the form of rebases, except rebases currently lack meta-data
21:52:15<dons>so you can't get away with say, ubuntu being 2 years out of date
21:52:24<dons>unless we /tell/ distros whta to package, they make arbitrary choices
21:52:36<skorpan>good thing arch exists
21:53:08<roconnor>dons: hmm, I find that distros argument is more compelling.
21:53:21<gwern>yes, that's a good point about the HP. now we can complain that they've only got x% of the HP
21:53:27<Philonous>dons: Do you know which Module contains the options parsing?
21:54:18<dons>System.Console.GetOpt
21:54:21<PeakerWork>gwern: git lets you do any kind of cherry picking of patches that darcs does - except you can retroactively choose different diff strategies for patch generation, when doing the cherry picks, which is more powerful than what darcs can - as darcs commits to a specific way of diffing in the whole repo
21:54:23<Philonous>Thanks
21:54:31<skorpan>Philonous: or try parseargs
21:55:06<skorpan>is there any generalized version of (\\)? i wrote my own one, bug included
21:55:26<gwern>PeakerWork: I'm not too up on DVCSs, but I've been assured by the other darcs dev that darcs can commute patches in ways git won't/can't
21:55:35<gwern>although I'm glad git can at least cherry pick changes...
21:55:48<skorpan>gwern++
21:55:58<skorpan>that's one of the big things i miss in hg
21:56:59<PeakerWork>gwern, skorpan: git lets you re-diff any previous revisions in history, and apply it on any other revision in history, which I think takes care of any kind of commuting you may want to do, except unlike darcs, you can do this using any diff algorithm you want, and not one pre-determined before ever setting up the repo
21:56:59<Gracenotes>skorpan: not many structures abstract over list modification
21:57:13<Gracenotes>not in the common libraries anyway
21:57:16<Nafai>I like that you can re-order commits in git
21:57:41<PeakerWork>skorpan: I think hg does not yet have git's rebase, and even git's rebase is lacking in metadata - which could really make rebase seamless even when collaborating on the rebased branches
21:57:59<solidsnack>There seems to be something off about readline/editline in the GHC 6.10.3, at least on Macintosh.
21:58:16<Nafai>PeakerWork: What kind of metadata would be useful?
21:58:18<skorpan>PeakerWork: but e.g. tortoisehg (a gui for hg) can actually display "hunks" of changes which leads me to believe it should really be super simple to implement
21:58:24<PeakerWork>gwern, skorpan: Like all revision-based DVCS, git places an arbitrary order between independent commits, but that order can be ignored when forming new revisions to use
21:58:45<solidsnack>`fn+shift+right` -- which used to get me `end` -- is now resulting in a capital F!
21:59:40<PeakerWork>Nafai: A rebase (or amend commits, etc) creates commits containing similar patches to other commits. It could be nice if these commits had metadata pointers to those older commits, and when someone pulls from a rebased branch, the metadata would tell the puller: "Your commits' patches are already in this new rebased revision, so you can rebase too and continue where he has"
22:00:13<PeakerWork>Nafai: They could allow to pull from rebased branches
22:00:43<PeakerWork>Nafai: as well as keep the old rebased stuff alive for future reference, rather than floating around until its GC'd when its no longer in the git reflog
22:00:50<Lemmih>PeakerWork: Isn't this still an issue: http://projects.haskell.org/camp/unique
22:01:08<jeffwheelerPhone>@pl \x y -> x : [y]
22:01:12<lambdabot>(. return) . (:)
22:01:12<PeakerWork>Lemmih: I don't have speakers here -- what is the issue being described?
22:01:54<PeakerWork>@unpl (. return) . (:)
22:01:54<lambdabot>(\ d g -> ((:)) d (return g))
22:01:57<PeakerWork>@unpl (:) . (. return)
22:01:58<lambdabot>(\ d -> ((:)) (\ g -> d (return g)))
22:02:32<PeakerWork>@unpl could use some sugaring
22:02:32<lambdabot>could use some sugaring
22:02:55<Lemmih>PeakerWork: It talks about how darcs tracks dependencies on the patch level and what that allows you to do.
22:04:08<PeakerWork>Lemmih: iiuc, the same can be done in git, where each commit represents a patch -- its metadata can contain anything, including actual patch dependencies on other commits. When you rebase, you can keep a pointer from the newly generated commit to the old one to retain all of this metadata (or just copy it)
22:04:14<Nafai>PeakerWork: Ah, good idea.
22:04:41<roconnor>Hmm, I don't suppose we could have hac φin July in Beijing instead. :)
22:05:15<PeakerWork>Lemmih: I think the darcs features are a nice idea - but I think the right way to implement these darcs features is on top of a git backend
22:05:38<roconnor>is it a good idea to have hac φ during the ICFP contest?
22:05:52<roconnor>oh wait
22:05:53<PeakerWork>A revision-based backend is more powerful than a patch-based backend, as long as your patches aren't perfect (and textual diffs are far from perfect)
22:05:57<roconnor>the contest is in June, not July
22:05:59<roconnor>\o/
22:06:15<roconnor>I thought I was going to miss it again.
22:10:43<inimino>PeakerWork: how is it more powerful if they are equivalent?
22:11:03<byorgey>roconnor: yeah, we took the ICFP contest into account =)
22:11:24<byorgey>roconnor: you're going to be in Beijing?
22:12:00<deech>Hi all, is there a function in that determines if a string is contained in another string? Or more generally if list x is a sublist of list y?
22:12:15<PeakerWork>inimino: Its not strictly more powerful, if you're willing to do a full repository conversion -- but if you're not, then the committing to imperfect patches in darcs means you may not switch patch strategies whereas in git, you can choose whatever way to diff between repos that you wish, on a case-by-case basis
22:12:20<Botje>deech: isInfixOf
22:12:48<deech>Botje: Awesome thanks!
22:12:50<PeakerWork>inimino: arg, its very late and I'm confusing words, sorry. s/repos/revisions
22:14:25<inimino>PeakerWork: ok. I actually use git and haven't looked into darcs
22:15:31<PeakerWork>inimino: If you think of git revisions as representing patches, and not whole trees, you can mix&commute those patches pretty easily, and you get most of the features darcs advertises. But them being whole trees in the backend lets you decide much later what kind of diffing to use
22:15:53<PeakerWork>s/being whole trees in the backend/representing whole trees in the backend
22:16:01<inimino>makes sense
22:16:27<inimino>I wasn't aware darcs actually had different patch formats
22:16:58<inimino>ACTION should probably read about it sometime
22:18:29<mm_freak>lament: as said, pretty would be to write your own groupBy variant, which always compares with the predecessor instead of the first group element
22:18:38<mm_freak>that would give a very nice, concise solution
22:23:36<lament>hm
22:35:22<PeakerWork>Not (Not a) -> a should be provable right? How do you create a value of type ((a -> Void) -> Void) -> a ?
22:35:24<Philonous>Is there a way to control the RTS without the + and -RTS options? Those might be a little awkward to non-haskell users
22:36:22<lament>why would a non-haskell user be profiling?
22:36:54<Philonous>They wouldn't, but they might want to instruct the RTS to use N system threads
22:37:28<mauke>@djinn Not (Not a) -> a
22:37:28<lambdabot>-- f cannot be realized.
22:37:57<solidsnack>Philonous: That's actually a really good point.
22:38:02<mauke>if all else fails, write a wrapper
22:40:39<eivuokko>It probably doesn't help, but you an also control RTC options via environment variable.
22:40:52<Baughn>@ask conal Let me confirm something. reactive is supposed to be deterministic, right? Specifically, if I create a behaviour from some source of events (stepper), and then snapshot it against the same event stream, I ought to get a 1:1 correspondence between behavior steps and snapshot output?
22:40:53<lambdabot>Consider it noted.
22:41:15<conal>Baughn: hi
22:41:15<lambdabot>conal: You have 1 new message. '/msg lambdabot @messages' to read it.
22:41:30<c_wraith>lambdabot, you may be suboptimal in this case.
22:41:42<Baughn>conal: Huh. I could swear I tried tab-completing..
22:42:24<conal>Baughn: yes, deterministic. No about the snapshot. the semantics of stepper/switcher is that the behavior changes immediately *after* the event occurrence.
22:42:26<eivuokko>Philonous, Oh, and also if you want to write some C, you can do it via some hooks or whatever it was called. Described in user's guide.
22:42:28<Baughn>conal: Or more generally - should it be just plain deterministic, providing same output given same input every time?
22:42:35<conal>Baughn: which allows recursively defined behaviors.
22:42:55<conal>Baughn: have you seen the semantic model for behaviors?
22:42:59<Baughn>conal: Ah. That explains my output a little bit, but the determinism is suffering in that conversion. Well, I'll get on it.
22:43:19<PetRat>Can I use lambdabot to check the type of a recursive function? what would be the syntax?
22:43:27<Baughn>conal: I've read it. Probably not well enough, still; by the time I'm done with exams I will have.
22:43:39<conal>Baughn: by the "semantic model", i mean the type of *meanings* of behaviors.
22:43:57<Baughn>:t let f x = 1 : x : f (fubar x)
22:43:59<lambdabot><no location info>:
22:43:59<lambdabot> not an expression: `let f x = 1 : x : f (fubar x)'
22:44:06<Baughn>:t let f x = 1 : x : f (fubar x) in f
22:44:07<lambdabot>Not in scope: `fubar'
22:44:17<Baughn>:t let f fubar x = 1 : x : f (fubar x) in f
22:44:19<lambdabot> Occurs check: cannot construct the infinite type: t = t1 -> t
22:44:19<lambdabot> Probable cause: `f' is applied to too few arguments
22:44:19<lambdabot> In the second argument of `(:)', namely `f (fubar x)'
22:44:31<Baughn>PetRat: ..impossible functions aside, thataway.
22:44:41<Philonous>eivuokko: That's both suboptimal, but I will manage. Thanks
22:44:57<conal>Baughn: in general you can learn essence of a data type or language simply by looking at the type of meanings ("denotations").
22:44:59<Tigran>PeakerWork: Not sure if this is what you were referring to, but `not (not a) -> a' can not be proved under intuitionistic logic
22:45:17<conal>Baughn: since the model of Behavior a is Time -> a, it has to be deterministic.
22:45:24<Baughn>conal: Right. By the way, do you think anyone would be terribly upset if I submitted a patch replacing TimeT with a fixed-point implementation?
22:45:25<conal>(it == semantics)
22:45:36<Tigran>PeakerWork: `a -> not (not a)' can, however
22:45:44<Baughn>conal: I have this vision of long-running programs going insane. But maybe you've thought of that one.
22:45:59<c_wraith>@check \a -> a == not $ not a
22:46:00<lambdabot> Couldn't match expected type `a -> b' against inferred type `Bool'
22:46:16<c_wraith>@check \a -> (a == not $ not a)
22:46:18<lambdabot> Couldn't match expected type `a -> b' against inferred type `Bool'
22:46:27<c_wraith>ok, my brain isn't in haskell mode today
22:46:28<mauke>@djinn a -> Not (Not a)
22:46:28<lambdabot>f a b = b a
22:46:34<conal>Baughn: i don't know what's best to represent times. hardly any operation really cares about the nature of time, other than that it's ordered.
22:46:46<PeakerWork>Tigran: That's disappointing. Is intuitionistic logic less powerful than classical logic?
22:47:06<copumpki>and lengths of time?
22:47:38<mreh>when pattern matching on records, can I be selective about which fields I match?
22:47:56<mauke>yes
22:48:06<Tigran>PeakerWork: It omits the axiom of choice, so I suppose `less powerful' is about right
22:48:10<mreh>cool
22:48:12<mauke>you can even match none of them
22:48:19<mreh>COOL
22:48:26<mreh>why would you bother?
22:48:28<mauke>Foo{} -- even works for non-record constructors
22:48:50<mreh>haha
22:48:58<Tigran>You don't lose the classical truths entirely
22:49:04<mauke>> (\x -> case x of Nothing{} -> "nothing"; Just{} -> "just _") (Just 42)
22:49:05<lambdabot> "just _"
22:49:18<Tigran>Intuitionistic simply doesn't contradict classical logic
22:49:35<Baughn>conal: Well, I suppose.. given double, with a 52-bit mantissa, you get microsecond precision for.. hm, 136 years
22:49:41<Baughn>..probably sufficient.
22:50:09<mreh>that's what they said in 60s about the millenium
22:50:46<chessguy>i'm totally going to Hac-φ :)
22:51:01<conal>Baughn: how about submitting a trac item?
22:51:21<Baughn>conal: Pretty sure someone already did. I tried fixpointing it just to see if that mattered at all.. it didn't.
22:51:41<conal>Baughn: oh, okay.
22:51:48<persica>mreh: And 640k should be enough for anyone.
22:51:53<Baughn>Not for a short-lived program, at least. ;)
22:52:00<roconnor>byorgey: I'm heading to Shanghi for the solar eclipse, then off to Beijing for a vist.
22:52:24<PetRat>:t either
22:52:25<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
22:52:41<conal>Baughn: i'm not attached to the current default time type.
22:52:44<Baughn>conal: Oh, and.. is the /current/ implementation of mkUpdater "supposed to do almost no work during known-constant phases", or is that yet to come? It pegs my cpu while blocked on stdin, you see.
22:53:16<conal>Baughn: supposed (by me) to do so now.
22:53:33<conal>Baughn: any idea what it's up to?
22:53:56<conal>i suck at performance analysis / debugging
22:55:13<mreh>persica: My favourtie quote from IBM, "The world will probably need five computers"
22:55:50<lament>roconnor: when are you in beijing?
22:55:53<FunctorSalad>everything that can be invented has been invented (around 1900?)
22:55:55<Baughn>conal: Not yet, really. I've had higher priority on debugging the actual /bugs/ - besides, it might go away by then.
22:56:10<c_wraith>mreh: Who says that it *need* more than that? The rest are just kind of handy.
22:56:16<c_wraith>blah. *needs
22:56:28<roconnor>lament: something like July 23 to July 26
22:56:32<Baughn>conal: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5106#a5106 <-- Have a testcase anyway.
22:56:49<roconnor>lament: but I don't think I'd travel to the US for a hackathon anyways.
22:56:53<mreh>and yet if we took them all away today, we wouldn't be able to cope
22:56:57<roconnor>lament: the US is unwelcoming to visitors
22:56:57<PetRat>http://www.mibbit.com/pb/Zx58ym I'm trying to use ErrorT following someone else's example, but my code isn't working. I want to write a function with type IO String, but the inferred type is IO (). Can someone explain?
22:57:13<lament>roconnor: cool, i'll be in beijing too
22:57:15<Baughn>conal: Funny thing - ghc is doing non-blocking (timeout=0) selects on stdin in there
22:57:27<roconnor>lament: :O really, why?
22:57:37<lament>roconnor: Go class :)
22:57:41<mauke>PetRat: putStrLn returns ()
22:57:46<conal>Baughn: how do you know?
22:57:53<Baughn>conal: strace
22:57:55<roconnor>lament: how long are you there?
22:57:56<mreh>lament: the game go?
22:57:59<conal>Baughn: what's that?
22:58:04<lament>mreh: yeah
22:58:09<lament>roconnor: july and august
22:58:15<mauke>http://en.wikipedia.org/wiki/Strace
22:58:16<nominolo>@users
22:58:16<lambdabot>Maximum users seen in #haskell: 658, currently: 602 (91.5%), active: 26 (4.3%)
22:58:25<Baughn>conal: ..you're on windows, I guess?
22:58:33<PetRat>mauke: oh, each branch of the either must be the same, I guess.
22:58:33<roconnor>lament: you should go to Shanghi for July 22.
22:58:46<lament>roconnor: I know
22:58:52<conal>Baughn: no. on linux. switched a few months ago.
22:58:55<Baughn>conal: Hum. It's only with the non-threaded runtime, which makes sense.
22:58:56<lament>roconnor: I was thinking... It's Shanghai - it's going to be cloudy anyway
22:59:09<conal>is strace helpful with ghc-compiled programs?
22:59:10<roconnor>lament: there is a certain truth to that statement
22:59:11<Baughn>conal: Then I recommend you look into strace and ltrace. Both are rather vital tools on linux. :)
22:59:17<Baughn>conal: strace is. ltrace, not so much.
22:59:20<conal>Baughn: will do. thx!
22:59:31<mreh>i need to update the state of my spaceship, and hence do lots of calculations to redraw it, does this merit using moands for the sequentiality?
22:59:47<Baughn>mreh: Do you /need/ the sequentiality?
23:00:01<lament>roconnor: but i might, it seems like a really cool opportunity
23:00:07<roconnor>lament: I hope it won't be cloudy though.
23:00:07<mreh>Baughn, to make it readable, yes
23:00:16<lament>i've seen two partial eclipses, they were cool but not all that exciting
23:00:22<mauke>conal: strace cuts through the surface bullshit and shows you what the damn program is really doing!
23:00:26<Baughn>mreh: And technically, monads aren't about sequentiality. Monads are about join :: m (m a) -> m a
23:00:33<wicket>I'm trying to get my parallell code working, and i think i need to control the evaluation in order to get some good results (right now -N1 is best). I have an embarrasingly data parallell routine, where i parse many strings into a data type. But it doesn't seem like line 23 is forcing evaluation. http://pastebin.com/m5b874951
23:00:33<lament>the best part is all the people walking around on the streets not knowing that anything is going on :)
23:00:34<roconnor>lament: totally eclipses are totally different.
23:00:38<roconnor>lament: total
23:00:39<lament>roconnor: totally.
23:00:47<mauke>it's equally useful for programs written in C, Perl or Haskell
23:00:51<Baughn>mreh: WHich, granted, allows sequentiality. Among other things.
23:00:52<conal>mauke: cool. thx.
23:01:20<roconnor>lament: this will be the longest eclipse this century
23:01:31<Baughn>mreh: I don't know how experienced you are, so - what about "let a = foo indata; b = munge a; c = munge b in c" or so?
23:01:32<wicket>If I don't add line 25 or 26 the execution time of the program goes down to < 1 second, and if i keep these it turns into the more realistic 15 seconds.
23:02:05<Baughn>mreh: In my case, I tend to write functions like "function x y z = <something simple>.. where <lots of clauses>"
23:02:29<lament>roconnor: i guess even through the clouds it will be quite apparent
23:02:36<opqdonut>Baughn: IMO that tends to get difficult to read when <lots of clauses> refer to eachother
23:02:51<Baughn>opqdonut: It's usually serial-ish
23:02:54<opqdonut>when <lots of clauses> are independent, it's good style
23:02:55<Baughn>Or at least tree-ish
23:02:58<roconnor>lament: true, but the sky is the best part of the show
23:03:25<mreh>Baughn: What i need is certain calculations to be done before others, like the rotation of the ship done before the velocity calculations
23:03:26<opqdonut>hmm, treeish
23:03:30<Baughn>opqdonut: I think of it as naming intermediate values. It's easier to read than /not/ having names.
23:03:33<opqdonut>some people use nested where's
23:03:42<opqdonut>i tend to think more equationally
23:04:06<opqdonut>i mean, with the same mindset as when writing mathematical equations
23:04:10<Baughn>mreh: Oh, you're talking /updates/..
23:04:11<conal>mreh: maybe you could find a more functional design.
23:04:13<mreh>Baughn: I'm thinking like destructive updates are an issue still, I'll work it out
23:04:25<Baughn>mreh: Functional Game Design 101:
23:04:33<Baughn>mreh: Make frame N+1 a function of frame N
23:04:38<conal>mreh: and let laziness and value dependencies sort out the scheduling
23:04:56<Baughn>mreh: Do not allow details of N+1 to be a function of other details of N+1 when you can avoid it
23:05:05<Baughn>mreh: Sprinkle parallelism as appropriate.
23:05:16<Baughn>Games tend to be much easier to parallelise like that. :)
23:05:43<mreh>Baughn, where does user input comein?
23:06:23<Baughn>mreh: The model was a bit simplified. You attach that to frame N as input.
23:06:37<mreh>frame N+1 is a funtion of frame N pkus input
23:06:41<Baughn>Right
23:06:42<mreh>cool
23:07:33<mreh>what I've seen done, is user input modifying the content of frame N... is that bad
23:07:44<mreh>sounds bad
23:07:44<Baughn>Yes. It makes it very hard to reason about the programs.
23:07:53<Baughn>Well, it's the exact same bad as all mutating code. ;)
23:08:02<Baughn>And, of course, it makes adding parallelism harder
23:08:11<mauke>.oO( self-mutilating code )
23:09:01<conal>Baughn: i have some unpushed changes to reactive that probably help some with the problems you've been having.
23:09:05<Baughn>mreh: Of course, one consequence of this is that some input may be two frames delayed. Say, user presses "roll left" on frame 1, the ship model rotates on frame 2 but you're still using the thrust vector from frame 1 for translating it
23:09:27<conal>Baughn: i'll shake the dust off, make sure it runs with reactive-fieldtrip examples, push, and let you know.
23:09:35<Baughn>Thanks
23:09:51<Baughn>mreh: One possibility is to design your game so this isn't an issue - it might be considered more realistic, even
23:10:38<Baughn>mreh: Another would be to actually make some of frame N+1 (translation dependent on other parts of N+1 (thrust). This isn'T /that/ big an issue; you're losing paralellism, but only for that one task
23:10:49<Baughn>Distinct ships can still be simulated separately. :)
23:10:55<mreh>ACTION brane asplodes
23:11:09<PeakerWork>conal: could you get fieldtrip to compile on ghc-6.10.[2,3] ? Its probably a few-minute fix (An Occurs check on a type)
23:11:39<conal>mreh: another piece of advice: make sampling (frame generation) and simulation (e.g., numeric integration / position updating) be independent of each other.
23:11:50<conal>PeakerWork: will do.
23:12:08<Baughn>conal: Oh, and you should limit reactive to Stream-0.3 - or switch to a newer version of quickcheck
23:12:23<conal>PeakerWork: i think i know what that problem would be. i changed the VectorSpace instance for functions.
23:12:49<p_l>Well, OpenGL afaik doesn't like multithreading too much...
23:12:50<conal>PeakerWork: for programmable lighting models
23:13:04<mreh>my design so far is to fold
23:13:08<mreh>oops
23:13:10<Baughn>mreh: A third piece of advise: Learn about reactive. :)
23:13:16<conal>heh
23:13:44<conal>or *any* way to think about animation/behavior/interaction/simulation *functionally*
23:13:46<mreh>my design so far is to fold the events generated by the user, onto the old state to make a new game state
23:13:51<Baughn>p_l: That is.. not quite true, but it's very specific about how you do multithreading
23:14:02<Baughn>Mostly, doing all rendering in a forkOS'd thread will do.
23:14:07<conal>and not just functionally, but also continuously
23:15:00<Baughn>conal: By the way, does reactive really need to call forkIO quite that much? -_-
23:15:11<PeakerWork>conal: FieldTrip sounds really really cool.. Is there a tutorial anywhere or in some future plan?
23:15:19<conal>Baughn: oh yeah. what symptom do you get for the stream/quickcheck issue?
23:15:29<Baughn>conal: Won't install. cabal-install refuses.
23:15:31<mreh>so what I need to do is... make sure when folding the updateState method onto the old state, that all functional dependancies are resolved then
23:15:40<Baughn>conal: Must provide Stream-0.3 constraint on command line in some form to make it work.
23:15:53<conal>Baughn: and if you don't?
23:16:04<PeakerWork>conal: its the same one I told you about a while ago -- you said you added it to your in-civilization TODO list :) You depend on Stream-0.3.1 which depends on a newer QuickCheck which conflicts with some other dependency of quickcheck
23:16:08<conal>Baughn: i'm not getting any sign of brokenness.
23:16:30<Baughn>conal: Ah.. I'd need to uninstall both to get the exact error message
23:16:56<PeakerWork>conal: cannot configure Stream-0.3.1. It requires QuickCheck >=2.0 QuickCheck-2.1 was excluded because checkers-0.1.3 requires QuickCheck <2.0 QuickCheck-2.1.0.1 was excluded because checkers-0.1.3 requires QuickCheck
23:17:17<PeakerWork>conal: same message with s/checkers/reactive
23:17:39<Baughn>It's really kind of silly. Their quickcheck use doesn't involve the other library at all.
23:17:41<PeakerWork>conal: missing <2.0 in the end of that error message there
23:17:42<conal>PeakerWork: yeep. i wonder why i'm not getting this error with my new ghc (downloaded when i was in civ)
23:17:55<conal>PeakerWork: i'd like to make sure i really fix it.
23:18:01<Baughn>conal: You need to ghc-pkg unregister reactive and Stream first
23:18:12<PeakerWork>conal: did you explicitly specify quickcheck<2.0 dependency in reactive and checkers?
23:18:50<conal>PeakerWork: probably not. i'd better do so for now.
23:19:33<PeakerWork>conal: where is cabal taking that restriction from?
23:19:35<mreh>cheers for all the help guys
23:19:43<mreh>i'm going to zleep
23:19:44<conal>mreh: good luck!
23:20:17<mreh>it seems Haskell just keeps on giving
23:20:28<mreh>...me headaches
23:20:37<conal>sry. i'm getting lost in details here. what explicit dependencies do my libs need?
23:20:44<Baughn>mreh: You know about tying the knot, right?
23:20:52<conal>Baughn: which forkIO in particular?
23:21:10<conal>PeakerWork: i don't have a FieldTrip tutorial. unsure about its future.
23:21:27<Baughn>conal: I don't know. I just see a whole lot of thread activity.
23:22:02<conal>Baughn: okay. i'd expect so, because of unamb, which is at the heart of reactive.
23:22:23<Baughn>Ah. That thing.
23:22:27<conal>Baughn: unamb is the key to how i figured out how to implement push functionally.
23:22:47<conal>not literally push. more like blocking pul