Experimental IRC log haskell-2009-05-31

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:01:24<mux>> let allEq xs = case group xs of (_:_:_) -> False; _ -> True
00:01:25<lambdabot> not an expression: `let allEq xs = case group xs of (_:_:_) -> False; _ -> ...
00:01:34<mux>> let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,2]
00:01:36<lambdabot> False
00:01:40<mux>> let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,1
00:01:42<lambdabot> <no location info>: parse error (possibly incorrect indentation)
00:01:44<mux>> let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq [1,1]
00:01:46<lambdabot> True
00:01:51<mux>> let allEq xs = case group xs of (_:_:_) -> False; _ -> True in allEq []
00:01:53<lambdabot> True
00:08:46<Gracenotes>:.
00:31:58<MyCatVerbs>@pl (\x -> if x then '1' else '0')
00:31:58<lambdabot>flip (flip if' '1') '0'
00:32:41<MyCatVerbs>@pl (\x -> case x of { True -> '1'; False -> '0'; }
00:32:42<lambdabot>(line 1, column 18):
00:32:42<lambdabot>unexpected "{"
00:32:42<lambdabot>expecting variable, "(", operator or ")"
00:34:35<xian>@pl (\x -> case x of True -> '1'; False -> '0')
00:34:36<lambdabot>(line 1, column 23):
00:34:36<lambdabot>unexpected ">"
00:34:36<lambdabot>expecting variable, "(", operator or ")"
00:34:58<Tsion>Can someone join lambdabot to #botters, please? :)
00:48:22<Qriva>Could someone explain why the function 'simple x y z = x * (y + z)' is typed: simple :: Integer -> Integer -> Integer -> Integer ?
00:48:44<Qriva>Is it because it takes 3 integer values and produces an integer result?
00:49:26<EvilTerran>Qriva, er, yes
00:49:32<IntergalacticOwl>you'd think so!
00:50:04<Qriva>EvilTerran: is it more complicated than that? or should I quit reading into it?
00:50:06<Qriva>:)
00:50:18<EvilTerran>?type let simple x y z = x * (y + z) in simple
00:50:19<lambdabot>forall a. (Num a) => a -> a -> a -> a
00:50:33<EvilTerran>it's a bit more complicated than that :)
00:50:45<Qriva>can i do that in ghci EvilTerran ? (the type let simple...)
00:50:50<Qriva>EvilTerran: care to try to explain it to me?
00:51:05<EvilTerran>Qriva, yes, ":type let simple ... in simple" would work
00:51:12<EvilTerran>but i have to go to bed now, unfortunately
00:51:31<EvilTerran>i'm sure there's other helpful people awake in here
00:51:33<Qriva>no worries -- thanks
00:53:03<Qriva>?type [(2,3), (4,5)]
00:53:04<lambdabot>forall t t1. (Num t, Num t1) => [(t, t1)]
00:54:25<Qriva>^-What's the proper type of that? [(Integer)]?
00:54:36<Qriva>^-What's the proper type of that? [(Integer), (Integer)]?
00:55:42<Zao>Depends on context.
00:55:56<Zao>Until now, it's just two possibly different types conforming to Num
00:56:21<Qriva>In the HSoE book he asks that question in an exercise
00:56:29<Qriva>early in the book
00:56:31<Zao>The type to use could be inferred by context or by explicit signatures.
00:56:52<Qriva>Zao: how about ['z', -42]?
00:56:59<Qriva>[Char, Integer]?
00:57:02<xian>No.
00:57:09<xian>It's not an expression.
00:57:22<Zao>Qriva: That would be broken.
00:57:29<Qriva>I noticed -42 when you ask for it's type gives you an answer with an a, not a t
00:57:35<idnar>@type ['z', -42]
00:57:36<Qriva>?type ['z', -42]
00:57:37<lambdabot> No instance for (Num Char)
00:57:37<lambdabot> arising from a use of syntactic negation at <interactive>:1:6-8
00:57:37<lambdabot> Possible fix: add an instance declaration for (Num Char)
00:57:38<lambdabot> No instance for (Num Char)
00:57:38<lambdabot> arising from a use of syntactic negation at <interactive>:1:6-8
00:57:38<lambdabot> Possible fix: add an instance declaration for (Num Char)
00:57:48<Zao>A list needs all elements to be the same type.
00:58:13<Qriva>how about:
00:58:21<Qriva>?type ('z', 42)
00:58:22<lambdabot>forall t. (Num t) => (Char, t)
00:58:29<Qriva>err -42
00:58:34<Qriva>?type ('z', -42)
00:58:35<lambdabot>forall t. (Num t) => (Char, t)
00:59:10<Qriva>what does the t represent? am ambiguous type?
00:59:13<Qriva>an*
00:59:26<skorpan>just a type
00:59:45<skorpan>it's a "type variable", meaning it could be any type
00:59:52<skorpan>in this case, the type also has to instantiate Num
01:00:10<Qriva>why does :type -42 and :type 42 give the result in 'a' and 't' respectively?
01:00:19<skorpan>:t -42
01:00:20<skorpan>:t 42
01:00:20<lambdabot>forall a. (Num a) => a
01:00:21<lambdabot>forall t. (Num t) => t
01:00:33<skorpan>i'm not sure, but there's no difference really
01:00:59<Qriva>hmm, okay, ill just move on and quit harding on it for now :)
01:01:00<Zao>Literal vs. expression?
01:01:03<Qriva>harping*
01:01:09<idnar>@type +42
01:01:11<lambdabot>parse error on input `+'
01:01:13<idnar>aww
01:01:15<idnar>@type 0+42
01:01:16<lambdabot>forall t. (Num t) => t
01:01:27<skorpan>+42 would have been valid javascript though :P
01:01:28<Qriva>?type --42
01:01:29<Zao>Bah, theory disproven.
01:01:30<lambdabot>on the commandline:
01:01:30<idnar>@type 0-42
01:01:30<lambdabot> Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead
01:01:30<lambdabot><no location info>: not an expression: `'
01:01:31<lambdabot>forall t. (Num t) => t
01:01:36<Zao>Qriva: -- is a comment
01:01:41<Qriva>lol so it is!
01:01:48<Qriva>?type -(-42)
01:01:49<idnar>that was a bizarre error, though
01:01:50<lambdabot>forall a. (Num a) => a
01:02:25<Qriva>?type -(42)
01:02:26<skorpan>:t -(-(-42))
01:02:26<lambdabot>forall a. (Num a) => a
01:02:27<lambdabot>forall a. (Num a) => a
01:02:30<Qriva>:)
01:02:57<Qriva>how do you define a temporary binding on the bot?
01:03:02<skorpan>"let"
01:03:08<skorpan>> let x = 5 in x + 3
01:03:09<lambdabot> 8
01:03:16<skorpan>> let myList = [1,2,3]
01:03:17<lambdabot> not an expression: `let myList = [1,2,3]'
01:03:21<skorpan>okay, so that doesn't work
01:03:24<skorpan>@let myList [1,2,3]
01:03:24<lambdabot> Parse error
01:03:28<xian>> let myList = [1,2,3] in myList
01:03:28<skorpan>@let myList = [1,2,3]
01:03:30<lambdabot> [1,2,3]
01:03:30<lambdabot> Defined.
01:03:34<skorpan>> head myList
01:03:35<lambdabot> 1
01:03:38<Qriva>cool, thank you
01:04:15<Zao>Note that lambdabot also accepts private messages.
01:04:25<Qriva>I have to say I was completely flabbergasted at learning Haskell -- seemed beyond my reach, but Cale gave me a good intro the other night and im really getting into it
01:04:31<xian>By the way, how is lambdabot protected against evaluating infinite lists etc.?
01:04:32<Qriva>this is fun stuff to think about
01:04:55<skorpan>Qriva: beware though, programming anything else after having done some haskell will prove painful
01:05:50<idnar>@sum [1..]
01:05:51<lambdabot>Maybe you meant: bug run src
01:05:52<idnar>err
01:05:53<idnar>> sum [1..]
01:06:00<lambdabot> mueval-core: Prelude.read: no parse
01:06:00<lambdabot> mueval: ExitFailure 1
01:06:06<skorpan>uhh
01:06:12<skorpan>that's not what it usually does, is it?
01:06:15<Qriva>@let x = x + 1
01:06:15<idnar>well, that wasn't quite the message I was expecting
01:06:17<lambdabot> <local>:5:0:
01:06:18<lambdabot> Multiple declarations of `L.x'
01:06:18<lambdabot> Declared at: <local>:2...
01:06:24<skorpan>> sum [1..]
01:06:29<lambdabot> mueval-core: Prelude.read: no parse
01:06:29<lambdabot> mueval: ExitFailure 1
01:06:31<idnar>but those expressions get evaluated in a separate process, which is killed after a certain period of time
01:06:41<skorpan>lambdabot is ill
01:06:46<Qriva>ACTION hugs lambdabot
01:07:54<Qriva>Is there a way to tell lambdabot something like:
01:07:59<Qriva>x :: Float
01:08:48<skorpan>what do you mean?
01:09:11<cads>hey, is there any way to turn f::(a, b, c, d ...) -> p into f'::a->b->c->d->...->p ?
01:09:33<skorpan>:t uncurry
01:09:35<lambdabot>forall a b c. (a -> b -> c) -> (a, b) -> c
01:09:38<skorpan>:t curry
01:09:39<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
01:10:19<skorpan>maybe something along the lines of `curry'
01:11:07<skorpan>cads: seeing as tuples of different lengths have different types, you may have to write your own function for it
01:11:16<eck>is there a way to get sprintf functionality out of Text.Printf?
01:11:47<kpreid>eck: if you let the return type be a string then it is sprintf
01:11:53<eck>ah, thanks
01:11:55<kpreid>then printf is sprintf, I mean
01:12:13<Qriva>skorpan: to be honest I don't really know what I mean -- many examples I'm looking at look like: totalArea :: Float totalArea = pi * r1^2 + pi * r2^2 + pi * r3^2
01:12:21<Qriva>Is that type 'declaration' necessary?
01:12:29<skorpan>Qriva: rarely is it necessary
01:12:59<skorpan>:t fromIntegral 1
01:13:00<lambdabot>forall b. (Num b) => b
01:13:20<skorpan>:t 1
01:13:21<lambdabot>forall t. (Num t) => t
01:13:22<Qriva>whoa now we've got a b! a, b, and t
01:13:45<cads>skorpan: "currying is a very important theoretical device because it reduces multiple-argument functions to single-argument functions only (Schoenfinkel, 1924"
01:13:51<Qriva>:t 0 - 1
01:13:52<lambdabot>forall t. (Num t) => t
01:14:13<skorpan>cads: what are you saying?
01:14:52<cads>well, in haskell it seems like the analogue of multi-arg functions, since functions are all normally curried, is a function that takes a tuple of some rank
01:15:32<cads>but how can we use the curry function to turn a function on a higher rank tuple into a curried form?
01:16:00<skorpan>you can't, afaik, but then again, what do i know
01:17:24<skorpan>afaik, in haskell, you can't have a function which takes a tuple of "any length", and therein lies the issue
01:18:46<idnar>@type curry
01:18:48<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
01:18:54<idnar>@type curry . curry
01:18:55<lambdabot>forall a b b1 c. (((a, b), b1) -> c) -> a -> b -> b1 -> c
01:19:07<idnar>@type curry . curry . curry
01:19:08<lambdabot>forall a b b1 b2 c. ((((a, b), b1), b2) -> c) -> a -> b -> b1 -> b2 -> c
01:19:24<skorpan>idnar: it's just too bad ((a, b), c) isn't the same as (a, b, c) :)
01:19:35<idnar>skorpan: some people think only the first one of those should exist :P
01:19:48<idnar>except I think they usually want (a, (b, (b1, (b2, ()))))
01:20:28<skorpan>idnar: i can understand that, but that's almost the equivalent of heterogeneous lists
01:20:41<idnar>except it's type-level
01:20:46<skorpan>yes
01:22:02<cads_>skorpan: I got disconnected so I missed any replie
01:22:19<skorpan><skorpan> you can't, afaik, but then again, what do i know
01:22:28<cads_>:t curry . curry . curry
01:22:30<lambdabot>forall a b b1 b2 c. ((((a, b), b1), b2) -> c) -> a -> b -> b1 -> b2 -> c
01:24:09<cads_>skorpan: hehe, I am looking up shoenfinkel '24 to see what he means by that
01:34:56<Qriva>So I'm reading the HSoE book and I'm trying to run the code he provides for a function but I can't get it to run
01:35:12<Qriva>@let listSum [] = 0
01:35:13<lambdabot> Defined.
01:35:32<Qriva>@let listSum (x:xs) = x + listSum xs
01:35:33<lambdabot> Defined.
01:35:44<Qriva>> listSum [1,2,3]
01:35:45<lambdabot> 6
01:35:52<Qriva>why doesn't this work in my GHCI?
01:36:20<Ralith>because your GHCI is overriding, not overloading, the previous definition.
01:36:50<Qriva>how do I fix that or get around it?
01:36:56<Ralith>> let listSum (x:xs) = x + listSum xs; listSum [] = 0
01:36:57<lambdabot> not an expression: `let listSum (x:xs) = x + listSum xs; listSum [] = 0'
01:37:01<Ralith>> let listSum (x:xs) = x + listSum xs; listSum [] = 0 in listSum [1,2,3]
01:37:02<xian>Put the definition in a file and then :load it into your ghci session.
01:37:02<lambdabot> 6
01:37:11<Ralith>or do what I just demonstrated
01:37:13<Ralith>:P
01:37:38<Ralith>(the '...in listSum [1,2,3]' bit isn't necessary if you're in GHC; the definition will stick.)
01:40:27<Qriva>thanks Ralith, im still newbin it up
01:46:24<Qriva>when im load a .hs file into ghci, does it matter the order the functions inside of it were written?
01:46:46<harlekin>Qriva, no
01:49:50<Ralith>Qriva: yes, it does, I'm pretty sure.
01:50:11<Ralith>you want most specific pattern match first.
01:51:03<Ralith>e.g. if you have foo x = x and foo (y:ys) = y then you'll want to put the latter first or else it'll never get hit (ghc should warn you about this)
01:51:47<eck>i'm pretty impressed by Data.Binary
01:51:47<xian>But harlekin is right that the order in which *functions* are defined is irrelevant.
01:51:53<eck>ACTION spent the better part of the day packing bits
01:52:37<Ralith>xian: okay, fair, but that probably wasn't the question Qriva meant to ask.
02:25:58<hackagebot>either-unwrap 1.0
02:29:11<Qriva>Ralith: actually I did sort of mean what xian said
02:30:01<Qriva>Ralith: although i am curious about the whole :load'ing process in general in ghci
02:32:14<Axman6>@hackage either-unwrap
02:32:14<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/either-unwrap
02:37:05<aavogt>so that library writer is aware of the function either?
02:37:47<aavogt>does eitherM === either?
02:38:06<aavogt>with slightly different parameter order
02:38:17<Axman6>:t either
02:38:18<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
02:38:29<Axman6>yeah, that's all eitherM is
02:39:50<aavogt>hmm, and the type isn't that much more specific that it will reduce the number of required annotations
02:40:48<jasondew>anyone feel like looking at some haskell code and pointing me in the right direction to speed it up? i've done profiling, looking at core, etc, etc
02:41:09<idnar>what's the type of eitherM?
02:41:19<aavogt>eitherM :: Monad m => Either a b -> (a -> m c) -> (b -> m c) -> m c
02:41:43<idnar>huh
02:42:50<aavogt>I like the parameter order on the regular either better
02:42:53<idnar>yeah, that's just weird
02:43:03<idnar>there's no particular point in the Monad annotation
02:43:15<idnar>which in turn makes the naming convention weird
02:44:41<aavogt>@type \x -> either ?f ?g =<< x
02:44:43<lambdabot>forall a b (m :: * -> *) b1. (?f::a -> m b1, ?g::b -> m b1, Monad m) => m (Either a b) -> m b1
02:45:12<aavogt>@type either (?f =<<) (?g =<<)
02:45:14<lambdabot>forall a (m :: * -> *) b a1. (?f::a -> m b, Monad m, ?g::a1 -> m b) => Either (m a) (m a1) -> m b
02:45:48<aavogt>@type on either (=<<)
02:45:50<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> (a -> m b) -> Either (m a) (m a) -> m b
02:46:12<Qriva>my 'friend' is telling me he thinks Haskell is 'kind of a toy'
02:46:16<Qriva>what do you even say to something like that?
02:46:53<Gracenotes>:>
02:47:06<inimino>"that's nice"?
02:47:09<inimino>nothing?
02:47:19<idnar>Qriva: well, it's a toy that's used to write financial software for banks :P
02:47:40<inimino>ACTION would probably smile and move on ;-)
02:47:50<Qriva>i feel bad for him -- he's so set on the idea that all he needs to do is go through a compsci program, learn Java and some C, and that's it
02:48:00<Qriva>im trying to open him up to the idea that there's more out there
02:48:05<inimino>Qriva: why is he studying CS?
02:48:09<shapr>Yeah, really.
02:48:20<p_l>Qriva: He probably will fail C with that kind of mindset
02:48:26<Qriva>he's like a lot of CS majors -- no other clue what to do
02:48:31<Qriva>and thinks it will make him money
02:48:39<shapr>Can't argue with that.
02:48:40<inimino>based on your description so far, it's probably for the money
02:48:42<inimino>yeah
02:48:47<inimino>no point in trying to help the guy then
02:48:54<p_l>Qriva: Java isn't helping. I'm surprised Java people can write any C without failing... oh
02:49:05<inimino>if we's in it for the money, let him learn Java and make what money he can
02:49:13<inimino>s/we's/he's/
02:49:33<Qriva>he has an interest in computers, but once i get onto ANY sort of theoretical discussion with him about i dont know, functional programming, persistence, blah blah
02:49:39<p_l>inimino: if he wants money, he should learn COBOL
02:49:43<Qriva>he just shrugs like he doesn't care
02:49:52<inimino>in my opinion people who learn programming for that reason rarely get good at it, and then only by accident
02:50:27<Qriva>he's just not passionate about it, which is really sad, i dont know
02:50:40<inimino>my advice would be to treat him as you would any other professional in a field that is not your own
02:50:42<Qriva>i cant save 'em all, but i thought id give it a try
02:51:07<aavogt>@faq can Haskell save souls?
02:51:07<lambdabot>The answer is: Yes! Haskell can do that.
02:51:11<Qriva>lol
03:04:31<Gracenotes>hallelujah
03:04:34<Gracenotes>..
03:05:33<athos>hm
03:05:38<athos>it's already 5am
03:14:05<alexsuraci>In Control.Concurrent.Chan, what if I write to a channel before something tries to read from it? Does the value get lost?
03:14:35<alexsuraci>I'm thinking no but it would explain the trouble I'm having
03:16:09<hydo>slow day...
03:16:26<hydo>sorry, alexsuraci, I don't know.
03:16:34<luqui>alexsuraci, it gets queued up
03:16:35<lambdabot>luqui: You have 1 new message. '/msg lambdabot @messages' to read it.
03:16:57<Gracenotes>alexsuraci: how soon before?
03:17:01<alexsuraci>luqui: that's what I thought
03:17:07<alexsuraci>Gracenotes: can't be certain
03:19:16<alexsuraci>well, I'm getting a "thread blocked indefinitely" and it seems to be happening when it's reading from a channel, even after I write to it
03:19:33<alexsuraci>maybe I'm writing to two different channels accidentally, hmm
03:20:37<alexsuraci>it can't be that the channel's simply empty though, readChan would wait in that case
03:20:50<alexsuraci>so something deeply sinister must be going on
03:23:51<Gracenotes>D:
03:24:51<Gracenotes>well, don't underestimate stdout. The source for Chan is simple-ish, so you could make your own module plus debugging... concurrency bugs are so annoying :/
03:25:12<alexsuraci>yeah I've made extensive use of Debug.Trace :P
03:25:15<bos>"thread blocked indefinitely" usually means a bug in your code.
03:25:32<alexsuraci>yeah, figured that much, I'm just not sure what causes it specifically
03:28:37<bos>alexsuraci: it means that your thread has the only reference to the Chan (or the MVars it's constructed with)
03:29:01<bos>alexsuraci: since no other thread has a reference to it, when you try to read from the Chan, it's not possible for the thread ever to wake
03:31:20<alexsuraci>ah, thanks
03:31:24<Gracenotes>as I said a few days ago, Chan needs to borrow some functionality from the MVars used to implement it. tryTake and tryPut, would be useful :/
03:32:27<Gracenotes>if that's possible
03:32:36<alexsuraci>bos: to be clear, by "your thread" you mean the thread trying to read from it, right?
03:32:48<bos>right
03:33:20<alexsuraci>alright, thanks
03:34:35<alexsuraci>in other news, if anyone's in the Fort Wayne, IN area help me find my cat :( https://post.craigslist.org/manage/1197573122/ysf8v
03:34:43<alexsuraci>http://fortwayne.craigslist.org/laf/1197573122.html rather
03:37:04<centrinia>Is there a way to set the channel's queue size?
03:38:52<mmorrow>Gracenotes: this is the replacement for Chan i use now http://moonpatio.com/repos/vacuum-gl/System/Vacuum/OpenGL/Q.hs
03:39:06<mmorrow>(ever since i was told that
03:39:10<Gracenotes>I have seen :)
03:39:20<mmorrow>forkIO (takeChan ch >> return ())
03:39:23<mmorrow>isEmptyChan ch
03:39:25<mmorrow>blocks
03:39:28<Gracenotes>do you have Haddocks of it?
03:39:35<mmorrow>Gracenotes: no, but i should
03:39:41<Gracenotes>preferably fried?
03:39:47<mmorrow>weee
03:41:46<mmorrow>centrinia: by channel you mean Chan? (and if so, what would be the desired behavior when the queue is full and a thread tries to add an elem to the Chan? (to block i assume?))
03:42:16<centrinia>Maybe the queue size can be set only once?
03:42:25<alexsuraci>is there a more detailed spec sheet on the concurrency implementations I could read up on?
03:43:08<Gracenotes>hm. I wish there was a built-in thing for return () :: Monad m => m (). No idea what it would be called though.
03:43:41<kpreid>Gracenotes: void;
03:43:44<kpreid>?
03:43:45<centrinia>Gracenotes, It would be called return () :p
03:43:46<mmorrow>alexsuraci: i peeked at this the other day and it looks like a good intro http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/AFP08-notes.pdf
03:43:52<Gracenotes>kpreid: oooh. I like.
03:43:58<centrinia>:t return ()
03:43:59<lambdabot>forall (m :: * -> *). (Monad m) => m ()
03:44:10<Gracenotes>centrinia: well. You know how it is with multiparameter functions and having to use parentheses.
03:44:17<alexsuraci>mmorrow: thanks
03:44:19<centrinia>@let void = return ()
03:44:21<lambdabot> Defined.
03:44:26<centrinia>> void
03:44:27<lambdabot> No instance for (GHC.Show.Show (m ()))
03:44:27<lambdabot> arising from a use of `M728820821...
03:45:16<bos>> void :: IO ()
03:45:17<lambdabot> <IO ()>
03:50:10<mmorrow>alexsuraci: actually, looking at that paper it looks like there's only a brief section on MVars, and the rest on STM.. so the three different ways of doing concurrent stuff are basically (IORef+atomicModifyIORef, MVar, and STM) (in decreasing order of speed and increasing order of ease-of-implementation)
03:50:35<centrinia>Oh, Chan has a queue size of 1.
03:50:52<mmorrow>centrinia: what do you mean by queue size?
03:51:28<centrinia>The number of elements that can be put in the FIFO.
03:51:41<mmorrow>it's unbounded
03:51:45<alexsuraci>mmorrow: ah, ok
03:52:10<centrinia>Okay.
03:52:41<mmorrow>alexsuraci: i liked this one: http://www.haskell.org/~simonmar/papers/concurrent-data.pdf
04:00:48<alexsuraci>mmorrow: looks nice and brief with plently of code examples. I approve. ;) Thanks.
04:01:01<mmorrow>alexsuraci: np :)
04:10:21<halberd>as I understand it, in type theory an expression can have multiple types--correct? how come in Haskell then we talk about "the" type of an expression?
04:10:44<Gracenotes>you're referring to polymorphism?
04:11:17<codebliss>@src join
04:11:17<lambdabot>join x = x >>= id
04:11:19<Gracenotes>a polymorphic type is still a type.
04:11:25<codebliss>How does that work? I still don't get it
04:11:51<NEEDMOAR>In some type systems, every expression has only one type, halberd.
04:11:53<alexsuraci>codebliss: >>= is equivalent to concatMap with lists
04:11:56<codebliss>Since id :: a -> a, and that part of (>>=) is (a -> m b), that means a has to be m b, and it would be (m b -> m b)?
04:12:14<Gracenotes>yes
04:12:17<codebliss>alexsuraci: I never said anything about lists?
04:12:31<alexsuraci>codebliss: sorry, assumed that's what you meant based on the context
04:12:33<Gracenotes>codebliss: you're right..
04:12:35<halberd>well Lambda ((x) x) has the type List A -> List A, and also the type Eq A -> Eq A, for example
04:12:40<codebliss>alexsuraci: No problem =)
04:12:59<Gracenotes>halberd: that's a union of types. which is one type.
04:13:07<Gracenotes>er, I mean, intersection
04:13:11<codebliss>OH
04:13:14<halberd>they are 2 different types which can be derived for the expression
04:13:20<halberd>using the rules of type theory
04:13:24<codebliss>so it's m (m b) -> (m b -> m b) -> m b
04:13:26<codebliss>OH
04:13:39<codebliss>Lol sorry, I never looked back at that first a XD
04:13:44<NEEDMOAR>hellige: in which type theory?
04:13:59<halberd>the type of an expression can be interpreted as just a proposition that is true of that expression, so there shouldn't be any limit to the number or kind of types a dependently typed expression might have, should there?
04:14:44<halberd>because any number of propositions might be true of a given expression
04:14:50<Gracenotes>unions and intersections of types are formulated pretty solidly in type theory
04:15:14<Gracenotes>halberd: you might be interested in http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf
04:15:19<NEEDMOAR>halberd: you do not state which type system are you using...
04:15:57<halberd>martin lof's type theory, as presented in the introduction by nordstrom, petersson, and smith
04:16:31<Gracenotes>..could've said that..
04:16:33<NEEDMOAR>halberd: well, intuicionistic type theory is not the same as Haskell's types.
04:16:44<halberd>I know that
04:18:37<Gracenotes>halberd: you've come asking here about Martin Lof's theory before, but.. I think LtU might know more? :) or maybe #haskell-in-depth
04:19:23<NEEDMOAR>halberd: you can talk about the type of an expression in Haskell, because the type system (probably) assures that an expression has only one type.
04:19:53<NEEDMOAR>Well, that's more or less.
04:19:57<halberd>ah #haskell-in-depth... didn't realize it existed
04:20:00<NEEDMOAR>You have the most generic type, etc.
04:21:25<aavogt>I'm having difficulties with specifying endomorphisms that work within an existential type
04:22:25<mmorrow>aavogt: unless you package the function within the same box that you put the data when you first box it up, the type system will refuse
04:22:48<mmorrow>(if i'm understanding your situation correctly)
04:25:33<mmorrow>(e.g. data A b = forall a. A (a -> b) a)
04:25:36<halberd>Gracenotes: I'm in the habit of asking #haskell for any computer-science-related question, just because it is full of computer science people
04:25:39<halberd>and math people
04:25:57<halberd>unlike #c or #java or #python
04:26:32<halberd>it's hit or miss though... I'll check out lambda the ultimate
04:26:43<copumpkin>isn't #python really strict? or was that another one
04:27:12<halberd>strict? well I never tried bending the rules in there
04:27:16<halberd>so I don't know
04:27:20<mmorrow>copumpkin: heh, what do you mean strict
04:27:22<mmorrow>?
04:27:24<aavogt>mmorrow: sort of like that
04:27:35<aavogt>I want to write something like:
04:27:43<halberd>but the people who frequent #python tend not to be as theoretically minded as the #haskell people
04:27:54<Gracenotes>halberd: sure... I understand
04:27:57<aavogt>liftExistential f (Box a) = Box (f a)
04:28:02<copumpkin>oh, I thought I heard someone that you get flamed/kicked for anything remotely off-topic and that it's full of the typical IRC-types who like to correct your question before answering it
04:28:08<copumpkin>but I've never been there myself so I don't know :)
04:28:20<mmorrow>so, (data Box = forall a. Box a) i take it?
04:28:22<Gracenotes>don't mind me :P
04:28:43<aavogt>this Box has some typeclass constraints too
04:28:59<aavogt>but that's basically it
04:29:03<mmorrow>aavogt: ah, ok. in that case you have at least something to work with
04:29:28<mmorrow>aavogt: but in the general case, you'd have to ensure correctness yourself and then just unsafeCoerce
04:29:36<mmorrow>@src fromDynamic
04:29:37<lambdabot>fromDynamic (Dynamic t v) = case unsafeCoerce v of
04:29:37<lambdabot> r | t == typeOf r -> Just r
04:29:37<lambdabot> | otherwise -> Nothing
04:29:47<mmorrow>@src Dynamic
04:29:47<lambdabot>Source not found. Maybe you made a typo?
04:29:53<mmorrow>@src Dyn
04:29:54<lambdabot>Source not found. That's something I cannot allow to happen.
04:30:18<aavogt>this seems close: liftLayout :: (LayoutClass l a, Read (l a), LayoutClass m a, Read (m a)) => (l a -> m a) -> Layout a -> Layout a
04:30:46<mmorrow>what's the def of Layout?
04:31:21<aavogt>but I can't get the (l a) to refer to the (l1 a) that's inside the (Layout a) argument
04:31:39<Berengal>I just had the weirdest dream. I was collecting pokemon-ish creatures in Bowser's castle, fighting of Bernie the dinosaur (or whatever his name), looking for a red and a blue monoid I could mappend with my yellow one and save the universe from Princess Peach...
04:32:11<aavogt>data Layout a where Layout :: forall a l. (LayoutClass l a, Read (l a)) => (l a) -> Layout a
04:32:29<Gracenotes>:ox
04:33:20<hydo>Berengal: Pr. Peach is the villain now adays or is this just in your dream?
04:33:54<Berengal>hydo: She wasn't a villain. She was the villain's secret weapon (against her will)
04:34:12<hydo>aww... poor pixelated thing.
04:34:30<mmorrow>aavogt: hmm
04:38:15<aavogt>I have a feeling that it is possible, but unsafeCoerce will prevent ghc from picking the correct class instances?
04:38:39<mmorrow>aavogt: so you need to forall the `l' there http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5436#a5436
04:39:01<sjanssen>aavogt: btw, I would prefer not to have unsafeCoerce# in xmonad's source code :)
04:39:03<mmorrow>since you don't know that the `l' your function works on is the same `l' that's in the box
04:39:14<sjanssen>aavogt: what if layout transformers were of type "Layout a -> Layout a"?
04:40:13<mmorrow>aavogt: so in that case, unsafeCoerce would just result in segfault
04:40:42<mmorrow>(but with the alternative liftLayout in that paste you don't need it)
04:44:00<mmorrow>ooh, also this is an option too
04:44:04<aavogt>sjanssen: yeah, I'm after layout transformers to be Endo (Layout a)
04:44:39<mmorrow>liftLayout :: (LayoutClass m a) => (forall l. LayoutClass l a. => l a -> m a) -> Layout a -> Layout a
04:45:53<sjanssen>that seems easy to write, no?
04:47:08<aavogt>mmorrow: any ideas as how to solve the: Inferred type is less polymorphic than expected; Quantified type variable `l' escapes
04:47:30<hackagebot>bindings-common 0.1
04:47:56<aavogt>from say (liftLayout Mirror) where Mirror has the correct instances
04:52:16<mmorrow>hmm
04:54:23<mmorrow>aavogt: i'd have to see the specific code i think
04:55:01<mmorrow>(like, what's the definition of LayoutClass, and of Mirror, and which version of liftLayout are you using?)
04:55:23<aavogt>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5437#a5437
04:55:29<mmorrow>ACTION looks
04:57:15<mmorrow>aavogt: what about Mirror?
04:57:23<mmorrow>(are these all in XMonad?)
04:57:33<hackagebot>bindings-sqlite3 0.0.1
04:57:48<aavogt>mmorrow: http://hackage.haskell.org/packages/archive/xmonad/0.8.1/doc/html/XMonad-Layout.html#t%3AMirror
04:57:59<mmorrow>ha, perfect
04:58:03<mmorrow>s/ha/ah/
05:00:33<hackagebot>bindings-libusb 0.0.1
05:04:49<malouin>how does HDBC relate to hsql?
05:05:19<Gracenotes>Haskell :D
05:06:22<Apocalisp>@bot
05:06:22<lunabot> :)
05:06:31<lambdabot>:)
05:07:25<Elly>haskell relates to everything
05:07:30<Elly>by force if necessary
05:08:40<aavogt>thanks for helping with this mmorrow, I think the latest problem is the that resuling layout type (m) depends on the input (l). But it doesn't really escape afaict :(
05:09:01<mmorrow>yeah, it's the `l' in Mirror that's causing the problem here
05:09:18<mmorrow>you might be able to work around it by making something like:
05:09:24<mmorrow>data ExistMirror a = forall l. (LayoutClass l a, Read (l a)) => ExistMirror (Mirror l a)
05:09:40<mmorrow>and using that, but then you have to hand-define an instance of Read for that
05:10:20<mmorrow>(which i was just trying but am getting errors about "(LayoutClass l a, Read (l a))" not being known, even though it's there in the ExistMirror def
05:10:24<mmorrow>which is annoying
05:10:39<mmorrow>maybe if ExistMirror was a GADT?
05:10:52<mmorrow>anyways, yeah this looks semi-painful :)
05:11:34<dmwit>> 6^6^6 * logBase 10 6 :: CReal
05:11:39<lambdabot> mueval-core: Prelude.read: no parse
05:11:39<lambdabot> mueval: ExitFailure 1
05:11:45<dmwit>> 6 :: CReal
05:11:46<lambdabot> 6.0
05:11:54<dmwit>> 6^6^6 :: CReal
05:12:00<lambdabot> mueval-core: Prelude.read: no parse
05:12:00<lambdabot> mueval: ExitFailure 1
05:12:04<dmwit>okay then
05:14:40<aavogt>> 6^6^6
05:14:42<lambdabot> 265911977215322677968248940438791859490534220026992430066043278949707355987...
05:14:51<aavogt>> 6^6
05:14:52<lambdabot> 46656
05:15:01<aavogt>> 6^6 :: CReal
05:15:02<lambdabot> 46656.0
05:15:19<aavogt>> length $ show $ 6^6^6
05:15:20<lambdabot> 36306
05:15:37<hackagebot>bindings 0.1.1
05:19:22<aavogt>mmorrow: the layout being modified shows up in the type of every modified layout, but perhaps the best thing to do would be to change them to start off as (Layout a -> Layout a)
05:19:58<aavogt>since this liftLayout has not worked out
05:20:50<mmorrow>possibly, i'm not sure all the moving pieces. what hard here is that you can't modify the types that already exist in xmonad..
05:21:31<mmorrow>aavogt: but yeah, i'd probably try a different angle of attack
05:22:50<mmorrow>(different from the original i mean, not different than (Layout a -> Layout a), that could work (not sure) :)
05:35:23<aavogt>mmorrow: thanks again, and good night. Hopefully we'll find a better solution to this issue later.
05:38:41<mmorrow>aavogt: good luck
05:49:03<jimmyjazz14>I'm looking for an example of mapping a function over the lines in a file.
05:50:45<mmorrow>main = putStr . unlines . fmap f . lines =<< getContents
05:51:23<mmorrow>better would be
05:51:26<mmorrow>main = putStr . unlines . f . lines =<< getContents
05:51:31<mmorrow>then you could do e.g.
05:51:51<mmorrow>f = zipWith (\n l -> n ++ ":" ++ l) [1..] -- number lines
05:51:53<mmorrow>etc
05:52:19<Gracenotes>:o
05:52:32<mmorrow>f = fmap (show . length) -- number of char on each line
05:53:01<mmorrow>err, show n
05:53:06<mmorrow>f = zipWith (\n l -> show n ++ ":" ++ l) [1..] -- number lines
05:57:01<rick_2047>hi everyone i was just starting out with haskell and was curious about its functional programming paradigim. i heard its very closely related to discrete mathematics. i am interested in maths so can anyone point me to a source which teaches me this language with a mathematical problem approach
05:57:04<jimmyjazz14>ah thanks
05:59:14<Twey>rick_2047: Perhaps ‘The Haskell Road to Logic, Maths, and Programming’
06:00:15<rick_2047>Twey, sounds interesting lemme just read a review on amazon
06:01:03<Twey>I'm not sure I'd describe Haskell as ‘closely related’ to any branch of mathematics
06:01:18<Twey>It does use a lot of mathematical concepts, but at its heart it is a programming language
06:01:40<Twey>Better to say it borrows from mathematics, perhaps
06:02:27<rick_2047>Twey, dats exactly what i mean but you see haskell is used in a lots of maths project and a friend suggested that i use it in my math experiments
06:03:36<Twey>Don't forget that Mathematic is the world's most powerful computational software.
06:03:39<Twey>Mathematica**
06:15:16<sayyestolife>what's up?
06:17:00<dmwit>?wn up
06:17:11<dmwit>uh...
06:17:13<dmwit>?botsnack
06:17:27<dmwit>Don't worry, I've got \bot's back!
06:17:47<dmwit>up (adj): being or moving higher in position or greater in some value
06:19:03<dmwit>sayyestolife: Doing any awesome Haskell hacks?
06:19:28<lambdabot>*** "up" wn "WordNet (r) 2.0"
06:19:28<lambdabot>up
06:19:28<lambdabot> adj 1: being or moving higher in position or greater in some value;
06:19:30<lambdabot> being above a former position or level; "the anchor is
06:19:32<lambdabot> up"; "the sun is up"; "he lay face up"; "he is up by a
06:19:33<sayyestolife>dmwit, no, I'm actually trying to figure out if there is a way to get max integer size in Ada
06:19:34<lambdabot>[28 @more lines]
06:19:36<lambdabot>:)
06:19:40<dmwit>laaaag
06:19:47<ski>@uptime
06:19:48<lambdabot>uptime: 5d 23h 25m 16s, longest uptime: 1m 10d 23h 44m 29s
06:20:13<dmwit>ACTION didn't know anybody used ada any more
06:20:26<sayyestolife>heh, it's for university
06:25:27<p_l>dmwit: it's still used in the same places as always :)
06:25:53<dmwit>so... the military?
06:26:51<stepnem>http://auroraux.blastwave.org/index.php/Main_Page
06:27:38<p_l>dmwit: embedded and critical stuff
06:32:52<hydo>Out of curiosity, does anyone here use netbsd? I'm thinking of using it for an embedded experiment.
08:01:08<mreh>@go yi
08:01:10<lambdabot>http://en.wikipedia.org/wiki/Yi
08:01:10<lambdabot>Title: Yi - Wikipedia, the free encyclopedia
08:01:24<mreh>@go site:haskell.org yi
08:01:26<lambdabot>http://www.haskell.org/haskellwiki/Yi
08:01:26<lambdabot>Title: Yi - HaskellWiki
08:41:48<dibblego>@type \x f -> case x of [] -> []; (h:t) -> f h : t -- is there a combinator for this in the standard library?
08:41:49<lambdabot>forall a. [a] -> (a -> a) -> [a]
08:44:31<Gracenotes>not that I know of...
08:50:02<ski>@let list :: as -> (a -> as -> as) -> ([a] -> as); list nil cons [] = nil; list nil cons (a:as) = cons a as
08:50:03<lambdabot> Couldn't match expected type `as' against inferred type `[a]'
08:50:17<ski>@let list :: as -> (a -> [a] -> as) -> ([a] -> as); list nil cons [] = nil; list nil cons (a:as) = cons a as
08:50:18<lambdabot> Defined.
08:50:35<ski>@type flip $ \f -> list [] ((:) . f)
08:50:37<lambdabot>forall b. [b] -> (b -> b) -> [b]
09:06:12<dibblego>@type \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x)
09:06:13<lambdabot>forall a. (a -> a) -> [a] -> [a]
09:06:29<dibblego>>let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k "abc"
09:06:33<dibblego>> let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k "abc"
09:06:35<lambdabot> Couldn't match expected type `a -> a'
09:06:41<dibblego>> let k = \f x -> ((++) . (f <$>)) `uncurry` (splitAt 1 x) in k toUpper "abc"
09:06:42<lambdabot> "Abc"
09:06:47<voker57__>how to modify one field in 'data' type?
09:07:04<ski>> (\f -> list [] ((:) . f)) toUpper "abc"
09:07:06<lambdabot> "Abc"
09:07:33<lars9>hi, who knows how to uninstall all packages installed by cabal-install?
09:07:42<voker57__>like ???? $ Wtf {a = 2, b =3} = Wtf {a=2, b=4}
09:08:00<eivuokko>lars9, Assuming ghc, use ghc-pkg unregister to remove them from package database and remove the files by hand.
09:08:31<ski>let wtf = Wtf {a = 2, b = 3} in wtf {b = 4} -- voker57__ ?
09:10:50<ski>> let wtf = Node {rootLabel = 2,subForest = []} in wtf {subForest = [Node {rootLabel = 3,subForest = []}]}
09:10:52<lambdabot> Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = []}]}
09:11:50<cayennext>I am trying to implement IO using dialogs and I have some problems with it. Process is a function that takes a request and returns response and program is a function that returns list of requests and have responses passed as argument. Please look at those 13 lines of code: http://pastebin.com/m2f1e06d0. It works well if both functions are pure ((1) in code). But when I added IO to process ((2) in code), it doesn't work. Can someon
09:11:50<cayennext>e help me with this?
09:11:52<ski>let ftw wtf = wtf {subForest = [Node {rootLabel = 3,subForest = []}]} in ftw $ Node {rootLabel = 2,subForest = []}
09:11:55<ski>> let ftw wtf = wtf {subForest = [Node {rootLabel = 3,subForest = []}]} in ftw $ Node {rootLabel = 2,subForest = []}
09:11:57<lambdabot> Node {rootLabel = 2, subForest = [Node {rootLabel = 3, subForest = []}]}
09:16:02<ski> {-# LANGUAGE RecursiveDo #-}
09:16:04<ski> run :: IO (List Request, List Response)
09:16:13<ski> run = mdo responses <- process requests
09:16:23<ski> let requests = program responses
09:16:32<ski> return (requests, responses)
09:16:44<ski>cayennext : tried something like that ?
09:16:59<cayennext>I didn't know about this lang extension
09:17:12<cayennext>thank you
09:17:37<ski>Chapter 7. GHC Language Features 7.3. Syntactic extensions 7.3.6. The recursive do-notation <http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#mdo-notation>
09:18:31<voker57__>ski: thanks
09:19:54<ski>The Hugs 98 User's Guide - Chapter 6. Language extensions supported by Hugs and GHC - 6.1. Syntactic extensions - 6.1.1. Recursive do-notation - <http://cvs.haskell.org/Hugs/pages/users_guide/hugs-ghc.html#RECURSIVE-DO>
09:20:43<cayennext>there's a problem: <<exception: loop>>
09:22:12<cayennext>my code heavily relies on laziness, can it work with unfinished data?
09:23:05<ski>possibly you need to use `~' (more ?) ?
09:23:12<cayennext>from documentation: "The do-notation of Haskell does not allow recursive bindings". That's what I am trying to do in this code.
09:23:25<cayennext>sorrry
09:23:34<cayennext>thought it's about mdo
09:23:55<voker57__>wtf {a=3} works ok, but can i use it as curried function? Like for map
09:24:20<ski> map (\wtf -> wtf {a = 3})
09:24:57<voker57__>ah, lambdas
09:25:54<Beelsebob>voker57__: usually the first thing I do when I define a record is write a bunch of boilerplate definitions:
09:26:14<Beelsebob>setA w na = w{a=na}
09:26:16<Beelsebob>etc
09:26:37<voker57__>not nice at all...
09:26:48<Beelsebob>no, record syntax in haskell fails
09:27:34<ski>@type let foo Node {rootLabel = r,subForest = f} = (r,f) in foo
09:27:36<lambdabot>forall t. Tree t -> (t, Forest t)
09:27:45<ski>@type let foo t {rootLabel = r,subForest = f} = (t,r,f) in foo
09:27:46<lambdabot>Parse error in pattern
09:28:02<ski>@type let foo (t {rootLabel = r,subForest = f}) = (t,r,f) in foo
09:28:04<lambdabot>Parse error in pattern
09:28:06<ski>mhm
09:28:11<mux>Data.Accessor helps with that
09:48:44<cayennext>fun = do { x <- g; return 1:x }. If g = _|_, can I get head of f where f <- fun?
09:49:58<Twey>cayennext: Yes
09:50:09<cayennext>What extension shoul I use?
09:50:16<Twey>No extension required
09:50:23<Twey>Oh!
09:50:30<Twey>Depends on the monad, though
09:50:35<cayennext>IO
09:50:43<Twey>Yeah, IO is strict, so that won't work
09:50:55<Twey>x can be _|_, but g cannot
09:50:56<cayennext>any extension magic to fix this?
09:51:10<Twey>No — it doesn't make sense to ‘fix’ it
09:51:26<Twey>Imagine if your IO actions weren't performed in the order you told them to be :-P
09:51:35<cayennext>:)
09:53:34<Cale>cayennext: Basically, if you have something like do x <- undefined; return (1:x) it has to evaluate the 'undefined' in order to tell that it isn't supposed to go and print something to screen there.
09:54:47<cayennext>Yes, now I see what I was trying to do, I should try another way.
09:55:47<Cale>You could use unsafeInterleaveIO to cheat though.
09:56:08<Cale>Prelude System.IO.Unsafe> do (y:ys) <- do { x <- unsafeInterleaveIO undefined; return (1:x) }; print y
09:56:08<Cale>1
09:56:18<mreh>I'm running the configure script in the ghc 6.10 binary, and I get this
09:56:19<mreh>configure: error: cannot determine current directory
09:56:31<Cale>mreh: What platform?
09:56:32<cayennext>I cannot. Professor said: no unsafe.
09:56:38<mreh>Cale: debian
09:56:47<Twey>Good professor
09:56:49<Cale>x86 or x86_64 ?
09:57:01<mreh>Cale: x86
09:57:30<mreh>it's GHC6.1.3
09:57:32<mreh>it's GHC6.10.3
09:58:00<Cale>mreh: Hmm, I recall getting that error when I accidentally tried to install the x86 package on a 64bit machine.
09:58:21<mreh>Cale: I'm definately not 64bit!
09:58:27<mreh>definitely*
09:58:39<Cale>okay :)
09:58:59<mreh>i've got one machine that has taken 3 hours to install cabal, and one that thinks it's 64 bit!!!
09:59:27<dcoutts>mreh: if it's been stuck for 3 hours then something is very wrong
09:59:34<mreh>dcoutts: its IO bound
09:59:50<dcoutts>linking programs takes at most 30 seconds over slow NFS
10:00:07<Cale>Maybe it's just caused by a similar problem. ISTR the GHC binary package coming with a funky version of pwd which is usually the first thing to fail if there's an incompatibility.
10:01:09<mreh>dcoutts: I have no memory to speak of
10:01:33<mreh>I figured it was writing and reading virtual memory the whole time
10:01:56<mreh>stupid laptop
10:02:10<Cale>mreh: try running ./utils/pwd/pwd forwardslash from the root of the package directory
10:02:16<Cale>mreh: does it work?
10:03:00<mreh>what does that do?
10:03:14<Cale>It should just print the current directory you're in
10:03:18<mreh>it reminds me of people telling you to press ALT-F4
10:03:26<Cale>(using forwardslashes)
10:03:44<Cale>pwd is a standard unix command, but for whatever reason, the ghc installer includes its own
10:04:15<Cale>and usually if there's a dependency problem, it's the first place in the install to fail
10:04:17<mreh>./utils/pwd/pwd: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory
10:04:19<Cale>aha
10:04:23<Cale>So you have no libgmp
10:04:43<mreh>what on earth is that?
10:04:55<Cale>It's the C library used to implement the Integer type in Haskell.
10:04:55<ski>(cayennext : it's arguable whether `unsafeInterleaveIO' actually is "unsafe", though ..)
10:05:20<mreh>it's completely missing from my installation of GHC?!
10:05:21<Cale>apt-get install libgmp3c2
10:05:48<Twey>It should be a dependency...
10:05:53<Twey>Oh, wait, you're compiling from source?
10:06:03<Cale>He's installing the generic binary
10:06:20<Cale>It probably should try to discover when that library is missing.
10:06:33<Twey>Yeah
10:06:41<Twey>I thought there were plans for an installer.
10:07:26<Cale>It's probably that someone overlooked that ./utils/pwd/pwd is written in Haskell and linked against libgmp and so if you run it before the test for libgmp the installer will fail without telling the user anything sensible.
10:07:40<mreh>configure: error: C compiler cannot create executables
10:07:47<Cale>Oh, nice.
10:07:55<Twey>>.<
10:08:28<mreh>I think I might try and upgrade my distribution
10:09:08<mreh>What does that even mean?!
10:09:48<Cale>I'm a bit surprised that the C compiler needs to be able to create executables to install the binary ghc...
10:10:00<Cale>It means that your install of GCC is broken though.
10:10:29<Cale>(or that autoconf's script thinks it is, anyway)
10:10:35<p_l>Cale: or that your options cause it to fail - had this with misplaced -mach
10:12:10<kynes>hi, I'm currently using catch from Control.Exception to run functions safely in my application
10:12:21<kynes>is there a way to specify a time limit on a function run / expression ?
10:12:35<Cale>kynes: System.Timeout
10:12:42<kynes>Cale, how can I use that?
10:12:49<Cale>timeout :: Int -> IO a -> IO (Maybe a)
10:12:59<Cale>I believe the parameter is in microseconds
10:13:01<mreh>my ghc wont install :''''(
10:13:09<kynes>Cale, okay thanks
10:13:18<Heffalump>does that work with let loop () = loop () in loop () ?
10:13:22<mreh>Cale: should I tinked with the configure script?
10:13:26<mreh>tinker*
10:13:33<kynes>Cale, if expression times out, what does it give as return value ?
10:13:34<Cale>Heffalump: probably if you apply evaluate to it first
10:13:41<Cale>kynes: Nothing
10:13:52<Cale>kynes: and if not, it gives Just x
10:13:56<Heffalump>most things only interrupt when an allocation happens, and that never allocates and never blackholes
10:14:01<Heffalump>or at least didn't the last time I checked
10:15:00<Cale>Prelude System.Timeout Control.Exception> timeout 1000000 (evaluate (let loop () = loop () in loop ()))
10:15:00<Cale>Nothing
10:15:28<Berengal>Prelude System.Timeout> timeout 10000 (return (loop ()))
10:15:28<Berengal>Just ^CInterrupted.
10:15:47<Cale>Of course, since return is not strict.
10:16:09<Berengal>Indeed, 's what I thought
10:17:37<Berengal>Prelude System.Timeout> timeout 10000 (loop () `seq` return ())
10:17:37<Berengal>Nothing
10:19:27<mreh>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2530#a2530 <--- This is the config.log
10:19:51<kynes>Cale, Berengal, thank you both
10:20:06<mreh>look at the failed program
10:21:48<Athas>How can I do unsigned arithmetic in Haskell? Or just shift Int32's without sign extension?
10:21:56<Bacta>@faggot Can haskell..
10:21:56<lambdabot>Unknown command, try @list
10:22:36<olsner>Athas: you have Word and Word32 etc that correspond to the Int types but are unsigned
10:22:44<Berengal>> 256 :: Word8
10:22:45<lambdabot> 0
10:22:57<olsner>> 255 :: Int8
10:22:58<lambdabot> -1
10:23:23<Athas>olsner: nifty, thanks.
10:26:09<voker57__>@hoogle (a -> a -> a) -> (a -> a)
10:26:10<lambdabot>Prelude foldl1 :: (a -> a -> a) -> [a] -> a
10:26:10<lambdabot>Prelude foldr1 :: (a -> a -> a) -> [a] -> a
10:26:10<lambdabot>Data.List foldl1 :: (a -> a -> a) -> [a] -> a
10:26:49<kynes>I run on hugs and it says: Can't find imported module "System.Timeout"
10:27:02<kynes>I'm on Ubuntu, is the default hugs package "minimal" ?
10:27:13<kynes>I can import System.Environment
10:28:06<kynes>is this an extra haskell package ?
10:28:11<kynes>I mean Timeout
10:28:49<Cale>kynes: Oh, it's something that comes with GHC
10:29:24<kynes>Cale, :( I was currently using runhugs
10:30:38<Cale>kynes: One moment while I get you a snippet of code to do a similar thing...
10:30:52<Cale>oh, heh, we can just steal the code probably
10:31:11<kynes>Cale, :) thanks man
10:31:15<Cale>er... hmm
10:31:15<mreh>editline-0.2.1.0 is missing from GHC6.10.3
10:31:45<Cale>mreh: right, it's gotten rid of the use of editline. I think the package can be obtained from hackage still if you really need it(?)
10:32:18<mreh>Cale: i'm installing the haskell platform with 6.10.3
10:32:28<mreh>i think it was distributed with .2
10:33:06<mreh>I only wanted to install the platform to get cabal, but i need cabal to install editline
10:33:10<mreh>:D
10:33:21<mreh>ACTION sighs
10:34:07<dcoutts>mreh: use the configure option to allow building with an unsuported ghc version
10:35:45<mreh>dcoutts: it appears to be undocumented, short of looking in the script, is there something you would guess at?
10:36:30<Berengal>Isn't cabal included in the ghc install?
10:36:36<mreh>no
10:36:41<mreh>the haskell platform
10:37:44<dcoutts>mreh: ./configure --help
10:38:18<Cale>kynes: ah, okay, in Hugs it can't work the same way as it does in GHC, since in GHC, what it does is to start a thread which throws an exception back to the original thread when the timeout is up, and Hugs doesn't support throwTo
10:38:20<mreh>yeah, thanks
10:38:43<kynes>Cale, oh
10:38:52<Cale>kynes: So, I can just get you some code which I wrote a long time ago. The difference is that it doesn't run the timed-out computation in the original thread.
10:39:09<Cale>http://www.haskell.org/haskellwiki/Timing_out_computations
10:39:25<Cale>The first two snippets on that page ought to work, I think...
10:40:01<kynes>Cale, okay I'm taking a look
10:40:45<Cale>Oh, d'oh, hugs has no killThread either.
10:40:52<Cale>Why are you using hugs anyway?
10:42:58<kynes>Undefined variable "threadDelay" for 1st snippet
10:43:01<Cale>Heh, apparently in Hugs, the ThreadId type is a synonym for ()
10:43:16<Cale>kynes: I didn't get that... did you remember to import Control.Concurrent?
10:43:39<Cale>But still, the killThread that it absolutely requires isn't there.
10:44:22<kynes>Cale, yes I imported that, just as in the snippet
10:44:32<stroan>"T a -> (a -> T a) -> a" I'm trying to make a monad, where bind ignores any operations after a certain situation holds true, simply passing on the previous state. But obviously, that does not match the requirement for bind in a monad. Is there any way to do this without making each function deal with that functionallity and making bind trivial
10:44:50<Cale>kynes: hugs is a somewhat impoverished environment for writing actual applications.
10:45:01<Peaker>Cale: that code is very similar to unamb's race - except it doesn't handle exceptions/etc
10:45:12<Twey>Hugs is for learning, Yhc is for playing, GHC is for working :-P
10:45:15<Peaker>(compete, that is)
10:45:48<Cale>Peaker: yeah
10:45:54<Peaker>one shouldn't write do { resourceAllocation ; ... ; resourceFreeing } in code -- should always use bracket, or a withResource thing
10:46:24<Cale>Peaker: hm?
10:46:42<Peaker>Cale: resourceFreeing should always be made to happen, even if the code in between throws or such
10:46:56<Cale>Peaker: yyyes... I don't see what you're referring to.
10:47:00<kynes>Cale, I was using hugs to evaluate simple Haskell codes without throwing every code piece to GHC and use the output
10:47:11<Cale>kynes: ghci?
10:47:11<kynes>Cale, it was a quick solution together with Python
10:47:14<Peaker>http://www.haskell.org/haskellwiki/Timing_out_computations -- compete has forkIO's and then killThreads
10:47:21<kynes>Cale, oh sorry, yes :)
10:47:33<Saizan_>stroan: your monad sounds like MaybeT (State s)
10:47:40<Peaker>and timeoutIterate has too
10:47:50<Cale>Peaker: Well, it more or less is the abstraction wrapper.
10:48:09<Cale>Peaker: You have to write the bracket-like-thingy somewhere :)
10:48:34<kynes>Cale, can I use ghci just as I use runhugs ?
10:48:40<Peaker>Cale: it could use a lower-level abstraction wrapper in it -- something like: withThread that scopes the operations afterwards and guarantees the thread is killed
10:48:47<Cale>kynes: There's runghc
10:48:58<Cale>kynes: Which works in more or less the same way :)
10:49:35<Cale>Peaker: I'm not sure it would make it any clearer, but you can try. :)
10:50:28<ski>stroan : define your own combinator which does what you want ?
10:50:37<kynes>Cale, ghci throws more parse errors than hugs.. :/
10:50:53<Cale>kynes: Can you paste the code on hpaste or something?
10:52:19<stroan>ski: Aye. That's what I have, I'm just trying to wrap it all up into a monad at the moment.
10:52:24<Cale>stroan: Could what you're describing be more or less similar to using a continuation?
10:53:10<Cale>stroan: That is, you wrap the whole thing in a callCC and when you reach the condition you mentioned, you call the continuation that's been passed in?
10:53:38<ski>stroan : maybe you could use an exception or continuation monad to abort the monadic computation when the "certain situation holds true", cutting off the rest of the bind operations ?
10:54:32<kynes>Cale, http://pastebin.com/d39d5e2f6
10:54:51<stroan>I'll look into these. I'm extremely new to all this. Writting this application to get my head around monads really.
10:54:53<kynes> parse error on input `;' for line 9
10:55:13<Cale>Yeah, you have a spurious ; at the end of the line there
10:55:15<Cale>delete it
10:55:15<kynes>which runs fine in Hugs
10:55:38<Cale>It shouldn't.
10:55:49<Saizan_>stroan: maybe you can paste your type and your combinator, and we can take a look
10:55:49<ski>stroan : you might try pasting your code (and/or explaining more what you're about)
10:55:52<kynes>Cale, I cannot delete it because it's student code :) they have built their homework around Hugs
10:56:19<kynes>Cale, is there a way to make GHCi more flexible like Hugs ?
10:56:36<Cale>That ; isn't correct Haskell syntax and I have no idea why hugs would accept it
10:56:55<stroan>will do now
10:57:57<Cale>; is a separator, not a terminator, and is only allowed inside of blocks, which occur in the 'let' portion of a let/in (but not the in), after 'where', 'do' and 'of' for a case
10:58:29<kynes>Cale, you're definitely right
10:58:30<ski>(kynes : btw "Unknown post id, it may have expired or been deleted")
10:58:49<kynes>ski, oh I'll repost
10:58:52<kynes>ski, sorry
10:59:18<stroan>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2531 I'm trying to write a parser.
10:59:24<kynes>ski, http://pastebin.com/d67416773
10:59:41<Cale>stroan: btw, you're indenting if/then/else unconventionally
10:59:59<Cale>stroan: the normal Haskell way is to always line up the 'then' with the 'else'
11:00:00<stroan>what would be standard?
11:00:04<Cale>So it goes
11:00:07<Cale>if foo
11:00:09<Cale> then bar
11:00:12<Cale> else quux
11:00:26<Cale>Or something like
11:00:27<stroan>ah, my every other language ever days coming back to haunt me ;)
11:00:32<Cale>if foo then bar
11:00:37<Cale> else quux
11:00:45<stroan>will change that now
11:01:01<Cale>It makes sense if you think about it :)
11:01:25<stroan>it does yeah
11:01:29<stroan>just habbits
11:01:29<Cale>The 'then' and 'else' are part of the 'if', so should be indented more than it, and are siblings, so should be indented the same.
11:01:56<Cale>I find it works really nicely in bash scripts too :)
11:02:12<Cale>(you can avoid semicolons :)
11:02:37<kynes>ski, have you taken a look ?
11:02:43<kynes>ski, I'll erase it after some time
11:03:45<ski>> let ; in ()
11:03:46<lambdabot> ()
11:03:51<ski>> let () = () ; in ()
11:03:53<lambdabot> ()
11:03:58<ski>> let ; () = () in ()
11:04:00<lambdabot> ()
11:04:15<ski>ACTION raises eyebrow
11:04:19<Beelsebob>> let ; a = 5 in a
11:04:21<lambdabot> 5
11:05:09<Cale>> (let a = 5 in a;)
11:05:11<lambdabot> <no location info>: parse error on input `;'
11:05:47<Cale>You can have empty declarations in a let, but the semicolon is totally out of place in an 'in'
11:05:50<Baughn>> let ; ; ; a = 5 in a
11:05:52<lambdabot> 5
11:06:04<Baughn>> let;a=5 in a
11:06:06<lambdabot> 5
11:06:17<Baughn>> let;a=5in a
11:06:18<lambdabot> 5
11:06:20<Beelsebob>looks like a good new way of obfuscating haskell
11:06:23<ski>kynes : i think the `;' in the paste there is ok, as long as you have some declaration/signature/definition after the one defining `executeCommands'
11:06:42<kynes>ski, yes there is
11:06:50<kynes>ski, so indeed the code is okay ?
11:07:06<kynes>I mean, is GHCi at fault ?
11:07:12<Cale>ski: I don't think so...
11:07:13<ski>kynes : not in isolation, but as a fragment followed by more top-level items
11:07:31<kynes>ski, yes, it's used like that in the code indeed
11:07:39<Cale>Note on line 8 the semicolon inside the 'in' which is followed by the 'else'
11:07:44<Cale>That is not valid.
11:07:52<Baughn>> let;a=5in;a
11:07:54<lambdabot> <no location info>: parse error on input `;'
11:07:55<ski>oh .. i missed that one
11:08:11<kynes>ski, http://pastebin.com/d2943c94f updated
11:08:47<kynes>Cale, so there is a bug at Hugs ?
11:09:21<kynes>I noticed that GHCi is also stricter about indentation
11:09:22<ski>(that `in' was indented too much, so i was thinking it was another equation inside that `let' ..)
11:09:22<dibblego>@type \f -> zipWith ($) (f : repeat id)
11:09:24<lambdabot>forall b. (b -> b) -> [b] -> [b]
11:09:33<dibblego>> let k = \f -> zipWith ($) (f : repeat id) in k toUpper "abc"
11:09:35<lambdabot> "Abc"
11:09:38<dibblego>zing!
11:09:49<ski>kynes : generally, one does not indent like
11:09:53<ski> let foo = ...
11:09:58<ski> bar x = ...
11:10:04<ski> in ..foo..bar..
11:10:14<kynes>ski, I didn't mean the indentation is correct in the pasted code
11:10:21<kynes>ski, I meant another code
11:10:33<kynes>ski, but I fixed that one so cannot paste.. hmm
11:10:40<Serica> i wonder why whatever i specify in --host= when building ghc it always defaults to i386-unknown-linux ?
11:10:51<Cale>kynes: Yes, it is a bug for hugs to accept that
11:11:02<ski>(stroan : btw, s/(elem s list)/elem s list/)
11:11:44<stroan>changed. Any idea how to make the monad do what combine does?
11:11:50<kynes>do I have a Timeout solution I can use in Hugs ?
11:12:05<kynes>ski, Cale, Baughn I'm erasing the post
11:12:09<kynes>is it okay ?
11:12:29<ski>(kynes : i already have it in browser, so sure :)
11:12:34<Cale>sure
11:12:35<Serica>umm i decided to ask in #ghc and close the question here
11:12:36<kynes>ski, :) okay
11:13:15<kynes>thank you very much for your help
11:13:42<ski>stroan : it appears like `extract' tries to separate a longest prefix of characters all occuring in a given list
11:14:39<ski>stroan : could you explain more what you're trying to do ?
11:14:59<ski>how and why are you going to use `extract' and `combine' ?
11:15:46<stroan>aye. there is also an extractWhile function that extracts till a non match. So say I want to extract an identifier which matches the pattern of a123df. The first leter must be a member of ['a'..'z'] and the rest of the letters must be of (['a'..'z'] ++ ['0'..'9'])
11:16:45<stroan>so I call extract with the first pattern. then I call extractwhile with the second pattern. but I want such combinations to terminate when the larger pattern can no longer be matched against
11:18:19<kynes>Cale, http://markmail.org/message/earajbrh2muzppn2#query:haskell%20base%20timeout+page:1+mid:mgpwb2rnxgzjuago+state:results
11:18:21<ski>so `Done' means something like "cannot parse further" while `Cont' means something like "partial parse succeeded, can parse further" ?
11:18:51<stroan>yup
11:18:59<Cale>kynes: yes, this is the code which uses throwTo
11:19:05<Cale>kynes: Which I was trying earlier.
11:19:26<Cale>mm... more or less, anyway
11:19:43<Cale>http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/System-Timeout.html#timeout
11:19:47<ski>(stroan : so why is `Done' not called something like `NoParse' or `ParseError' or `Bad', then ?)
11:20:00<stroan>because it's not nesecarilly a bad thing
11:20:55<stroan>like when matching an arbitrarilly large thing. I just want to match till the pattern fails. so if I have "a+b" it will match the a, and give me a done
11:21:00<ski>if i pass the string "1abc45" for parsing with your identifier parser, wouldn't that return a `Done' result ?
11:21:22<kynes>Cale, ERROR "test.hs" - Unknown entity "throwDynTo" imported from module "Control.Exception"
11:21:29<kynes>Cale, as you said
11:21:37<stroan>it would pass a done, after having extracted nothing
11:21:46<Cale>Right, and that's throwTo in the current library, but neither exists in hugs
11:22:03<Cale>kynes: Hugs doesn't even have a concept of a ThreadId, so it's impossible.
11:22:14<ski>stroan : right .. how is that not a parse error (wrt your identifier parser) ?
11:22:42<Cale>(you can start threads, but there are no operations on them -- you can only use MVars to communicate with them, and they are responsible for stopping themselves)
11:22:57<ski>stroan : e.g. do you expect to be able to extract some partial information for a parse, even if not the whole parse succeeded ?
11:23:49<stroan>Because I'm building this of an LL(1) grammar, so I was going to ask it to check several possible patterns at once and only one of them may match, and return a result and whichever one does is the correct one.
11:24:11<stroan>if multiple patterns match then it's also an error
11:24:23<stroan>but that was going to be checked with other logic
11:25:20<ski>mhm
11:26:10<ski>i'm not convinced your `ParserData' is defined correctly
11:26:32<stroan>It's probably not :/ Though this is as close to working as I've gotten the program in a few days :P
11:27:07<stroan>A third, error, state might be required
11:27:27<ski>btw, you're aware there are already parsing combinator libraries which you might use or at least be inspired by ?
11:27:53<stroan>Aye. This is mostly a get to know haskell / get my head around monads project
11:27:59<ski>i'm not sure why the type signature of `extract' should mention all those `[Char]'
11:29:12<ski>it seems some occurances of `[Char]' there stands for the underlying list of tokens to be parsed, while other occurances of it stands for an identifier being currently implemented as a list of characters
11:29:32<ski>what if you had an abstract type of identifiers, `Ident'
11:29:55<ski>hm
11:30:42<stroan>My current plan is just to tokenise / parse in one step.
11:30:52<jkramer>Hello
11:31:16<ski>(i realize i misread before, `extract' only does one step of identifier parsing)
11:31:26<stroan>aye.
11:31:48<stroan>I also have extractWhile, that extracts until done.
11:31:59<ski>so, what would the type be of an operation for parsing a whole identifier, in your parsing combinator framework ?
11:32:15<ski>(i'm just asking for a type signature, not an implementation)
11:32:16<jkramer>I'm trying to install encoding with cabal, but it seems to hang at 43/47 (Data.Encoding.JISX0208). Does anyone know that problem?
11:32:33<jkramer>ghc eats 99% of CPU
11:32:52<jkramer>Or is that module just very hard to compile?
11:33:54<stroan>extractIdentifier :: String -> ParserData
11:34:01<stroan>and that raises some issues :P
11:34:04<Saizan_>jkramer: the latter
11:34:10<ski>`ParserData' requires a type argument
11:34:22<stroan>ParserData (String,String)
11:34:50<jkramer>Saizan_: But +10 minutes eating ~100% CPU on 2x2Ghz?
11:34:51<ski>and what if an identifier had type `Ident' instead of `String' ?
11:35:15<ski>(you may assume `data Ident = MkI String' if that makes you feel better)
11:35:46<jkramer>The other encodings compiled in < 1s
11:36:08<maltem>jkramer, I tried and I'm seeing the same thing. Let's see how long it takes here :)
11:36:09<stroan>so the signature would be String -> ParserData(Ident, String)?
11:36:37<ski>ok
11:37:07<jkramer>maltem: May the faster machine finish first :)
11:37:26<Saizan_>jkramer: well, two processors don't count when you're using only one :)
11:37:32<ski>so the first occurance of `String' is the input from the point to parse an identifier, and the second occurance of `String' is the input from the point after the identifier being parsed, yes ?
11:37:33<jkramer>That's true
11:37:41<stroan>yes
11:37:51<jkramer>It's not even two processors but just two cores :(
11:38:22<jkramer>Has anyone tried turbinator yet?
11:38:23<ski>your `ParserData m' is basically the same as `Either m m' (just other names for the two constructors)
11:38:37<ski>so that makes your type being roughly
11:38:47<ski> String -> Either (Ident, String) (Ident, String)
11:39:49<ski>iiuc, the first case (the `Cont' case) corresponds to an identifier having been parsed, and also there's some part left of the input string to parse on from
11:39:58<jkramer>He, it just finished :)
11:40:17<jkramer>http://en.wikipedia.org/wiki/JIS_X_0208 - sounds like a lot of characters
11:40:18<PeakerWork>Nicer to have (Bool, Ident, String) ?
11:40:27<stroan>Cont if the last parse was successful. Done if the last match failed
11:40:47<ski>what is the "last parse/match" ?
11:40:52<ski>say the input string is
11:41:04<ski> "a123df+1"
11:41:30<ski>say we want to parse an identifier, and then maybe continue parsing some else with the rest of the input
11:42:14<stroan>the last match it would perform inside the identifier parsing section would be the "+", which it would leave in place and return done
11:42:39<stroan>so Done ("a123df","+1")
11:42:56<ski>so is the first string there a valid identifier ?
11:43:03<stroan>yes
11:43:12<ski>what if the string was
11:43:20<ski> "(1+2)"
11:43:30<stroan>Done ("", "(1+2)")
11:43:31<ski>what should the identifier parser return ?
11:43:43<ski>is the empty string a valid identifier ?
11:43:53<stroan>Nope
11:44:06<ski>then the types doesn't match
11:44:15<stroan>You're right
11:44:22<stroan>I need an error type
11:44:39<ski>or at least a "NoParse" alternative
11:44:50<ski>(maybe that amounts to the same thing :)
11:44:56<stroan>:)
11:45:16<ski>maybe it would be easier to think here of a parser of boolean values
11:45:27<ski>the parser would parse strings as
11:45:30<ski> "True"
11:45:32<ski>as well as
11:45:34<ski> "False"
11:45:54<ski>also allowing there to be any amount of extra tokens/characters after those characters
11:45:59<ski>so
11:46:17<ski> parseBoolean :: String -> ParserData (Bool,String)
11:46:19<ski>maybe ?
11:47:00<stroan>I already have a Token datatype, which I was planning on using a step later. But it's pretty clear you're completely right :)
11:47:00<ski>(the point being that the type `Bool' doesn't contain any such dummy values as the empty string above, so one can't make a mistake in that way at least)
11:47:53<ski>also, i'll give a suggestion, which i'm not completely sure if it applies with the kind of parsing you want to do, but anyway
11:48:24<ski>if you feel you're having this `String -> ParserData (Foo,String)' pattern over and over, consider defining
11:48:36<maltem>jkramer, true, that's a really tough package to compile :o (now at 45/47)
11:48:48<ski> newtype Parser a = MkP (String -> ParserData (a,String)) -- or something similar
11:48:53<ski>so that you can then have
11:49:01<ski> parseBoolean :: Parser Bool
11:49:09<ski> parseIdentifier :: Parser Ident
11:49:58<ski>(also, it might be that even though `ParserData' maybe can't be made into a monad, mayhaps `Parser' can be)
11:50:46<stroan>hmmm, thanks for all this. It is seriously a huge help.
11:51:10<stroan>Haskell really makes it very hard to be unclear in your thinking.
11:51:38<ski>anyway, good luck
11:51:42<stroan>thanks :)
11:51:42<ski>ACTION needs to leave
11:58:34<Absolute0>Is it possible to make Map.lookup x map into a higher order function where x is the only argument, without making a helper function with reversed arguments? (let helper x = Map.lookup x setup) ?
11:59:08<Cale>flip
11:59:12<Cale>:t flip
11:59:13<lambdabot>forall a b c. (a -> b -> c) -> b -> a -> c
11:59:26<EvilTerran>(`Map.lookup` map)
11:59:28<Cale>Or just use a lambda :)
11:59:48<Absolute0>Cale: yeah i was using a lambda but it was to long for my example
11:59:48<EvilTerran>or (flip Map.lookup map), or (\x -> Map.lookup x map)...
12:00:49<Absolute0>does flip have to take 3 parameters?
12:01:03<Absolute0>@let foo x y = x
12:01:04<lambdabot> Defined.
12:01:10<Absolute0>> flip foo
12:01:11<lambdabot> Overlapping instances for GHC.Show.Show (b -> a -> a)
12:01:11<lambdabot> arising from a use...
12:01:17<Absolute0>:(
12:01:39<Jedai>Absolute0: What do you mean ? flip like all functions in Haskell only takes one parameter
12:01:45<maltem>Absolute0, that as because functions cannot be printed
12:01:49<maltem>*was
12:03:10<Absolute0>:t flip foo
12:03:11<lambdabot>forall a b. b -> a -> a
12:03:32<Absolute0>what is forall?
12:03:36<Absolute0>:t forall
12:03:37<lambdabot>Not in scope: `forall'
12:03:43<Absolute0>not a function..
12:03:58<Absolute0>oh its polymorphic?
12:04:03<Jedai>Absolute0: forall is for all, it just means that a and b are type variables
12:04:11<Absolute0>gotcha
12:04:16<Jedai>Absolute0: like in mathematics
12:04:35<Absolute0>haskell has got to be the closest language to mathematics :)
12:04:55<Jedai>Absolute0: actually you can write forall yourself in your type annotation if you enable some extensions
12:05:25<Cale>(It's because those extensions are enabled that the bot prints it)
12:05:34<Absolute0>I was thinking, why can't you achieve what monads achieve by simply writing a bunch of where declarations?
12:05:37<Cale>Specifically, RankNTypes
12:05:39<Jedai>Absolute0: it's usually implicit, but for some advanced type manipulation, making forall explicit is necessary
12:06:04<Absolute0>each new declaration caliing a previous one
12:06:05<Cale>Absolute0: The point of monads is to have general operations which work across a wide class of libraries that have been recognised.
12:06:09<Absolute0>hence having states
12:06:25<Cale>Monads in general have essentially nothing to do with state.
12:06:29<Jedai>Absolute0: I'm not sure where you're coming from ? Monads are nothing magic, they're just an useful abstraction
12:06:58<Twey>Absolute0: The answer is ‘you can’
12:06:58<Absolute0>according to most tutorials they seem to simplify state manipulation
12:07:02<Jedai>Absolute0: If you're speaking about the State monad, you sure can do it by hand
12:07:03<Twey>Monads don't do anything magic
12:07:06<Cale>(To think that they do is confusing the abstraction with the application :)
12:07:07<Twey>They just make it prettier
12:07:28<Absolute0>Is there any nice simple to read monad tutorial out there?
12:07:29<Cale>Absolute0: Beware, there are many poor monad tutorials.
12:07:40<Absolute0>the majority of them seem to get too academic
12:07:53<Absolute0>or poor as Cale said :)
12:08:03<Jedai>Absolute0: but if you try to do it on a big example you'll soon understand why we use monads
12:08:05<Twey>And therefore I recommend Cale's excellent Monads as Computation: http://haskell.org/haskellwiki/Monads_as_computation
12:08:27<Cale>Yeah, actually in that one I try to explain what the point is of talking about monads at all.
12:08:44<Jedai>Absolute0: and as other said, State monads are only a small part of what you can do with monads
12:09:11<Cale>If all you want is any one monad, there's no point in talking about monads. For example, if all you want is IO, there's no need to recognise that it's a monad.
12:09:27<foo-nix>twanvl, ping.
12:10:08<Cale>It's only when you get reuse out of the general polymorphic operations in Control.Monad and elsewhere that the fact that anything is a monad becomes useful knowledge.
12:10:17<Cale>Like, for example...
12:10:19<Cale>:t mapM
12:10:21<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m [b]
12:10:24<Cale>:t sequence
12:10:26<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m [a]
12:10:29<Cale>:t foldM
12:10:31<lambdabot>forall a b (m :: * -> *). (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
12:10:36<Cale>etc, etc.
12:11:19<Absolute0>isn't forall superflous in the above lines?
12:11:21<Cale>Otherwise, you're just talking about specific combinator libraries, and while even that is new for most people, it's not what monads are about.
12:11:27<Absolute0>no type means all types...
12:11:27<Jedai>Absolute0: it is
12:11:28<Cale>yes
12:11:30<Absolute0>ehh
12:11:35<Cale>It's just being very explicit.
12:11:43<Jedai>Absolute0: but it doesn't hurt anything
12:11:47<PeakerWork>didn't know about foldM
12:11:54<Absolute0>Jedai: might confuse some...
12:11:55<Absolute0>:)
12:11:58<Absolute0>like i was
12:12:11<Cale>In Haskell, if you leave type variables unquantified, they're automatically forall'd at the beginning of the type signature
12:12:22<Cale>But if you place the foralls elsewhere, the meaning changes.
12:12:39<Jedai>Absolute0: Actually the explicit notation is rather clearer in my eyes
12:12:59<Cale>For example, foo :: (forall a. a -> a) -> ... means that foo takes a function *required to be polymorphic* as a parameter
12:13:07<Absolute0>superflous is superflous making it unecessary
12:13:12<Jedai>Absolute0: what might be confusing is the coexistence of an implicit and an explicit notation
12:13:42<PeakerWork>Absolute0: Monads abstract computations that can be sequenced to use previous results. They can be used to abstract state, continuations, exceptions, side effects, and many other interesting things
12:14:00<Jedai>Absolute0: it's not like it will tire the bot...
12:14:00<Cale>Absolute0: But yeah, if you like, you can ignore all that part up to the '.'
12:14:26<Cale>It's just making explicit that m is a type constructor and that a, b are types
12:14:33<Cale>(any types, not particular ones)
12:14:40<Absolute0>PeakerWork: regarding the "sequenced" part i mentioned that simple where clauses could do the job.
12:14:41<Jedai>Absolute0: and being consistent (putting forall everywhere rather than only when it needs to be explicit) is not bad either
12:15:04<PeakerWork>Absolute0: what do you mean?
12:15:20<Absolute0>ie: where x = 5 y = x + 2 z = y + 3
12:15:42<PeakerWork>Absolute0: That's not "sequencing computations" -- that's just creating a graph for evaluation
12:15:54<Jedai>Absolute0: there is no sequencing in your example
12:16:12<Cale>That is more or less the identity monad without recognising that it's the identity monad.
12:16:15<PeakerWork>Absolute0: "sequencing computation" means "apply whatever sequencing operation the specific Monad implements" in order get exceptions, continuations, failure handling, state, etc
12:16:42<Absolute0>i need to do some RTFM'ing
12:16:59<Jedai>Absolute0: Don't listen to Peaker though, "explicit sequencing" is only one aspect of the capacity of monads
12:16:59<PeakerWork>Absolute0: For example, an "exception monad" might implement the sequencing operation to ignore any computation its requested to sequence, if the previous computation has resulted in error
12:17:13<Cale>Though, of course, let is a bit different in its typing rules than do-notation (which translates in terms of lambdas) would be.
12:17:32<Cale>But that's not a big difference.
12:17:49<PeakerWork>Jedai: What other aspects do you have in mind?
12:17:58<Jedai>PeakerWork: I don't much like "the sequencing operation" to design bind (>>=), it's not the only thing that it can do
12:18:35<PeakerWork>Jedai: I think its a legitimate POV on monads, as the "sequencing order" is always allowed to have semantic significance
12:18:41<Jedai>PeakerWork: I don't see how the list monad enter your description exactly, for me it's not a matter of sequencing
12:18:56<Jedai>PeakerWork: and the monads that can commute ?
12:19:01<PeakerWork>Jedai: even the list monad sequences
12:19:07<Jedai>PeakerWork: No
12:19:13<Cale>Jedai: It's a certain kind of sequencing. The order in which selections are made.
12:19:19<PeakerWork>> liftM2 (,) [1,2] [3,4] /= liftM2 (,) [3,4] [1,2]
12:19:20<lambdabot> True
12:19:22<EvilTerran>Jedai, considering it to be the backtracking computation monad, >>= starts to look like sequencing
12:19:29<Cale>It just happens to have nothing to do with the evaluation order.
12:19:38<Cale>(well, essentially nothing)
12:19:41<Jedai>PeakerWork: the list "sequence" in your example, not the monad
12:19:56<PeakerWork>Jedai: some monads don't sequence, but since monads in general are allowed to sequence -- its hard not to see the sequencing as part of the abstraction of monads
12:20:01<Cale>> do x <- [1..3]; y <- [1..x]; return (x,y)
12:20:03<lambdabot> [(1,1),(2,1),(2,2),(3,1),(3,2),(3,3)]
12:20:38<Cale>Pick a number x from 1 up to 3, then pick a number y from 1 up to x, and return the pair (x,y)
12:20:59<Jedai>PeakerWork: That's part of the capacity of monads, I agree, I just don't think it's a very good idea to use "sequence" and "sequencing operation" as a basic vocabulary to describe monads in general
12:21:00<Cale>So it's a kind of sequence of operations, though the evaluation order is drastically different.
12:21:18<Absolute0>Is it common to have type signatures in where clauses?
12:21:28<ivanm>not really
12:21:34<Cale>I think sequencing is to some extent at the heart of what monads abstract over, but you have to be cautious that you really know what is meant by it.
12:21:56<Absolute0>silly monads
12:22:01<Jedai>Absolute0: it is sometimes necessary, especially if the monomorphism restriction is activated, but it's relatively uncommon
12:22:02<Absolute0>confusing everyone
12:22:10<Cale>Using the term around those who are uninitiated is perhaps dangerous. :)
12:22:14<EvilTerran>Cale, as in, sequencing the flow of information, not the evaluation order
12:22:15<EvilTerran>?
12:22:23<Gracenotes>Absolute0: in some cases you might even need scoped type variables >_>
12:22:27<Cale>EvilTerran: something like that, I suppose.
12:22:30<PeakerWork>Jedai: Monads do Functor(fmapping) + Applicative(sequencing + value combining) + Monad(can use results of previous sequence to choose how to continue sequencing)
12:22:30<sohum>this is very offtopic, but where would I go to ask a CS question?
12:22:43<Absolute0>the author of the haskell book at yale says that monads should've been called "warm and fuzzy things
12:22:45<Cale>EvilTerran: Sequencing in terms of what <=< does
12:22:54<EvilTerran>although the Etats monad has information flowing in both directions <.< >.>
12:23:02<Jedai>Cale: That's what I was saying, not that "sequencing" has nothing to do with monads, just that a little caution around the term when teaching a beginner may be good
12:23:17<Gracenotes>sohum: can't do much if we don't know what the question is...
12:23:17<Cale>That is, a monad has about as much to do with sequencing as the composition of any category does.
12:23:43<Cale>But associativity is the heart of what we expect from sequences
12:23:59<Cale>and composition in categories is associative
12:24:01<sohum>Gracenotes: well, I don't want to ask #haskell, I just wondered if yall knew somewhere where a CS question would be ontopic
12:24:03<Jedai>sohum: you can try here, eventually go to haskell-in-depth
12:24:15<Gracenotes>sohum: CS is extremely general. what.
12:24:22<PeakerWork>Jedai: I think a beginner should learn Functor, then Applicative, then Monad -- and Applicative should already introduce sequencing
12:24:22<sohum>fair enough.
12:24:32<Gracenotes>unfortunately there's not a CS channel on freenode. at least not a busy one.
12:24:44<Cale>Applicative doesn't really have sequencing in the sense that Monad does.
12:25:01<Gracenotes>:/ but... for jeeve's sake, what's the question?
12:25:11<sohum>if there's a graph with exactly 2x nodes, and each node is connected to exactly x other nodes, does there have to exist a clique of size x?
12:25:22<Absolute0>Applicative?
12:25:36<Jedai>Absolute0: another typeclass
12:25:42<Absolute0>does lambdabot provide links?
12:25:43<Cale>Absolute0: Applicative is another abstraction similar to Monad, but weaker in its operations and more general.
12:25:44<EvilTerran>sohum, you could also try #math for a problem like that
12:25:52<sohum>EvilTerran: I could, thankee.
12:25:53<Jedai>Absolute0: yes, I think
12:25:59<Absolute0>whats the syntax?
12:26:00<Cale>(Every monad is an applicative functor, but not every applicative functor is a monad)
12:26:07<Cale>See Control.Applicative
12:26:10<Jedai>> (+3) <$> [1..5]
12:26:10<Gracenotes>sohum: math is a good channel :) sorry for snarky
12:26:11<lambdabot> [4,5,6,7,8]
12:26:22<Cale>that's just fmap...
12:26:42<Cale>> [id, (+2), (*2), (^2), (2^)] <*> [5,6,7]
12:26:44<lambdabot> [5,6,7,7,8,9,10,12,14,25,36,49,32,64,128]
12:26:52<Gracenotes>better to ask than to ask to ask, they say
12:26:53<Absolute0>:t <+>
12:26:55<lambdabot>parse error on input `<+>'
12:27:01<Absolute0>:t (<+>)
12:27:02<lambdabot> Ambiguous occurrence `<+>'
12:27:02<lambdabot> It could refer to either `Control.Arrow.<+>', imported from Control.Arrow at /home/cale/.lambdabot/State/L.hs:4:0-19
12:27:02<lambdabot> or `Text.PrettyPrint.HughesPJ.<+>', imported from Text.PrettyPrint.HughesPJ at /home/cale/.lambdabot/State/L.hs:54:0-46
12:27:03<Cale>:t pure
12:27:05<lambdabot>forall a (f :: * -> *). (Applicative f) => a -> f a
12:27:08<EvilTerran>> [f,g,h] <*> [x,y,z] :: [Expr]
12:27:08<Cale>:t (<*>)
12:27:09<Jedai>Absolute0: "f <$> x <*> y" is a simple example, you can have more sophisticated ones
12:27:09<lambdabot> Ambiguous occurrence `x'
12:27:10<lambdabot> It could refer to either `L.x', defined at <local...
12:27:10<sohum>Gracenotes: np ;}
12:27:11<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
12:27:23<Cale>Absolute0: pure and <*> are the basic functions for Applicative
12:27:38<Absolute0>:t Control.Arrow.<+>
12:27:39<lambdabot>parse error on input `Control.Arrow.<+>'
12:27:44<Absolute0>:t Control.Arrow.(<+>)
12:27:45<lambdabot>Couldn't find qualified module.
12:27:48<Absolute0>beh
12:27:55<Cale>Absolute0: everything else is built from those two
12:27:55<Gracenotes>sohum: you're sure it's not P? :P
12:28:04<Cale><+> is unrelated
12:28:13<Jedai>Absolute0: <+> isn't an operator of Applicative
12:28:16<NEEDMOAR>sohum: btw, an "square" (four points joint by four lines in the standard way) wouldn't be a counterexample?
12:28:16<Absolute0>xmonad uses <+> in the config
12:28:22<Absolute0>i am trying to figure out what it does
12:28:37<Jedai>Absolute0: search in the xmonad doc (look in the index)
12:28:39<ivanm>Absolute0: it's an xmonad operator
12:28:40<sohum>Gracenotes: :P
12:28:41<Cale>I think you'd have to look in the xmonad code for that.
12:28:46<ivanm>it joins together two hooks, IIRC
12:29:13<sohum>NEEDMOAR: no, because the "square" has four cliques of size 2
12:29:31<NEEDMOAR>sohum: nevermind, stupid me.
12:29:32<Absolute0>it looks funky, very intriguing :)
12:29:33<Cale>http://hackage.haskell.org/packages/archive/xmonad/0.8.1/doc/html/XMonad-ManageHook.html#v%3A<%2B>
12:29:35<Cale>Absolute0: ^^
12:30:11<Cale>Heh, apparently its implementation is mappend :P
12:30:31<Absolute0>xmonad rocks by the way
12:30:38<Cale>aha, type ManageHook = Query (Endo WindowSet)
12:30:40<Absolute0>hands down the best WM
12:30:48<walter_>>pates
12:30:51<walter_>>paste
12:30:52<sohum>(incidentally, the reason my mind is currently blown is because I read through the Monad chapters in RWH ;})
12:30:52<Cale>and Query derives its Monoid instance
12:31:02<Cale>So it just composes functions on WindowSets
12:31:19<Cale>er, oops
12:31:23<Cale>newtype Query a = Query (ReaderT Window X a)
12:31:27<Cale>instance Monoid a => Monoid (Query a) where
12:31:27<Cale> mempty = return mempty
12:31:27<Cale> mappend = liftM2 mappend
12:31:36<Cale>so, more or less :)
12:32:30<Jedai>Absolute0: So <+> is related to Monoid, though only the Hook monoid
12:32:31<Cale>So what it does when you <+> two ManageHooks together is it constructs the Query computation which when run will run each, and then compose their results
12:32:48<Cale>(which are required to be WindowSet -> WindowSet functions
12:32:50<Cale>)
12:32:57<Cale>(wrapped in Endo)
12:32:57<Absolute0>thanks :)
12:33:04<Jedai>Absolute0: I suppose you already know the Monoid typeclass ? If not it's well worth knowing despite its apparent simplicity
12:33:15<Absolute0>I'll pretend to. :)
12:33:26<Absolute0>for the time being.
12:33:28<Cale>Absolute0: It's rather simple to explain...
12:33:56<Absolute0>monoid related to monad?
12:34:10<Cale>distantly
12:34:15<Berengal>@quote endofunctors
12:34:15<lambdabot>wadler says: A monad is a monoid in the category of endofunctors, what's the problem?
12:34:18<Jedai>Absolute0: monoid are just set with a binary operation that is associative and has a neutral element
12:34:39<Absolute0>monoid monad functor, haskell sounds like some sort of new funky religion :)
12:34:48<Cale>If you have a type, and a special operation, say (*) you'd like to identify on that type, which happens to be associative, that is x * (y * z) = (x * y) * z for all x,y,z, and has an identity, say 1 such that 1 * x = x * 1 = x, for all x, then you can make it an instance of the Monoid class
12:34:48<Jedai>Absolute0: for instance (Integer, (+), 0) is a monoid
12:34:56<Cale>With mappend = (*) and mempty = 1
12:35:00<Absolute0>Jedai: a field...
12:35:04<Jedai>Absolute0: monoid are really basics in maths
12:35:08<Absolute0>in mathematical terms
12:35:17<Jedai>Absolute0: a field is much more complicated,
12:35:56<Absolute0>are there isomorphisms in haskell? :-D
12:35:59<Cale>A field is a group under addition, and a monoid under multiplication satisfying a distributive law, and having inverses for nonzero elements under multiplication
12:36:03<Absolute0>or ways to verify isomorphism?
12:36:09<Absolute0>i guess using map function..
12:36:11<Cale>A group is a monoid with inverses for all elements.
12:36:24<Cale>(Monoid is a mathematical term)
12:36:41<Absolute0>where can a monoid be useful?
12:36:41<walter_>I got a "parse error" , but dont know why, thanks in advance. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5443#a5443
12:36:57<Cale>Absolute0: Monoids are almost everywhere.
12:37:04<Absolute0>ah :)
12:37:12<Jedai>Absolute0: http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html
12:37:50<Berengal>> sortBy (comparing length `mappend` compare) (words "asd fdsasdf fdsaf fds fdssdf fds")
12:37:51<lambdabot> ["asd","fds","fds","fdsaf","fdssdf","fdsasdf"]
12:38:10<Cale>http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx
12:38:14<Cale>Absolute0: ^^
12:38:29<hackagebot>bindings-sqlite3 0.0.2
12:38:33<Cale>there's a post I wrote about one example of what recognising that monoids are everywhere gets you :)
12:38:54<Cale>and, it explains what Berengal just showed
12:39:03<olsner>cgibbard = Cale?
12:39:05<Cale>yes
12:39:06<Jedai>walter_: I think the error may well be in the code before the line 28...
12:39:22<Absolute0>I am writing a simple chess game, don't seem to require any of this fancy stuff to get by...
12:39:26<Jedai>walter_: maybe a ")" or a "]" is lacking
12:39:28<Absolute0>not sure why
12:39:46<Absolute0>http://github.com/ramin32/chessengine/tree/master
12:39:55<apfelmus>Absolute0: Ah, but the stuff is not fancy at all.
12:40:15<Cale>There are a lot of monoids associated with chess.
12:40:15<Absolute0>simple data definitions and functions do everything :)
12:40:25<apfelmus>Rather, in its simplicity lies its power.
12:40:39<walter_>Jedai, dont understand where to add ] more in makeNewsPair :: [Tag] -> [(String, String)]
12:40:56<Jedai>Absolute0: as apfelmus says, this stuff is not "fancy", in fact it's rather recognizing simple structure gives you more leverage to manipulate them
12:41:30<Absolute0>monads are not that simple..
12:41:37<Absolute0>other things could be
12:41:45<Jedai>Absolute0: and I'm sure you don't _need_ them to do pretty impressive things in Haskell, but when you do know them you'll get more elegant, flexible, shorter... code
12:41:48<Absolute0>ehh i am just ill informed
12:41:53<Cale>The basic part of what a monad is, is actually extremely simple.
12:42:07<Jedai>walter_: I said before this line
12:42:28<Cale>The laws might seem confusing, but there is actually a way to present them which makes them seem really simple indeed.
12:42:47<Absolute0>Maybe in my second week of haskell coding i'll get it. :-P
12:43:00<Cale>It's possible to define a monad as a type constructor M with an operation:
12:43:19<Cale>(<=<) :: (b -> M c) -> (a -> M b) -> (a -> M c)
12:43:22<Cale>and
12:43:24<Jedai>walter_: this line appears perfectly correct, but the parser says there is an indentation error, it's probably because the code that precede this line is incorrectly indented or lacks a closing character
12:43:27<Cale>return :: a -> M a
12:43:51<Absolute0>(x) is a functor, right?
12:43:52<Cale>Before I go on, take a moment to compare those types with
12:44:00<Cale>(.) :: (b -> c) -> (a -> b) -> (a -> c)
12:44:03<Cale>and
12:44:07<Cale>id :: a -> a
12:44:17<Jedai>Absolute0: what's (x) ? do you means [] ?
12:44:22<Cale>So we've basically just stuck some M's in :)
12:44:22<Absolute0>return is just taking a simple value and makes it into a Maybe
12:44:26<Cale>yeah
12:44:38<Absolute0>Jedai: (x -> y ->z) -> some fancy crap
12:44:57<Cale>Now the laws are really easy to state in this form:
12:45:00<EvilTerran>Cale, can you define >>= in terms of >=> and return? do you need join too?
12:45:09<Cale>EvilTerran: yes you can
12:45:15<Cale>return <=< f = f
12:45:19<Cale>f <=< return = f
12:45:33<Cale>(f <=< g) <=< h = f <=< (g <=< h)
12:45:42<Cale>those are the three monad laws
12:46:02<Jedai>Cale: like the composition with return =~= id :)
12:46:04<Absolute0>Cale: so <=< is just some transitive sort of function mapping then
12:46:31<Cale>Absolute0: 'transitive', I'm not sure is the word
12:46:35<Cale>But associative
12:46:41<Cale>and having identity return
12:46:50<Cale>Note that
12:46:54<Cale>id . f = f
12:46:58<Cale>f . id = f
12:46:59<Cale>and that
12:47:03<Absolute0>Cale: can you give an example of <=< in use?
12:47:06<Jedai>Absolute0: (<=<) is an operator that "compose" functions of the form (a -> M b)
12:47:06<Cale>(f . g) . h = f . (g . h)
12:47:47<Cale>and so (.) and id define what's called the identity monad, though we can't make that directly an instance of Monad in Haskell, since we need a type constructor
12:48:01<Cale>(so you have to do some extra wrapping then)
12:48:06<walter_>Jedai, excellent, you are right! thank you
12:48:09<EvilTerran>?type \f m -> (f <=< const m) () -- Cale, would this be =<< ?
12:48:10<lambdabot>forall b (m :: * -> *) c. (Monad m) => (b -> m c) -> m b -> m c
12:48:10<ivanm>well, the new darcs wiki doesn't seem to like searching... >_>
12:48:15<Cale>EvilTerran: yeah
12:48:37<Absolute0>Cale: let me just read your article
12:48:40<Absolute0>thanks anyways
12:48:57<EvilTerran>ACTION feels uncomfortable about the extraneous () in that, but ok...
12:48:57<Cale>Absolute0: My article gives a more down-to-earth look at the monad laws
12:49:12<Cale>Absolute0: Which deals with how they might be desirable in actual programming.
12:49:39<Absolute0>there's some paper i recently read
12:49:43<Absolute0>by some walders guy?
12:49:47<Cale>Wadler
12:49:47<Absolute0>not bad..
12:49:51<Absolute0>yeah that guy
12:50:02<Heffalump>Cale: btw, I found some situations where blanket use of . . . $ instead of $ $ $ $ is unnatural: if you're doing the same/similar operation on a bunch of things, some of which are simple values and some of which are applications themselves, it feels quite weird for the $ to keep moving around.
12:50:13<Absolute0>I am thinking of doing my phd in functional programming.
12:50:17<Absolute0>i hope i get it in time..
12:50:20<Absolute0>:)
12:50:38<Absolute0>are there any undone research that can be done?
12:50:39<Cale>Heffalump: hm?
12:50:48<Cale>Absolute0: I'm sure there is.
12:50:50<Beelsebob>Absolute0: there's *many* bits of FP research to do
12:51:01<EvilTerran>Absolute0, it's a huge field, there's lots of unexplored edges
12:51:06<Absolute0>i like programming languages in general
12:51:12<Absolute0>but haskell is just cool
12:52:19<Cale>Heffalump: I'm not sure I understand what you mean there...
12:52:20<Absolute0>scala and python hype about having functional functions, but haskell had it from the start..
12:52:20<Absolute0>:)
12:52:55<Twey>‘Functional functions’?
12:53:01<Absolute0>map,
12:53:08<Absolute0>all any..
12:53:11<Twey>If you mean first-class functions, they've been around since Lisp
12:53:13<ivanm>higher-order functions?
12:53:15<Heffalump>Cale: I can't find my example now
12:53:25<Twey>Which has been around since the '50s
12:53:26<ivanm>Twey: doesn't "first-class" mean you can pass functions around?
12:53:32<Twey>ivanm: Yes
12:54:00<ivanm>whereas Absolute0 seems to be referring to higher-order functions, which IIRC means you have functions that use functions
12:54:01<Absolute0>Twey: in those languages these functions are second-class
12:54:10<ivanm>(which kinda relies on first-class functions...)
12:54:22<Twey>ivanm: It's the same abstraction
12:54:24<Absolute0>unlike haskell/lisp
12:54:26<Cale>Heffalump: I'll tell you one exception I usually make is that I won't split up the parameters to a zip or zipWith
12:54:31<Cale>Heffalump: well... usually
12:54:43<Twey>First-class functions begets higher-order functions; higher-order functions require first-class functions
12:54:54<Twey>Absolute0: In what languages? Lisps?
12:54:57<ivanm>yes, but they're still different ;-)
12:55:05<Heffalump>that's the thing though, if there are cases where you do want $ $, then you can't make it left associative
12:55:14<Absolute0>Twey: scroll up
12:55:16<ivanm>Twey: I think Absolute0 means scala, python, etc.
12:55:17<Cale>Heffalump: Oh, I still don't do that
12:55:21<Twey>Oh, right
12:55:24<Cale>Heffalump: I just use natural application
12:55:28<Twey>Absolute0: Python functions are first-class, at least
12:55:33<hackagebot>uu-parsinglib 2.0.1
12:55:33<Twey>I don't know about Scala
12:55:47<Heffalump>that involves too many () for me :-)
12:55:49<Cale>Heffalump: This is specifically in the case that it's last in the chain
12:55:49<EvilTerran>Heffalump / Cale: it'd be nice if you could write "zipWith (...) $ some list expression $ some other list expression", eh =/
12:56:00<Cale>Right.
12:56:15<Cale>That's actually a case where I'd love left associative $
12:57:07<Cale>But I just meant that if I have something like, oh, foo . bar $ zip x y, I usually won't push it as far as foo . bar . zip x $ y
12:57:18<Twey>ivanm: Absolute0 simply said ‘map’
12:57:29<Twey>That could have been referring to the arguments it takes *shrugs*
12:57:35<ivanm>Twey: the message before
12:57:36<Cale>But usually I try to maximise my use of composition to the exclusion of application.
12:57:47<ivanm><Absolute0> scala and python hype about having functional functions, but haskell had it from the start..
12:57:55<ivanm>Twey: though hey also mentioned all and any
12:58:15<Twey>Absolute0: You got higher-order functions and not first-class functions from ‘functional functions’? :-P
12:58:58<Twey>Cale: In fact I go the other way
12:59:05<Absolute0>Twey: details....
12:59:07<Twey>Because it saves a character or two :-P
12:59:14<Twey>Er, ivanm** sorry
12:59:38<ivanm>Twey: I got it from map, all, any ;-)
13:00:59<sohum>ACTION stabs this question
13:01:36<sohum>are there any good resources on clique membership problems, as opposed to clique existence problems?
13:01:39<walter_>how express empty tuple? []?
13:01:54<Cale>walter_: [] is the empty list, () is the empty tuple
13:01:59<sohum>walter_: empty tuple? ()
13:02:07<walter_>got, thank you!
13:02:08<EvilTerran>walter_, [] is empty list. () is empty tuple.
13:02:08<EvilTerran>?type []
13:02:08<EvilTerran>?type ()
13:02:09<lambdabot>forall a. [a]
13:02:10<lambdabot>()
13:02:24<esap>is there a standard way to compare functors for equality based on their structure?
13:02:32<Cale>sohum: Clique membership?
13:03:10<sohum>Cale: as in, given a graph G, a node N in G, and k, is N a member of a clique of size k or greater
13:03:33<Cale>esap: hmm, find a pair of natural transformations and prove they compose to the identity in either direction?
13:03:44<ivanm>sohum: you want to find cliques in a graph?
13:03:57<sohum>ivanm: no, I know that's NP-complete
13:04:02<Cale>sohum: Oh, okay, so you're looking for an algorithm.
13:04:05<ivanm>so what are you actually wanting?
13:04:16<ivanm>ACTION has clique-finding code for FGL graphs, if you want
13:04:23<sohum>ivanm: I want to find if a given node is a member of a clique (of size >= k)
13:04:37<sohum>Cale: yep
13:04:50<ivanm>sohum: as in in Haskell, or an algorithm to do so?
13:05:15<sohum>ivanm: an algorithm will do, this is really a CS question.
13:05:24<ivanm>ahhhh
13:05:37<esap>cale: that's up-to-iso. Well ok, maybe that's what I need to do. I'm just wondering if that's sufficient for declaring two natural transformations to be composable (that the functors in middle are isomorphic?)
13:05:44<ivanm>sohum: I would just try and build a clique with that node; once you've found k nodes in that clique, stop
13:06:37<Cale>esap: Well, otherwise, equality is, well, they're directly the same functor. I suppose we take it for granted in mathematics that you can decide that.
13:07:07<Cale>esap: I suppose if they're only isomorphic, you need a specified isomorphism.
13:07:48<Cale>esap: In implementing a programming language, I suppose I would just check that the types are equal.
13:08:06<sohum>ivanm: hmmmmm. am I right in thinking that that's O(k^2) for the case where you're checking if it's a member of a clique of size k?
13:08:42<ivanm>sohum: sounds like it off the top of my head
13:08:52<esap>cale: Well the thing is, I tried to represent functors as a simple "map of objects" and "map of arrows", but that representation doesn't allow the equality comparison...
13:09:18<Cale>esap: Well, they're equal if those maps are equal...
13:09:33<esap>cale: Well I don't have equality comparison for the maps :-)
13:09:35<uzytkownik>What is standard indentation of do?
13:09:44<Cale>uzytkownik: something like:
13:09:46<Cale>do foo
13:09:48<Cale> bar
13:09:50<Cale> baz
13:10:23<uzytkownik>Cale: Ok. I was not sure if it was do\n foo or do foo. Thanks
13:10:27<Cale>That is, subsequent lines line up with the first non-whitespace character after the 'do'
13:10:36<ivanm>sohum: then again, the way I've found cliques is to take a node n, find it's neighbours, then recursively try adding a neighbour to the current clique and finding the intersection of its neighbours with the neighbours-so-far
13:10:49<ivanm>uzytkownik: you can do that as well
13:10:52<ivanm>some people do:
13:10:55<ivanm>main = do
13:10:57<ivanm> foo
13:10:58<ivanm> bar
13:11:00<ivanm> baz
13:11:00<esap>Cale: http://www.kotiposti.net/epulkkin/Category.txt
13:12:59<Cale>esap: This sort of thing is kind of tricky, because as you go up, you need more and more ability to test equality. I suppose that if you don't mind the finiteness it imposes on things, you can turn more things into concrete values.
13:13:11<uzytkownik>Should I use IO (Maybe a) or use fail?
13:13:22<Cale>uzytkownik: The first, I think.
13:13:37<Cale>uzytkownik: You should never use fail, but there are ways to throw IO exceptions.
13:13:48<esap>cale: yea, I suppose I must rely on finiteness here
13:14:11<Cale>Use Data.Map instead of functions or something
13:14:21<uzytkownik>Cale: Thanks
13:15:41<Cale>uzytkownik: It's generally more convenient to use Maybe when you have any sort of 'lookup' type of operation, because pattern matching is nice and easy. Catching exceptions is not hard, but it's not quite as pretty.
13:15:44<esap>cale: yea, that will work [it'll not be fast, but works]
13:16:33<sohum>ivanm: gaah, brain. could you rephrase that so I can figure out why it's either a heuristic or exponential time?
13:16:49<ivanm>it's not a heuristic
13:16:55<ivanm>but the way my code found cliques was:
13:17:03<CSWookie_>Blah. I feel dumb, but I can't seem to find the syntax for how to define a funtion in the book I'm reading.
13:17:10<ivanm>take a node n; find it's neighbours ns
13:17:56<ivanm>then recursively, take the first elem of ns, and find the intersection of its neighbours and ns
13:18:14<ivanm>(actually, I did this on tails of n's neighbours, IIRC)
13:18:30<ivanm>sohum: I have code online if that would help you...
13:19:28<CSWookie_>Ah, wait, I think I found it.
13:20:24<sohum>ivanm: aha. so in the worst case scenario that is factorial time
13:20:43<ivanm>something like that, yes
13:20:56<sohum>ok, brain better
13:20:59<sohum>thankee
13:21:02<ivanm>you can always simplify it (?) by finding how many you have so far as possibles, as well
13:26:08<sohum>ahaha
13:26:10<sohum>I have it
13:26:32<sohum>checking whether a node of order n is a member of a clique of size n is just O(n^2)
13:26:49<sohum>if the order > n then it becomes exponential
13:41:43<hackagebot>gtk2hs-cast-glib 0.10.1.1
13:51:56<EvilTerran>ACTION notes that you don't seem to be able to nest QuasiQuoters
13:52:05<EvilTerran>, [$ty| [$ty| () |] |]
13:52:06<lunabot> luna: parse error on input `|]'
13:53:12<EvilTerran>ACTION also notes that surely (ty [|...|]) would make more sense than [$ty| ... |], seeing as the body is meant to be a haskell expression
13:54:08<dcoutts>EvilTerran: you can effectively nest them, but not lexically
13:54:44<dcoutts>and similarly for splicing
13:54:46<hackagebot>bindings-common 0.1.1
13:55:59<EvilTerran>dcoutts, "effectively nest"?
13:56:11<dcoutts>EvilTerran: using let
13:56:44<dcoutts>EvilTerran: actually, I should admit I've only done it for splicing, not quoting
13:56:59<dcoutts>it'd need reify I think
13:58:25<Whoof>ACTION pokes Phyx with a large stick.
13:59:15<Phyx->ACTION uses Arrows on Whoof
13:59:46<EvilTerran>, let theType = [$ty| () |] in [$ty| theType |]
13:59:49<lunabot> luna: Exception when trying to run compile-time code:
14:04:24<koeien>@where showHex
14:04:24<lambdabot>I know nothing about showhex.
14:04:34<koeien>?index showHex
14:04:35<lambdabot>Numeric
14:09:26<CSWookie_>Is there nice way to say 'multiples of 3' in haskell?
14:09:55<CSWookie_>I'm used to python, and I'm trying to understand the haskell idioms.
14:10:16<EvilTerran>> [0, 3 ..]
14:10:17<kpreid>> [0,3..]
14:10:22<lambdabot> mueval-core: Prelude.read: no parse
14:10:22<lambdabot> mueval: ExitFailure 1
14:10:22<lambdabot> [0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,...
14:10:32<kpreid>whoops
14:11:29<kpreid>hm, is that lb's parser's bug? I would think that 3 isn't a module name
14:12:33<Phyx->lol
14:12:38<Phyx->which of those failed?
14:12:44<kpreid>mine, I expect
14:12:49<kpreid>> [0, 3 ..]
14:12:50<lambdabot> [0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,...
14:12:51<kpreid>yes
14:12:53<Phyx->ah
14:13:14<olsner>@faq can template haskell iterate all identifiers in a module?
14:13:15<lambdabot>The answer is: Yes! Haskell can do that.
14:13:30<olsner>now, for the how :)
14:13:36<Phyx->@faq can haskell save the world?
14:13:36<Twey>No no
14:13:36<lambdabot>The answer is: Yes! Haskell can do that.
14:13:40<Phyx->rofl
14:13:41<Twey>You don't even need TH
14:13:47<Twey>Look, it says *Haskell* can do it
14:14:12<Twey>That obviously means '98 :-P
14:14:19<Phyx->you could use SYB and haskell-src-ext? :P
14:14:19<olsner>hmm, well of course *Haskell* can do it, question is can *I* :)
14:14:30<trofi>@hoogle :: Integer -> [a] -> a
14:14:30<lambdabot>Data.List genericIndex :: Integral a => [b] -> a -> b
14:14:30<lambdabot>Data.List intersperse :: a -> [a] -> [a]
14:14:30<lambdabot>Data.List genericDrop :: Integral i => i -> [a] -> [a]
14:14:50<Twey>olsner: *grin*
14:14:58<kpreid>trofi: genericIndex is the general (!!) equivalent
14:15:22<CSWookie_>Can I say multiples of 3 or 5 in a similar way?
14:15:29<CSWookie_>I'm doing projecteuler.
14:15:55<hackagebot>gtk2hs-cast-glade 0.10.1.1
14:15:56<kpreid>No...
14:15:58<kpreid>hm
14:16:02<kpreid>@hoogle merge
14:16:02<lambdabot>Distribution.Simple.PackageIndex merge :: Package pkg => PackageIndex pkg -> PackageIndex pkg -> PackageIndex pkg
14:16:02<lambdabot>Text.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError
14:16:02<lambdabot>Text.ParserCombinators.Parsec.Error mergeError :: ParseError -> ParseError -> ParseError
14:16:03<Jedai>CSWookie_: You could just merge the multiples of 3 and the multiples of 5
14:16:19<Jedai>CSWookie_: write the appropriate merge and it's a snap
14:16:26<CSWookie_>Jedai: That sounds like what I want.
14:16:28<byorgey>or you could just use a list comprehension.
14:16:37<kpreid>yeah.
14:16:42<Phyx->yeah, and restrict the values to a multiple of 3 and 5
14:16:51<trofi>kpreid: yeah, i searched exactly that function
14:16:54<kpreid>> [x | x <- [0..], x `mod` 3 == 0, x `mod` 5 == 0]
14:16:55<lambdabot> [0,15,30,45,60,75,90,105,120,135,150,165,180,195,210,225,240,255,270,285,30...
14:17:02<kpreid>er
14:17:06<kpreid>> [x | x <- [0..], x `mod` 3 == 0 || x `mod` 5 == 0]
14:17:07<lambdabot> [0,3,5,6,9,10,12,15,18,20,21,24,25,27,30,33,35,36,39,40,42,45,48,50,51,54,5...
14:17:40<Jedai>kpreid: That works if you're in a hurry but it examines much more numbers
14:18:29<Jedai>(ok, in the case of 3 and 5 not that much more, but imagine you want multiples of much bigger numbers... ^^ )
14:18:57<hackagebot>gtk2hs-cast-th 0.10.1.0
14:19:02<kpreid>> let merge xs@(x:xs') ys@(y:ys') | x < y = x : merge xs' ys; | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..]
14:19:03<lambdabot> <no location info>: parse error on input `|'
14:19:09<kpreid>> let merge xs@(x:xs') ys@(y:ys') | x < y = x : merge xs' ys | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..]
14:19:11<lambdabot> [0,0,3,5,6,9,10,12,15,15,18,20,21,24,25,27,30,30,33,35,36,39,40,42,45,45,48...
14:19:27<kpreid>> let merge xs@(x:xs') ys@(y:ys') | x == y = x : merge xs' ys' | x < y = x : merge xs' ys | otherwise = y : merge xs ys' in merge [0, 3 ..] [0, 5 ..]
14:19:28<lambdabot> [0,3,5,6,9,10,12,15,18,20,21,24,25,27,30,33,35,36,39,40,42,45,48,50,51,54,5...
14:19:31<kpreid>there you go
14:19:43<CSWookie_>Jedai: kpreid: the LC up there will go through all numbers, and return those that are multiples of 3 or 5, yes?
14:19:55<Jedai>CSWookie_: Yes
14:19:57<hackagebot>gtk2hs-cast-gnomevfs 0.10.1.2
14:19:57<hackagebot>gtk2hs-cast-gtk 0.10.1.2
14:19:59<kpreid>CSWookie_: all nonnegative integers, yes
14:20:33<CSWookie_>Haskell is hard for me to read.
14:20:52<kpreid>practice
14:20:55<CSWookie_>ACTION looks up merge in his book.
14:20:57<hackagebot>gtk2hs-cast-gtkglext 0.10.1.2
14:21:09<Jedai>CSWookie_: merge is not a standard function
14:21:11<Phyx->if the numbers are in sequence anyway, wehy not just generate them based on x*3 and 5*x
14:21:14<EvilTerran>CSWookie_, it can take a bit of getting used to
14:21:38<CSWookie_>Oh.
14:21:43<Jedai>CSWookie_: it usually design a function that takes two sorted list and merge them into a sorted list, the detail may vary
14:21:57<kpreid>my eval above gives a definition of merge
14:21:58<hackagebot>gtk2hs-cast-gtksourceview2 0.10.1.2
14:22:02<Jedai>CSWookie_: kpreid gave a version appropriate to our use above
14:22:06<kpreid>in particular, one which combines equal items rather than repeating them
14:22:18<Jedai>kpreid: and works on infinte streams
14:22:50<kpreid>Jedai: I would expect any merge function on Haskell lists to work on infinite streams.
14:23:01<kpreid>Now, mine fails on *finite* lists, but that's just for brevity.
14:23:08<Jedai>kpreid: I meant and only works on infinite streams
14:23:24<CSWookie_>I'm used to much longer variable names.
14:23:49<uzytkownik>I have a parametrized function - by parametr k. In a where close I need to cast on this type (compiler have no way to determin - but that's a different story). Is it possible to indicate that a in where statement is the same a as in function declaration or I have to use less direct method (I know how but it requires 'empty' statement such as head (y:(snd z)) to indicate type of z).
14:23:50<Jedai>CSWookie_: well in our case there is not much point to them
14:24:27<CSWookie_>Jedai: Why?
14:24:52<kpreid>CSWookie_: One can construct a general principle: variable names' length is proportional to the nearness of their uses
14:24:59<Jedai>CSWookie_: merge is the traditional merge, a more precise name is hard to give, and the (x:xs) (y:ys) are traditional for general lists
14:25:18<kpreid>Since Haskell code is so short otherwise, we use short names...
14:25:25<CSWookie_>What?
14:25:35<CSWookie_>Your general principle doesn't make sense to me.
14:25:52<CSWookie_>Jedai: What does the @ mean?
14:25:54<kpreid>Like in C, you almost always use 'i' for a simple array index.
14:25:56<kpreid>Because it's part of the loop and nothing larger.
14:26:04<Jedai>CSWookie_: you could write (head:tail) but it wouldn't give more detail
14:26:29<Jedai>CSWookie_: the @ is a "as-pattern"
14:26:52<Axman6>i prefer x:xs to had:tail because there's a visual que that x is smaller than xs (which is most cases it will be)
14:27:03<Axman6>head*
14:27:21<Axman6>head:tail seems to imply to me that they are equal lengths
14:27:23<Jedai>CSWookie_: xs'@(x:xs) match xs' with the whole list, x with the head of the list and xs with the tail
14:27:30<Axman6>i'm probably alone here though...
14:28:04<Axman6>CSWookie_: xss@(x:xs) defines xss to be the whole list, x to be the head of the list, and xs to be the tail
14:28:15<Jedai>CSWookie_: in general, it allows you to keep a name for the whole parameter while breaking it into finer parts at the same time
14:28:31<olsner>turns out, reify barfs with a compile error when given a nonexistant identifier (rather than indicating whether or not it was defined)
14:28:40<CSWookie_>I'm sorry if I'm thick about things. I've got to go to church, now. I'll be back later, maybe in quiter.
14:29:15<Jedai>CSWookie_: You're not thick, Haskell isn't a particularly easy language to learn
14:29:30<Jedai>CSWookie_: especially if it's your first functional language
14:29:37<Axman6>it's handy for a lot of other things, like data Vec = V Double Double Double; f :: Vec -> Double; f v@(V x y z) = x + 2y* mag v
14:29:44<Twey>Oh, CSWookie_, hello
14:29:56<nA1828KcFz9q>type theory resources?
14:30:06<paolino>hi, anyone can explain the different behaviors here http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5444#a5444 , please?
14:32:36<kpreid>paolino: in the second one, your ErrorT adds an independent error mechanism which has no relation to the one in IO. And your catchError applies to that one rather than IO.
14:32:40<EvilTerran>?hoogle catchError
14:32:41<lambdabot>Control.Monad.Error.Class catchError :: MonadError e m => m a -> (e -> m a) -> m a
14:32:45<Axman6>nA1828KcFz9q: i don't think those words form a question
14:33:18<kpreid>paolino: you'll have to "lift" the catchError into IO to make it do the same as the first (but note that it's a 2-arg function so you can't just apply lift)
14:33:19<EvilTerran>?instances-importing Control.Monad.Error MonadError
14:33:21<lambdabot>IOError IO, e (Either e), e (ErrorT e m), e (RWST r w s m), e (ReaderT r m), e (StateT s m), e (WriterT w m)
14:34:21<EvilTerran>ACTION concurs with kpreid - that'll be the instance MonadError IOError IO, and the instance MonadError e (ErrorT e m)
14:34:46<kpreid>(where e = String and m = IO)
14:34:57<paolino>it makes sense
14:35:49<nA1828KcFz9q>Axman6: Which papers or pages are the standard resources referred to when one is beginning to study algebraic type theory?
14:36:03<EvilTerran>unfortunately, there's an ambiguty in chosing an instance for MonadError for (ErrorT e m) where m is already a MonadError instance
14:36:22<Axman6>that is a certainly a questions. i wish i could help you now :)
14:36:28<paolino>is lifting catchError the way to go from the IOException to a common layer with logic errors ?
14:36:32<Axman6>ACTION doesn't know anything (formally) about type theory
14:36:33<EvilTerran>and, while it does make more sense to go for the instance based around the ErrorT, it does result in this kinda behaviour
14:37:53<paolino>if I'm able to lift it, in the end
14:38:28<EvilTerran>nA1828KcFz9q, Ben Pierce's Types and Programming Languages is an excellent introductory text
14:38:37<EvilTerran>?go TaPL pierce
14:38:38<lambdabot>http://www.cis.upenn.edu/~bcpierce/tapl/
14:38:38<lambdabot>Title: Types and Programming Languages
14:39:19<EvilTerran>i don't recall how much detail it goes into wrt algebraic types, but it covers basic type theory nicely
14:40:28<uzytkownik>?hoogle listToMaybe
14:40:29<lambdabot>Data.Maybe listToMaybe :: [a] -> Maybe a
14:40:37<voker57__>can i make a list which has different types, but all of one typeclass?
14:40:55<voker57__>like type Objects = (Object a) => [a]
14:41:23<EvilTerran>voker57__, not in haskell98; there's usually other ways of achieving the same thing, though
14:41:48<Axman6>hmm, i can see it being possible using partially applied functions... maybe
14:41:49<voker57__>EvilTerran: like?
14:42:33<EvilTerran>voker57__, well, it depends on what you want to do with the list
14:42:53<paolino>kpreid: I don't know how to lift catchError :-/
14:43:04<EvilTerran>for instance, rather than having a [forall a. Show a => a], you could achieve pretty much the same result with just a [String]
14:44:42<kpreid>voker57__: you can get the effect using an existential-type wrapper (which is not h98 as EvilTerran said) -- but yes, you should first consider whether there's a better way to do it
14:48:10<jbjohns>hi all. How does the dynamic linking work in Haskell? I want to create a Haskell CMS and I want users to be able to add modules to the running system like one can with e.g. Joomla! .
14:51:26<harlekin>jbjohns, check out http://hackage.haskell.org/cgi-bin/hackage-scripts/package/plugins.
14:52:06<Jedai>jbjohns: look at happstack too, it may be a good basis
14:53:30<paolino>kpreid: to move errors between layers I have to tag results from IO and case-match them in the ErrorT layer ?
14:53:50<alexsuraci>Is there a way to dump the raw data of a string? e.g. raw "ABC" => "\x41\x42\x43" (or something more natural)
14:54:03<alexsuraci>"raw data" may be the wrong term
14:54:11<kpreid>paolino: it's up to you how you translate the errors
14:54:23<kpreid>> map fromEnum "ABC"
14:54:24<harlekin>@ty ord
14:54:26<lambdabot> [65,66,67]
14:54:26<lambdabot>Char -> Int
14:54:35<harlekin>alexsuraci, map ord "ABC"
14:54:46<alexsuraci>harlekin: thanks, that seems like it'd do it
14:55:00<harlekin>alexsuraci, kpreid's suggestion is more general, though. I'd prefer that.
14:55:11<Axman6>> ord maxBound
14:55:12<lambdabot> 1114111
14:55:49<Axman6>> foldl' (\x n -> n * 1114111 + x) "ABC"
14:55:50<lambdabot> No instance for (GHC.Num.Num [GHC.Types.Char])
14:55:51<lambdabot> arising from the literal ...
14:55:59<Axman6>> foldl' (\x n -> x * 1114111 + n) "ABC"
14:56:00<lambdabot> No instance for (GHC.Num.Num [GHC.Types.Char])
14:56:00<lambdabot> arising from the literal ...
14:56:12<Axman6>> foldl' (\x n -> x * 1114111 + n) 0 "ABC"
14:56:13<lambdabot> No instance for (GHC.Num.Num GHC.Types.Char)
14:56:13<lambdabot> arising from the literal `1...
14:56:32<Axman6>> foldl' (\x n -> n * 1114111 + ord x) 0 "ABC"
14:56:33<lambdabot> Couldn't match expected type `GHC.Types.Char'
14:56:48<Axman6>:t foldl' (\x n -> n * 1114111 + ord x) 0
14:56:48<Jedai>> foldl' (\x n -> x * 1114111 + ord n) 0 "ABC"
14:56:50<lambdabot> 80680889352258
14:56:50<lambdabot> Couldn't match expected type `Char' against inferred type `Int'
14:56:50<lambdabot> In the expression: n * 1114111 + ord x
14:56:50<lambdabot> In the first argument of `foldl'', namely
14:57:00<Axman6>thaks Jedai
14:57:12<Axman6>i never can remember how to use folds
14:57:25<paolino>kpreid: I want to write a function IO a -> ErrorT String IO a, where the possible IOExceptions are found in Lefts values , I suppose
14:57:27<Jedai>Axman6: you're welcome... so base 1114111 ?
14:57:37<Axman6>yup
14:57:51<Axman6>or, base Haskell Char
14:59:08<paolino>:i ErrorT
14:59:16<paolino>@src ErrorT
14:59:17<lambdabot>newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }
14:59:52<marcot>Is there a getDirectoryContentsRecursive function somewhere?
14:59:52<marcot>Like unix find.
14:59:52<lambdabot>marcot: You have 1 new message. '/msg lambdabot @messages' to read it.
15:00:32<EvilTerran>marcot, there may be something on hackage
15:00:42<jbjohns>harlekin: thanks
15:00:48<jbjohns>l
15:03:45<Phyx->@info ->
15:03:45<lambdabot> Parse error at "->" (column 1)
15:03:48<paolino>:t \f -> ErrorT ((Right <$> f) `catch` (return . Left . show))
15:03:54<Phyx->@info ~>
15:03:54<lambdabot>(~>)
15:04:01<Phyx->helpful
15:04:09<harlekin>:D
15:04:42<Phyx->@info (~>)
15:04:42<lambdabot>(~>)
15:04:59<Phyx->@type (~>)
15:05:00<lambdabot>Not in scope: `~>'
15:05:02<paolino>info is not offensive at least :|
15:05:17<Phyx->lol
15:05:20<EvilTerran>Phyx-, there's no @info command, it's typo-corrected to @undo
15:05:20<EvilTerran>@info do x <- 1; return (x,x)
15:05:20<lambdabot>1 >>= \ x -> return (x, x)
15:05:36<Phyx->EvilTerran: which explains alot
15:05:37<Phyx->lol
15:05:51<EvilTerran>^ see, @undo :)
15:06:20<Phyx->> folder (+) 0 []
15:06:22<lambdabot> Not in scope: `folder'
15:06:42<Phyx->oops, right, only commands are typo corrected
15:08:59<Phyx->@king StateT
15:08:59<lambdabot>Maybe you meant: kind ping
15:09:09<Phyx->@king\d StateT
15:09:10<lambdabot>* -> (* -> *) -> * -> *
15:09:20<Phyx->lol
15:09:41<Phyx->that was actually unintentional
15:09:44<jbjohns>@src (>>>)
15:09:44<lambdabot>Source not found. Where did you learn to type?
15:09:51<Phyx->hahaha
15:10:07<Phyx->@index (>>>)
15:10:07<lambdabot>Control.Arrow
15:10:17<Phyx->@src Control.Arrow
15:10:17<lambdabot>Source not found. Where did you learn to type?
15:10:23<paolino>src is offensive
15:10:28<Jedai>@source Control.Arrow
15:10:29<lambdabot>http://darcs.haskell.org/packages/base/Control/Arrow.hs
15:10:39<Jedai>@source Control.Arrows
15:10:40<lambdabot>Control.Arrows not available
15:10:49<Jedai>@source isn't though :)
15:10:49<lambdabot>isn't though :) not available
15:10:52<Phyx->why both src and source?
15:11:08<Jedai>Phyx-: they don't do the same thing
15:11:17<Phyx->is src for it's local definitions?
15:11:34<EvilTerran> @src prints source code to the channel; @source provides a link to the source file
15:11:49<EvilTerran>@src foldr
15:11:49<lambdabot>foldr f z [] = z
15:11:49<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
15:11:50<Jedai>Phyx-: @src gives the source code for a function (when it knows it, so never... ;) and @source gives a link to the source file of a module
15:12:01<Phyx->@src (+)
15:12:02<lambdabot>Source not found. I am sorry.
15:12:05<jbjohns>I think it's actually in Category
15:12:11<EvilTerran>@source Prelude
15:12:11<lambdabot>http://darcs.haskell.org/packages/base/Prelude.hs
15:12:11<Phyx->Jedai: so... @src is useless?
15:12:14<Jedai>@src Int (+)
15:12:14<lambdabot>Source not found. BOB says: You seem to have forgotten your passwd, enter another!
15:13:05<Jedai>Phyx-: no, as EvilTerran has shown, @src works for Prelude functions and some others, but it won't work very often otherwise
15:13:16<Jedai>@src Maybe fmap
15:13:16<lambdabot>fmap _ Nothing = Nothing
15:13:16<lambdabot>fmap f (Just a) = Just (f a)
15:13:21<Phyx->@hoogle (>>>) --info
15:13:21<lambdabot>Control.Arrow (>>>) :: Arrow a => a b c -> a c d -> a b d
15:13:21<lambdabot>
15:13:21<lambdabot>From package base, version 3.0.1.0
15:13:58<Phyx->Jedai: ok, then not useless, just not so useful :)
15:14:12<Jedai>Phyx-: nice to show a basic function to a beginner
15:14:54<Phyx->:)
15:15:10<Jedai>Phyx-: by the way, @src (+) don't work because (+) is a class method, @src Int (+) should work but I'm guessing it don't because it's defined somewhere in the entrail of GHC
15:15:27<Jedai>@src Complex (+)
15:15:27<lambdabot>Source not found. Are you on drugs?
15:15:32<Phyx->hahahah
15:15:41<Phyx->rofl
15:15:59<Jedai>@src (++)
15:15:59<lambdabot>[] ++ ys = ys
15:15:59<lambdabot>(x:xs) ++ ys = x : (xs ++ ys)
15:15:59<lambdabot>-- OR
15:15:59<lambdabot>xs ++ ys = foldr (:) ys xs
15:16:22<Phyx->@src return
15:16:22<lambdabot>Source not found. I can't hear you -- I'm using the scrambler.
15:16:34<Jedai>@src Maybe return
15:16:34<lambdabot>return = Just
15:16:39<Phyx->ah
15:16:40<Phyx->right
15:17:27<Phyx->i was actually expecting it to print out the definition in the class, on the first one
15:17:36<EvilTerran>marcot, would http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-tree suit your purposes?
15:17:44<Taejo>which Regex library is the fastest? (my regexes are large but fairly simple)
15:17:52<Berengal>@src Monad
15:17:53<lambdabot>class Monad m where
15:17:53<lambdabot> (>>=) :: forall a b. m a -> (a -> m b) -> m b
15:17:53<lambdabot> (>>) :: forall a b. m a -> m b -> m b
15:17:54<lambdabot> return :: a -> m a
15:17:56<lambdabot> fail :: String -> m a
15:17:58<marcot>EvilTerran: I was looking at Unixutils, let me see this option.
15:18:03<Jedai>Phyx-: Nope, @src is pretty stupid... and offensive !
15:18:22<Phyx->hehehe
15:18:34<kpreid>ACTION also wishes @src wouldn't print insults
15:18:43<jbjohns>I was just trying to figure out an example from Niel Bartlett's blog
15:18:56<Jedai>Taejo: regex-pcre is pretty fast from what I know, if you ever write a benchmark don't forget to post the results !
15:19:10<jbjohns>> test1 a = a * a
15:19:11<lambdabot> <no location info>: parse error on input `='
15:19:20<jbjohns>> let test1 a = a * a
15:19:21<lambdabot> not an expression: `let test1 a = a * a'
15:19:31<marcot>EvilTerran: Unixutils seems to be simpler.
15:19:44<jbjohns>no way to define functions with lambda bot then?
15:19:49<Phyx->@let test1 a = a * a
15:19:50<lambdabot> Defined.
15:19:53<jbjohns>ah
15:19:57<Phyx->> test1 6
15:19:59<lambdabot> 36
15:20:04<Taejo>Jedai: I was just thinking, if all else fails, I'll just use something that isn't PCRE. I prefer high-factor linear time to heavily optimized exponential
15:20:18<Jedai>jbjohns: but usually we use "> let ... in ..."
15:20:29<EvilTerran>but note all the @let definitions disappear if anyone does an @undef
15:20:45<jbjohns>He gave the example: summaries = deep (hasName "cd") >>> (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary
15:20:50<Jedai>@undef
15:20:55<Phyx->@undef test1
15:21:07<Phyx->odd
15:21:12<Phyx->> test1 7
15:21:13<lambdabot> Not in scope: `test1'
15:21:15<Phyx->ah
15:21:37<Phyx->> join (+) 6
15:21:38<lambdabot> 12
15:22:51<Jedai>Taejo: you still have posix, IIRC they're linear time, no ?
15:22:55<jbjohns>As I read that, deep must be returning a list of xml nodes, but the rest of it seems to work with only one element
15:23:06<mxc>regarding atomicModifyIORef, the docs say that it is unsafe for multiple IORefs, does that mean that if you are trying to modify multiple IORefs in a single call its unsafe or if you have multiple IORefs in distinct parts of the code, anywhere, its unsafe?
15:23:16<EvilTerran>Phyx-, as i said, @undef doesn't take a parameter, it undefines everything
15:23:26<Taejo>Jedai: well, posix, tdfa and dfa seem to be the options
15:23:40<Phyx->EvilTerran: that needs some updating
15:23:59<jbjohns>@let itemSummary a t = t ++ " performed by " ++ a
15:24:01<lambdabot> Defined.
15:24:12<Jedai>jbjohns: what's the definition of deep
15:24:21<jbjohns>deep scan of an XML tree
15:24:30<eivuokko>mxc, it means it's not possible to have atomic guarantee when trying to change multipe iorefs from one location, in presence of other threads/finalisers.
15:24:35<Jedai>jbjohns: right but what's its type
15:25:04<mxc>eivuokko : thanks. thats what I thought, but just wanted to double check
15:25:09<jbjohns>@let getAttrValue k ((k',v):'t) = if k == k' then v else getAttrValue k 't
15:25:09<lambdabot> Parse error in pattern: HsVarQuote (UnQual (HsIdent "t"))
15:25:22<jbjohns>@let getAttrValue k ((k',v):t') = if k == k' then v else getAttrValue k t'
15:25:23<lambdabot> Defined.
15:25:40<jbjohns>getAttrValue "artist" [("artist", "me")]
15:25:46<jbjohns>> getAttrValue "artist" [("artist", "me")]
15:25:47<lambdabot> "me"
15:26:00<Berengal>> curry id 5 6
15:26:02<lambdabot> (5,6)
15:26:04<Jedai>@type lookup
15:26:05<lambdabot>forall a b. (Eq a) => a -> [(a, b)] -> Maybe b
15:26:19<EvilTerran>@src lookup
15:26:20<lambdabot>lookup _key [] = Nothing
15:26:20<lambdabot>lookup key ((x,y):xys) | key == x = Just y
15:26:20<lambdabot> | otherwise = lookup key xys
15:26:59<jbjohns>> (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary $ [("artist", "Puddle of mud"), ("title", "She hates me")]
15:27:00<lambdabot> "She hates me performed by Puddle of mud"
15:27:32<jbjohns>so I was trying to figure out how deep is able to get this part to iterate over all the nodes. It seems to operator only on a single entry
15:27:47<jbjohns>> :t (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary
15:27:48<lambdabot> <no location info>: parse error on input `:'
15:27:59<jbjohns>@type (getAttrValue "artist") &&& (getAttrValue "title") >>> (arr . uncurry) itemSummary
15:28:00<lambdabot>[([Char], [Char])] -> [Char]
15:28:01<Jedai>@type (>>>)
15:28:02<lambdabot>forall (cat :: * -> * -> *) a b c. (Control.Category.Category cat) => cat a b -> cat b c -> cat a c
15:28:47<jbjohns>@type deep
15:28:48<lambdabot>Not in scope: `deep'
15:29:14<Jedai>jbjohns: Your inquiry is pointless without the type of deep, the arrow in which we're operating or a link to the article/paper
15:29:54<jbjohns>it's from HXL
15:30:05<jbjohns>HXT even
15:30:24<jbjohns>the XML library that uses arrows
15:30:53<jbjohns>deep :: XmlFilter -> XmlFilter
15:31:17<jbjohns>type XmlFilter = XmlTree -> [XmlTree]
15:35:34<lars9>hey, i've learning haskell, i have a problem to solve but dunno how to design the code, may i get some help here?
15:35:52<Zao>Quite possibly.
15:35:54<eivuokko>Very likely.
15:36:25<burp>?faq can haskell solve the problem?
15:36:25<lambdabot>The answer is: Yes! Haskell can do that.
15:36:31<lars9>the problem is: given a list l, print out all sublist of length n, and the number of their appearence
15:39:19<Phyx->> quickCheck \x->x==x
15:39:20<lambdabot> <no location info>: parse error on input `\'
15:39:34<Phyx->> quickCheck (\x->id x = x)
15:39:36<lambdabot> <no location info>: parse error on input `='
15:39:41<Phyx->> quickCheck (\x->id x == x)
15:39:42<lambdabot> Not in scope: `quickCheck'
15:40:02<Jedai>jbjohns: From what I see, deep is an operation from the class ArrowTree
15:40:29<EvilTerran>@check \x -> id x == x
15:40:30<lambdabot> "OK, passed 500 tests."
15:40:42<Phyx->ah
15:40:46<EvilTerran>@check \x y -> x == y -- but beware of defaulting
15:40:47<lambdabot> "OK, passed 500 tests."
15:40:47<jbjohns>ah, yep, I see it
15:41:04<Phyx->@check \x join pure x == x
15:41:04<lambdabot> Parse error at "==" (column 16)
15:41:13<Phyx->@check \x-> join pure x == x
15:41:14<lambdabot> "OK, passed 500 tests."
15:41:29<Jedai>jbjohns: anyway, arrows are a very powerful abstraction, (>>>) on this case isn't working on simple functions, trying to approximate it with composition won't work
15:41:34<Phyx->how does that work anyway, i don't see how join pure becomes the identity
15:41:35<lars9>for example, give 1231234, all sublists of length 3 are: 123, 231, 312, 234, which appears 2, 1, 1, 1 times, respectively
15:41:55<voker57__>lars9: something like [inits ts | ts <- tails xs]
15:42:04<voker57__>where xs is the list
15:42:43<Phyx->@type join pure
15:42:44<lambdabot>forall a. a -> a
15:42:47<Phyx->@type join
15:42:48<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
15:42:58<voker57__>> let xs = [1..10]
15:42:59<lambdabot> not an expression: `let xs = [1..10]'
15:43:06<EvilTerran>?type join pure
15:43:07<lambdabot>forall a. a -> a
15:43:16<voker57__>> let xs = [1..10] in [inits ts | ts <- tails xs]
15:43:17<lambdabot> [[[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6],[1,2,3,4,5,6,7],...
15:43:28<jbjohns>Jedai: I agree, but the thing I did above was using the same operators. I tried passing a list of those nodes but I didn't see how to make it traverse. (>>>) also doesn't seem to be a type class method so I didn't see how it's overloaded unless (.) itself is overloaded
15:43:39<Taejo>> break (== 2) [2, 2, 3, 4]
15:43:42<lambdabot> ([],[2,2,3,4])
15:43:48<Phyx->EvilTerran: I thought the result of join was always a monad
15:43:50<Taejo>> break (=/ 2) [2, 2, 3, 4]
15:43:52<lambdabot> Not in scope: `=/'
15:43:59<Taejo>> span (== 2) [2, 2, 3, 4]
15:44:01<lambdabot> ([2,2],[3,4])
15:44:01<byorgey>Phyx-: that's using the ((->) a) monad
15:44:16<Taejo>anyone have a good mnemonic for which is which of break and span?
15:44:21<Jedai>> M.fromList (take 3 . tails $ [1, 2, 3, 1, 2, 3, 4])
15:44:22<lambdabot> Couldn't match expected type `(k, a)' against inferred type `[a1]'
15:44:32<voker57__>> let xs = [1..5] in [filter (/= []) (inits ts) | ts <- tails xs]
15:44:33<byorgey>pure :: a -> m a, so unifying that with m (m a) means m = (a ->)
15:44:34<lambdabot> [[[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]],[[2],[2,3],[2,3,4],[2,3,4,5]],[[...
15:44:34<Jedai>> S.fromList (take 3 . tails $ [1, 2, 3, 1, 2, 3, 4])
15:44:35<lambdabot> fromList [[1,2,3,1,2,3,4],[2,3,1,2,3,4],[3,1,2,3,4]]
15:45:02<voker57__>> let xs = [1..3] in [filter (/= []) (inits ts) | ts <- tails xs]
15:45:04<lambdabot> [[[1],[1,2],[1,2,3]],[[2],[2,3]],[[3]],[]]
15:45:06<EvilTerran>Phyx-, both the join and the pure are in the (e->) monad
15:45:13<Jedai>> M.fromList (map take 3 . tails $ [1, 2, 3, 1, 2, 3, 4])
15:45:14<lambdabot> Couldn't match expected type `b -> c'
15:45:20<voker57__>> let xs = [1..3] in filter (/=[]) [filter (/= []) (inits ts) | ts <- tails xs]
15:45:21<Jedai>> M.fromList (map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4])
15:45:22<lambdabot> [[[1],[1,2],[1,2,3]],[[2],[2,3]],[[3]]]
15:45:23<lambdabot> Couldn't match expected type `(k, a)' against inferred type `[a1]'
15:45:29<EvilTerran>Phyx-, in which join f x = f x x, and pure = const
15:45:30<Jedai>> S.fromList (map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4])
15:45:31<lambdabot> fromList [[],[1,2,3],[2,3,1],[2,3,4],[3,1,2],[3,4],[4]]
15:45:35<voker57__>that's it, i guess
15:45:35<lars9>in other languages, that problem requires a 'map', but how to do in haskell
15:45:41<Phyx->EvilTerran, byorgey hm, ok, guess i'll go take a look at that monad
15:45:47<Jedai>lars9: with a MAp
15:46:15<voker57__>with map, you map!
15:46:24<Jedai>> M.fromListWith (+) . map (flip (,) 1) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4]
15:46:26<lambdabot> fromList [([],1),([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1),...
15:46:56<Jedai>lars9: there, it's almost good, you just have to delete those pesky too small sublists
15:47:09<EvilTerran>Phyx-, Reader is just (->) with a newtype wrapper
15:47:23<voker57__>i solved this already
15:47:58<voker57__>why IntMap?
15:48:12<Jedai>voker57__: I didn't see it ?
15:48:24<Phyx->EvilTerran: ah ok, cool
15:48:39<voker57__>Jedai: let xs = [1..3] in filter (/=[]) [filter (/= []) (inits ts) | ts <- tails xs]
15:48:46<Jedai>voker57__: I don't think you're resolving the problem lars9 asked
15:49:02<skorpan>would it be appropriate to call something with the type "s -> Bool" a predicate?
15:49:05<EvilTerran>voker57__, it'd be better to write (not.null) rather than (/= [])
15:49:06<Jedai>voker57__: he wanted all sublists of length n (3 in his example)
15:49:12<voker57__>ah, length n
15:49:19<EvilTerran>?type not.null
15:49:19<EvilTerran>?type (/= [])
15:49:20<lambdabot>forall a. [a] -> Bool
15:49:21<lambdabot>forall a. (Eq a) => [a] -> Bool
15:49:27<voker57__>well another filter :)
15:49:31<EvilTerran>skorpan, entirely appropriate, imo
15:49:32<Jedai>@src (>>>)
15:49:33<lambdabot>Source not found. My brain just exploded
15:49:34<Phyx->ahhh ok
15:49:36<skorpan>EvilTerran: okay, thanks
15:49:40<Phyx->makes sense now
15:49:44<Jedai>@source Control.Arrow
15:49:44<lambdabot>http://darcs.haskell.org/packages/base/Control/Arrow.hs
15:50:08<voker57__>Jedai: let xs = [1..3] in filter (((==) 3) . length) [filter (not.null) (inits ts) | ts <- tails xs]
15:50:15<voker57__>> let xs = [1..3] in filter (((==) 3) . length) [filter (not.null) (inits ts) | ts <- tails xs]
15:50:17<lambdabot> [[[1],[1,2],[1,2,3]]]
15:51:06<Jedai>@source Control.Category
15:51:06<lambdabot>Control.Category not available
15:52:18<Jedai>jbjohns: but (.) is overloaded (in Control.Category, where (>>>) is defined)
15:52:37<voker57__>> let xs = [1..5]; n=3 in filter (not.null) [filter (((==) 3) . length) (inits ts) | ts <- tails xs]
15:52:39<lambdabot> [[[1,2,3]],[[2,3,4]],[[3,4,5]]]
15:53:08<Jedai>voker57__: not elegant (and you have too much [])
15:53:25<voker57__>> let xs = [1..5]; n=3 in foldl (++) [] $ filter (not.null) [filter (((==) 3) . length) (inits ts) | ts <- tails xs]
15:53:27<lambdabot> [[1,2,3],[2,3,4],[3,4,5]]
15:54:03<voker57__>yep... the requirement on length allows to make it easier
15:54:04<Jedai>> M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate 2 inits) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4]
15:54:05<lambdabot> Occurs check: cannot construct the infinite type: a = [a]
15:54:26<Jedai>> M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate 2 init) . map (take 3) . tails $ [1, 2, 3, 1, 2, 3, 4]
15:54:28<lambdabot> fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1)]
15:54:36<Jedai>ok, so :
15:54:41<Taejo>what is the language pragma for no monorphism restriction?
15:54:52<jbjohns>jedai: yea, I was looking to see if that was overriden to do some iteration anywhere, but the definition for deep you found doesn't seem to iterate. Definition: deep f = f `orElse` (getChildren >>> deep f)
15:55:02<wli>{-# LANGUAGE NoMonomorphismRestriction #-}
15:55:40<Jedai>let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate (n-1) init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4]
15:55:46<Jedai>> let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate (n-1) init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4]
15:55:47<lambdabot> fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1),([3,4],1)]
15:56:14<Jedai>> let countSub n = M.fromListWith (+) . map (flip (,) 1) . foldr (.) id (replicate n init) . map (take n) . tails in countSub 3 [1, 2, 3, 1, 2, 3, 4]
15:56:15<lambdabot> fromList [([1,2,3],2),([2,3,1],1),([2,3,4],1),([3,1,2],1)]
15:56:49<Jedai>lars9: There, you have it, works perfectly and not too inneficient
15:57:07<voker57__>> let n = 3; xs = [1..5] in filter (((==) n) . length) $ map (take n) (tails xs)
15:57:09<lambdabot> [[1,2,3],[2,3,4],[3,4,5]]
15:57:10<lars9>Jedai: thanks, let me learn it
15:57:14<Taejo>wli: thanks, must have been misspelling it
15:57:15<voker57__>another one :)
15:57:15<lars9>Jedai: first
15:57:28<lars9>voker57__: great, thanks too
15:58:06<voker57__>Jedai: so why do use Map?
15:58:23<Jedai>voker57__: ((==) n) can be written (n ==), it's a little bit better IMHO
15:58:56<Jedai>voker57__: to count the number of occurence of each sublist, it was my understanding that this was what was asked
15:59:08<voker57__>oh.
15:59:20<lars9>Jedai: yeah, count the number of occurence
15:59:24<voker57__>ACTION needs to learn to read
15:59:45<Jedai><lars9> the problem is: given a list l, print out all sublist of length n, and the number of their appearence
16:00:01<voker57__>i though it was about a total number of sublists
16:00:21<lars9>that would be length - n + 1, :D
16:01:02<Jedai>voker57__: also your proposition is less efficient than my own, probably two times slower
16:02:07<lars9>Jedai: is there staright forward way to do the count thing? like count the number of each char in a string
16:02:50<Jedai>lars9: the idiom is "M.fromListWith (+) . map (flip (,) 1)"
16:03:03<EvilTerran>lars9, length . filter (==c) would be the usual method
16:03:14<EvilTerran>(for each char)
16:03:32<EvilTerran>or map (head &&& length) . group . sort
16:03:42<EvilTerran>to get a [(Char,Int)] with a list of counts
16:03:43<lars9>EvilTerran: then we need to 'unique' the string first?
16:03:58<Phyx->nub
16:04:00<EvilTerran>> map (head &&& length) . group . sort $ "abracadabra"
16:04:02<lambdabot> [('a',5),('b',2),('c',1),('d',1),('r',2)]
16:04:25<Jedai>Phyx-: Please don't say nub to the beginner, it's too damn slow !
16:04:36<Phyx->rofl
16:04:53<Phyx->it's because he is a beginner i said it
16:04:56<lars9>EvilTerran: abracadabra is common in textbook, did you just think it out? :D
16:05:05<EvilTerran>nub is O(n^2); map head . sort is O(n*log n)
16:05:05<Phyx->@type group
16:05:07<lambdabot>forall a. (Eq a) => [a] -> [[a]]
16:05:10<Jedai>EvilTerran: What do you think is faster ? The Map trick or this one (theoretically it has the same complexity)
16:05:31<Heffalump>hi augustss
16:05:55<augustss>hi
16:05:57<Phyx->@index group
16:05:57<lambdabot>Data.List
16:06:05<EvilTerran>lars9, i just use it as a placeholder for demo'ing various string manipulations
16:06:13<EvilTerran>lars9, it has various useful properties for that sort of thing
16:06:17<Phyx->hmm interestig function
16:06:22<EvilTerran>(like five 'a's)
16:08:13<lars9>what about the usual way of implementing key-value data structure in haskell?
16:08:26<EvilTerran>Jedai, no idea; i figure they're probably close enough that you should use whichever you find clearest
16:08:29<EvilTerran>lars9, that'd be Data.Map
16:09:12<lars9>EvilTerran: let me check Data.Map, maybe it's better in doing the counting job
16:09:27<lars9>EvilTerran: more straight forward i mean
16:09:28<Jedai>lars9: That's what I used in my method
16:09:56<lars9>Jedai: the 'M' is Data.Map?
16:10:04<Jedai>@type M.fromListWith
16:10:05<lambdabot>forall a k. (Ord k) => (a -> a -> a) -> [(k, a)] -> M.Map k a
16:10:11<lars9>Jedai: sorry i didnt figure it out
16:10:42<Jedai>lars9: it's a shortcut in lambdabot (Data.Map is imported qualified as M)
16:10:54<EvilTerran>lars9, lambdabot basically has "import qualified Data.Map as M"
16:11:06<lars9>Jedai: i see, smart bot
16:13:05<stepnem>and what is the comma in (flip (,) 1)?
16:13:26<Jedai>stepnem: I could rewrite that as (\x -> (x,1))
16:13:41<stepnem>ah, I see, :)
16:13:49<Jedai>stepnem: It could be clearer (depending on your addictiong to pointfree style)
16:14:10<byorgey>@type (,)
16:14:11<lambdabot>forall a b. a -> b -> (a, b)
16:14:16<byorgey>> (,) 2 3
16:14:17<lambdabot> (2,3)
16:14:22<stepnem>heh
16:14:42<lars9>i know the Map thing now. How to do this counting job onlinely?: read symbols from a list one by one, and print the number of occurence of the read symbol.
16:15:31<Jedai>lars9: I'm not sure what you mean, you want to print the number of occurence "until now" ?
16:15:33<byorgey>you can do that with a Map too. just keep a Map around and update it each time you read a symbol
16:16:02<lars9>read 'a', print 1, read 'b', print 1, read 'a', print 2, read 'c', print 1
16:16:23<lars9>read '\n', exit
16:17:48<kpreid>lars9: if you like functionalness, start with 'main = interact yourFunc' where yourFunc :: String -> String
16:18:19<Jedai>lars9: Yep, do that with a Map, you can even be pretty efficient by using an insertLookupWithKey (in order to read and modify the value simultaneously)
16:18:51<lars9>Jedai: but how to loop in main?
16:19:21<Jedai>lars9: Try using kpreid method (interact)
16:20:00<lars9>Jedai: kpreid : thanks, let me check 'interact' first
16:20:15<Jedai>lars9: it's pretty easy to loop anyway, you can just call main in main (or do the same with another function if you want a smaller loop)
16:21:14<lars9>i see, recursion for loop
16:21:53<lars9>got to go now, thanks guys, bye:)
16:22:03<Jedai>lars9: You can also write your own loops
16:28:01<RayNbow>ah, apfelmus has a nice quit msg :)
16:34:01<Taejo>how do I run an external process in Haskell?
16:36:40<int-e>something in the process library should do the trick. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/process -- System.Cmd is a simple interface that simply runs commands while System.Process is more complicated but allows you to capture stdin, stdout and stderr as well.
16:44:18<burp>argl, I hate "where" indention
16:46:38<Cale>burp: what about it?
16:46:52<Cale>burp: You have roughly two options
16:46:56<Cale>foo = bar
16:47:05<Cale> where bar = quux
16:47:10<Cale>foo = bar
16:47:12<Cale> where
16:47:16<Cale> bar = quux
16:48:08<dolio>No, no. In that second one, you should line bar up with where. :)
16:48:17<Cale>In either case, the subsequent lines should align to the column containing the first non-whitespace character after the 'where'
16:48:20<burp>really?
16:48:26<Cale>I wouldn't.
16:49:20<Cale>(but obviously the rule is a little more general than this)
16:49:54<Cale>The important thing is that the contents of the 'where' is indented more than the function/value definition itself.
16:51:15<burp>ok
16:51:27<kpreid>there's also foo = bar where
16:51:27<kpreid> ...
16:51:42<Cale>I find that a bit annoying, myself :)
16:51:56<burp>@pretty looooooooooong t = A*cos(omega*t) + B*sin(omega*t) + h where { A = 4.8-5*h; B = 1/2; h = 12.8/14; omega = 2*pi/12 }
16:51:56<lambdabot> looooooooooong t = A * cos (omega * t) + B * sin (omega * t) + h
16:51:56<lambdabot> where A = 4.8 - 5 * h
16:51:56<lambdabot> B = 1 / 2
16:51:56<lambdabot> h = 12.8 / 14
16:51:56<lambdabot> omega = 2 * pi / 12
16:51:57<Cale>Unless the contents of the where will all fit onto that one line
16:52:34<Cale>burp: Note that the 'where' is part of the function definition itself, and *not* the expression on the right hand side of the =
16:53:03<Cale>This actually matters conceptually, as 'where' will scope over multiple guards.
16:53:18<Cale>foo x | y < 0 = ...
16:53:23<Cale> | y == 0 = ...
16:53:28<Cale> | y > 0 = ...
16:53:33<Cale> where y = x^2 + x + 1
16:54:56<burp>http://paste.railsbox.eu/show/1IOFKrp52ZBMHgMHhPyr/ <- why is this indention wrong then?
16:55:23<burp>oh.. capitals
16:55:33<Cale>(heh, of course, thinking would reveal there that only one of my guards will ever succeed :)
16:55:49<Cale>oh, yes
16:55:58<Cale>A and B look like data constructors
16:56:03<burp>with correcty syntax highlighting the problem is directly visible :>
16:56:09<Cale>indeed :)
17:00:44<int-e>Calling a local binding in a function 'h' 'h' may lead to confusion.
17:01:55<burp>uh, thats true
17:05:33<Taejo>what is the Bool argument to executeFile?
17:06:48<Taejo>ah, never mind, looks like I should be using System.Process
17:06:59<alexsuraci>woo, just implemented python's struct.unpack in haskell
17:07:16<int-e>Taejo: yes you should. but it tells executeFile whether to search the PATH or not.
17:07:31<Taejo>int-e: thanks
17:09:30<stepnem>are there some more accessible resources on arrows (>>>,&&& etc.)?
17:10:27<stepnem>I see there's plenty of stuff on monads, on haskell.org, but what about arrows (other than the paper(s))...?
17:11:03<Taejo>stepnem: the distinction between "papers" and "not papers" is artificial :)
17:11:22<Taejo>but I agree that the arrows paper is not a great tutorial
17:11:44<stepnem>Taejo: well, whatever, *accessible* is my point here, :)
17:12:02<Saizan>the papers are quite accessible
17:12:08<stepnem>and more tutorial-like, yeah
17:12:46<stepnem>hm... maybe I should try the papers then -- honestly, I haven't so far, heh
17:13:03<PeakerWork>stepnem: I think you should start with Category, its much simpler
17:13:30<Saizan>arrows are not so widely used, so you don't have many compelling examples to work with
17:13:34<PeakerWork>stepnem: Arrows are not a very interesting class, due to a design mistake in there..
17:14:40<arjanb>what design mistake?
17:14:44<Taejo>Saizan: I don't use arrows much, but I use the arrow combinators a fair bit with plain old (->) arrows
17:14:59<Taejo>first, second, (&&&), (***) are all pretty handy
17:15:10<stepnem>hm, I have to say that 'map (head &&& length) . group . sort $ "abracadabra"' *is* quite interesting and compelling for me, :)
17:15:36<Saizan>Taejo: yeah, but that's more like having Data.Tuple than anything else
17:16:00<Taejo>Saizan: yes, indeed. but it seems that's what stepnem is interested in
17:16:19<Saizan>i mean, if you're only using one instance ever you don't even need to learn about the abstraction
17:16:25<Taejo>indeed
17:16:27<Saizan>just learn about what each combinator does
17:16:38<Taejo>so, stepnem, don't bother learning the abstraction right now
17:17:42<Taejo>stepnem: the (&&&) combinator has type (a -> b) -> (a -> c) -> (a -> (b, c)) (restricting to the ordinary -> arrow)
17:17:49<stepnem>Taejo: but what should I look at then? only from the source it isn't very ovious to me what's going on there
17:17:55<stepnem>obvious*
17:18:09<Taejo>yes, because of the unneeded abstraction
17:18:46<Taejo>without the abstraction, (&&&) f g x = (f x, g x)
17:19:02<Taejo>and (***) f g (x, y) = (f x, g y)
17:19:07<Saizan>the instance for (->) should have that definition, or similar
17:19:14<stepnem>ah... right, :)
17:19:15<Taejo>true
17:19:25<Taejo>@src (&&&) (->)
17:19:26<lambdabot>Source not found. That's something I cannot allow to happen.
17:19:32<Taejo>@src &&& ->
17:19:33<lambdabot>Source not found. My pet ferret can type better than you!
17:19:42<Taejo>@src (->) (&&&)
17:19:43<lambdabot>Source not found. My mind is going. I can feel it.
17:19:49<Taejo>never mind, then
17:22:53<PeakerWork>how can Ocaml beat Haskell's conciseness in: http://gmarceau.qc.ca/blog/2009/05/speed-size-and-dependability-of.html ?
17:23:40<Taejo>@where (</>)
17:23:41<lambdabot>I know nothing about (</>).
17:26:10<Taejo>is it impossible to use readFile and appendFile on the same file in a program, even if I know that the one finishes before the other starts?
17:29:19<Athas>I just had my first real use of the Maybe monad in code.
17:29:22<Athas>Man, that is really handy.
17:29:45<Athas>I have a definition that now looks like: s' = s { finger = finger s >>= return . (+1) }
17:29:55<Athas>That would have been much more ugly if written explicitly. Thank you, Data.Maybe!
17:30:12<CSWookie_>ACTION goes back to look at that merge thing again.
17:33:37<Jedai>Taejo: No, it's not impossible at all
17:34:01<int-e>Taejo: It's not impossible, but the only way to close the file reliably after readFile is to consume all data that readFile returned. consume :: String -> IO (); consume = foldr (const id) (return ()), say.
17:34:41<Jedai>Athas: s' = s { finger = fmap (+1) (finger s) }
17:35:08<Jedai>Athas: Maybe is an instance of Functor too, and in your case that's all you need
17:35:16<Athas>Oh yes, that is better. Thank you.
17:37:40<PhDP>Somebody know what Don is using in this vidéo; http://www.youtube.com/watch?v=2Lqzygxvus0... emacs ? Vim ? (I really don't know much about this kind of thing, but it seems powerful)
17:38:16<Samy>Probably vim.
17:38:26<Samy>ACTION didn't look at the video
17:38:54<profmakx>its vim
17:38:59<profmakx>as you can see in the top bar
17:39:01<Jedai>PhDP: I couldn't say, the url is malformed for me
17:39:40<profmakx>some day i will try stuff out for my phd in haskell...
17:39:50<PhDP>http://archhaskell.wordpress.com/2009/03/24/chart-a-library-for-generating-2d-charts-and-plots/
17:39:52<Taejo>int-e: my seq was in the wrong place. thanks for the help
17:41:55<jbjohns>do haskell structures have any kind of syntax like Erlang does?
17:42:16<skorpan>what do you mean?
17:42:28<jbjohns>like for example, the UTCTime structure has a field for every element of time, day, month, etc.
17:42:49<jbjohns>in erlang you could take one of those and do like: UTCTime#variable{hour = 2}
17:42:57<jbjohns>and get a copy of the variable but with the time set to 2
17:43:02<jbjohns>er, with the hour set to 2
17:43:36<Jedai>PhDP: Yeah, it vim but he doesn't do anything impressive with it (by emacs or vim standard anyway), the demo is nice thanks to the library, ghci and xmonad
17:43:51<jbjohns>it's nice when you just want to change a part of the "structure" but not all of it
17:44:17<Jedai>jbjohns: In haskell they're called records
17:44:22<PhDP>Well then I'm just easily impressed, for now I'm writting my code with basic text editor.
17:44:39<jbjohns>Erlang as well. I just knew they were made with the data keyword so I didn't know what Haskell called them
17:44:45<Jedai>jbjohns: and you have this kind of syntax too
17:44:51<jbjohns>wonderful
17:45:16<Jedai>data Stuff = { foo :: Int, bar :: Maybe Bool }
17:45:36<Jedai>test = { foo = 5, bar = Nothing }
17:45:53<Jedai>test2 = test { bar = Just True }
17:46:07<Jedai>data Stuff = Stuff { foo :: Int, bar :: Maybe Bool }
17:46:20<jbjohns>ah, that works? I didn't even know what try
17:46:24<Jedai>test = Stuff 5 Nothing
17:46:42<jbjohns>I read through Real World Haskell in the records part but I didn't see it
17:46:43<Jedai>jbjohns: sorry, my first version lacked the constructor
17:47:24<Jedai>test = Stuff {foo = 5, bar = Nothing}
17:47:41<Jedai>jbjohns: so test2 is test with bar modified
17:48:03<Jedai>jbjohns: "foo test" gets the value in the foo field
17:48:53<Jedai>jbjohns: This isn't perfect though, especially when you want to modify a value deep inside a record in a record in a record
17:49:58<Jedai>jbjohns: if you find yourself doing things like that look up the data-accessor package, it's pretty nice
17:50:52<Jedai>jbjohns: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/data-accessor
17:51:06<fracture>(got booted; so missed if anyone answered that)
17:51:58<jbjohns>thanks, I just tried it out on my stuff, looks good
17:52:14<jbjohns>now I can go change a bunch of my code from when I didn't know you could do this
17:52:33<Jedai>jbjohns: How did you do it before ?
17:53:00<jbjohns>I have a function like: withDays f dt = UTCTime { day = f dt.day, month = dt.month, year = ....
17:53:45<Jedai>jbjohns: dt.month is written month dt in Haskell though
17:53:52<fracture>so in case that didn't go through: is there a way to make user defined data constructors that take a variable number of arguments (like [] does)?
17:53:54<jbjohns>I used Haskell before Erlang so it never occurred to me to even look for something like this
17:54:03<fracture>(or maybe [] doesn't...)
17:54:05<jbjohns>Jedai: Yea, must be that then
17:54:45<fracture>actually (after playing around), I guess I don't understand what the tutorials mean when they say [] is like a data constructor
17:54:45<Jedai>fracture: [1,2,3] is special syntax, it's syntax sugar for 1:2:3:[]
17:55:04<fracture>ohh now I get it... [] is a type constructor
17:55:05<Jedai>fracture: [] is not a data constructor, (:) is
17:55:09<fracture>got it
17:55:11<fracture>thanks
17:55:16<Jedai>fracture: right, [] is a type constructor
17:55:18<idnar>Jedai: [] is the data constructor for the empty list
17:55:39<Jedai>idnar: True, but it hasn't any arguments in this case
17:55:45<idnar>yeah
17:55:47<idnar>@src []
17:55:48<lambdabot>data [] a = [] | a : [a]
17:56:05<idnar>(that's not a "real" definition, but if there were one, that would be it)
17:56:14<fracture>ah
17:56:56<Jedai>fracture: Note that you can use operator as data constructor for your datatypes, as long as they start by :
17:57:08<fracture>ah
17:57:37<Jedai>@src Complex
17:57:37<lambdabot>data (RealFloat a) => Complex a = !a :+ !a
18:00:34<Jedai>jbjohns: with data-accessor, you can rewrite that "day ^: f $ dt"
18:01:10<jbjohns>ah, that's some kind of composition?
18:01:40<PeakerWork>Jedai: [] is both a type-constructor and a data-constructor (as evident in its appearing on the LHS and RHS of that data declaration)
18:02:14<Jedai>PeakerWork: Yep, I forgot the empty list at first
18:02:16<PeakerWork>oh, didn't read the whole thing, you acknowledged that
18:02:19<PeakerWork>sorry
18:02:37<AllNight^>how can I get ghc to show me what the current directory is? I know I can change it with :cd
18:03:00<AllNight^>ACTION just got haskell-mode working :D
18:03:22<Jedai>jbjohns: Yes, in this case it's not particularly interesting, but with longer field name and especially with nested records it makes all the difference in the world
18:03:50<jbjohns>it looks neat with this as well
18:04:03<Jedai>jbjohns: "state ^: date ^: day ^: (+1) $ gameState"
18:04:16<jbjohns>but yea, I can imagine that really helping a lot for nested structures
18:04:30<PeakerWork>Jedai: probably nicer to use a composed accessor, in the same sense a (.) chain is nicer than ($)
18:05:15<PeakerWork>and accessor composition could be done with (Control.Category..) (You might need to declare your own instance) so you could have: (state . date . day) ^: (+1) $ gameState
18:05:33<Jedai>PeakerWork: True, something like "state <: date <: day ^: (+1) $ gameState"
18:05:52<PeakerWork>except <: is silly because accessors should be Control.Category.Category :)
18:06:03<PeakerWork>and one can use (.) or (<<<)
18:06:21<PeakerWork>(much less operator names to remember!)
18:06:22<Jedai>PeakerWork: I guess so, but I don't think the instance is defined by default
18:08:27<Taejo>I'm trying to open an external editor from Haskell -- 'runProcess "vim" [fn] Nothing Nothing Nothing Nothing Nothing' seems to me to be the right thing, but vim complains "Vim: Error reading input, exiting..."
18:08:51<EvilTerran>Taejo, you may need to provide a handle for it to read as stdin
18:09:11<Taejo>EvilTerran: "Handle to use for stdin (Nothing => use existing stdin)"
18:09:36<EvilTerran>oh right, i was thinking Nothing meant that stdin would start closed.
18:10:53<PeakerWork>@hoogle runProcess
18:10:53<lambdabot>System.Process runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle
18:11:02<EvilTerran>AllNight^, :!pwd, perhaps?
18:11:25<AllNight^>yes that does it - thanks EvilTerran :)
18:11:37<PeakerWork>Maybe [Handle] would probably be nicer (stdin,stdout,stderr are just a convention, you may have more)
18:12:34<PeakerWork>@hoogle runProcess --info
18:12:34<lambdabot>System.Process runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle
18:12:34<lambdabot>
18:12:34<lambdabot>Runs a raw command, optionally specifying Handles from which to take the stdin, stdout and stderr channels for the new process (otherwise these handles are inherited from the current process).
18:12:53<PeakerWork>Taejo: is your "existing stdin" ok?
18:13:09<PeakerWork>what's the 2nd FilePath?
18:13:23<EvilTerran>ACTION didn't know @hoogle could do that! :o
18:13:28<Taejo>PeakerWork: I'm running the program from a terminal; the 2nd FilePath is the cwd
18:13:44<EvilTerran>PeakerWork, i think it's the name of the process image as it sees it itself
18:13:53<EvilTerran>... or that.
18:14:08<PeakerWork>I guess that would be the 2nd arg's (!!0)
18:18:37<frwmanners>join haskell-in-depth
18:18:38<lambdabot>frwmanners: You have 1 new message. '/msg lambdabot @messages' to read it.
18:21:00<frwmanners>Baughn: I seem to have got your message 7 days late
18:21:03<Athas>What's the easiest way to read a file as a list of Word32's?
18:21:46<PeakerWork>@hoogle FileHandle -> ByteString
18:21:46<lambdabot>Did you mean: Handle -> ByteString /count=20
18:21:46<lambdabot>Data.ByteString unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString
18:21:46<lambdabot>Data.ByteString.Lazy unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString
18:21:56<PeakerWork>@hoogle FileHandle -> IO ByteString
18:21:57<lambdabot>Did you mean: Handle -> IO ByteString /count=20
18:21:57<lambdabot>Data.ByteString unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString
18:21:57<lambdabot>Data.ByteString.Lazy unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString
18:22:22<frwmanners>Baughn: re filterE
18:23:04<alexsuraci>I'm getting this error when trying to build haskelldb-hsql: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5449#a5449
18:23:12<alexsuraci>related: http://hackage.haskell.org/packages/archive/haskelldb-hsql/0.10/logs/failure/ghc-6.10
18:23:38<alexsuraci>Is there any known fix for that?
18:23:42<PeakerWork>hoogle/hayoo really kind of suck on this search
18:23:44<Jedai>@hoogle Handle -> IO ByteString
18:23:44<lambdabot>Data.ByteString hGetContents :: Handle -> IO ByteString
18:23:44<lambdabot>Data.ByteString hGetLine :: Handle -> IO ByteString
18:23:45<lambdabot>Data.ByteString.Char8 hGetContents :: Handle -> IO ByteString
18:24:10<Jedai>PeakerWork: as suggested, Handle instead of FileHandle works better
18:24:15<PeakerWork>oh
18:24:18<PeakerWork>whoops
18:24:32<Jedai>Athas: using binary is probably the easiest way
18:24:33<PeakerWork>Athas: you can combine this with Data.Binary.Get
18:25:10<Athas>Yes, I tried using Data.Binary myself, but I think my attempt just consed up a huge list, without ever passing beyond the first four bytes in the file.
18:25:28<PeakerWork>Athas: How did you use it?
18:25:34<Athas>Additionally, Data.Binary seems hardcoded to use lazy bytestrings.
18:26:12<gwern>Athas: indeed
18:26:15<Athas>I can't remember. A recursive parser using getWord32be.
18:26:18<gwern>and binary-strict is a hack
18:26:33<PeakerWork>hmm.. ByteString should have been a class? :P
18:26:45<Athas>Is there a clean way to force the evaluation of the parser before my file handle is closed, in that case?
18:27:04<gwern>'Performance This was the real unknown. Performance on the prototype looked
18:27:05<gwern>good, but we did not know how it would scale. Other systems implemented in
18:27:05<gwern>Haskell, like Darcs (Roundy, 2005), have shown that performance can be an issue
18:27:05<gwern>in real-world workloads.
18:27:08<Athas>Perhaps I should just use Data.Binary.decodeFile?
18:27:19<gwern>auugh. I knew darcs would become a cited example of bad haskell performance -_-
18:27:25<PeakerWork>Athas: the doc says it just uses ByteString's readFile?
18:27:52<PeakerWork>gwern: is that a horrible thing?
18:28:05<gwern>PeakerWork: yes, it prevents people from swallowing our koolaid
18:28:24<PeakerWork>I don't know how much of darcs' bad performance was attributed to Haskell and how much to the logic, though
18:28:36<frwmanners>Baughn: looking at the new code, it's redundant
18:29:07<Baughn>frwmanners: How's that?
18:29:47<frwmanners>Baughn: So, the problem was Max (AddBounds t) as time in FutureG
18:30:02<Baughn>frwmanners: Er. Hang on, what?
18:30:04<Baughn>What new code?
18:30:04<gwern>' A surprising weakness was executable size,
18:30:08<gwern>with our executables coming in at 5 megabytes each. With several executables per
18:30:11<gwern>release, and several prototype releases running simultaneously, fpf turned out to
18:30:14<gwern>be unexpectedly disk hungry.
18:30:33<frwmanners>Baughn: reactive-0.11
18:30:37<gwern>' A combination of make (Feldman, 1979) and Perl (Wall & Schwartz, 1990) scripts
18:30:40<gwern>complete the build system infrastructure, including a program-level regression test
18:30:41<frwmanners>I think (???)
18:30:43<gwern>suite. Relatively mainstream tools were selected here to simplify maintenance.
18:30:43<Baughn>frwmanners: So that should be the unamb code..
18:30:45<gwern>-_-
18:30:54<Baughn>frwmanners: Um, I don't think I've got any code in reactive-0.11..
18:31:14<frwmanners>frwmanners: Sorry, you asked me to elaborate on something I said a week ago
18:31:20<Baughn>frwmanners: What I've been working on is unamb and TVal.hs. The latter is part of reactive, granted, but it isn't done yet..
18:31:21<frwmanners>^^^ Baughn
18:31:23<Baughn>Oh
18:31:31<Baughn>I'd completely forgotten about that
18:31:49<frwmanners>Baughn: I only remembered because the lambdabot just told me
18:32:01<frwmanners>Baughn: sorry for time / confusion
18:33:02<gwern>' The points-free approach, while
18:33:04<Baughn>It rolled out of my log, unfortunately. :/
18:33:06<gwern>elegant, can make code unreadable, especially if it is written by quantitative analysts
18:33:09<gwern>moonlighting as functional programmers.
18:33:26<Tsion>Hello, could someone with admin on lambdabot make it join #botters please?
18:33:32<gwern>@remember SimonFrankau The points-free approach, while elegant, can make code unreadable, especially if it is written by quantitative analysts moonlighting as functional programmers.
18:33:32<lambdabot>It is forever etched in my memory.
18:33:43<Athas>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5450#a5450 <- Why doesn't that work?
18:34:00<Athas>It just conses infinitely.
18:34:33<Baughn>frwmanners: But am I mistaken to think that implementing reactive for io-driven events will require the use of unsafePerformIO to grab the current time for the Ord instance of Improving?
18:35:02<PeakerWork>does Lazy Bytestring's file functions do unsafeInterleaveIO?
18:35:03<Baughn>frwmanners: Eg. when merging two Events
18:35:47<Taejo>@pl (\x -> not $ (x `inDB` db) || ("#" isPrefixOf x))
18:35:48<lambdabot>not . liftM2 (||) (`inDB` db) isPrefixOf
18:36:09<Baughn>frwmanners: "Event a's first occurence is at 1.5 seconds. Event b's first occurence is unknown, but will get timestamped when it happens. We can wait until either (a) it happens, or (b) its clock says 1.5 seconds too, in which case a is first
18:36:37<Baughn>...oh god, the horror
18:36:48<frwmanners>Baughn: I'd agree with that, but I'm now confused
18:36:55<Taejo>hang on, that's not right
18:36:57<int-e>Athas: what are you expecting it to do? and what are you reading?
18:37:02<Taejo>@pl (\x -> not $ (x `inDB` db) || (['#'] isPrefixOf x))
18:37:03<lambdabot>not . liftM2 (||) (`inDB` db) isPrefixOf
18:37:05<Taejo>ack
18:37:13<Taejo>@pl (\x -> not $ (x `inDB` db) || ("#" `isPrefixOf` x))
18:37:15<lambdabot>not . liftM2 (||) (`inDB` db) ("#" `isPrefixOf`)
18:37:34<gwern>' The preferred solution would be developers more ex-
18:37:37<gwern>perienced in Haskell, but the combined Haskell and financial knowledge is rather
18:37:40<gwern>rare, and it seems that even a relatively inexperienced Haskell programmer can be
18:37:43<PeakerWork>Athas: do you want lazy I/O? Do you mind if the entire file is read immediately?
18:37:43<gwern>more productive than an experienced C++ programmer in domains such as ours.
18:37:59<gwern>' Should in-process operation be required in the
18:38:03<gwern>future, a com interface can be integrated (Finne et al., 1999).
18:38:04<gwern>the fools! the poor fools!
18:38:10<duaneb>goddamn
18:38:12<duaneb>I hate parsing
18:38:15<Athas>int-e: I would expect it to read a list of Word32s from a file (sequentially, I suppose). And no, I have no strictness requirements.
18:38:32<PeakerWork>duaneb: why not use a Haskell DSL then?
18:38:32<duaneb>Only networking and database theory is a more evil field of computer science
18:38:42<duaneb>PeakerWork: because I need to parse :P
18:38:49<PeakerWork>duaneb: what needs parsing? :(
18:38:50<Wraithan>Ok, I am writing a client for todoist, their API returns JSON objects and I can get the JSON object into a object I could potentially use but I have no clue a to how I would get the data I need from it: http://www.moonpatio.com/fastcgi/hpaste.fcgi/view?id=2532
18:39:03<duaneb>PeakerWork: s expressions
18:39:06<Baughn>frwmanners: You're not the only one. I'll need to break referential transparency to implement this.
18:39:06<duaneb>homework :/
18:39:31<Taejo>what characters do I need to escape to make a string into a regex that matches itself?
18:39:32<Wraithan>I would like to grab the api_token value (along with others) but it seems like a rather complicated object to reach in and just grab that data
18:39:42<Baughn>frwmanners: Hopefully in a safe manner, exporting a referentially transparent /interface/, but.. oh my, I see why reactive has provoked RTS bugs
18:40:00<frwmanners>Baughn: I'm happy to think of the eventual goal (futures) as a fairly reasonable extension of the language's semantics
18:40:15<int-e>Athas: well, the list instance reads a word from the file, treats it as the length of the returned list, and then reads that many words. and decodeFile is strict so it won't return any data before the whole list is read.
18:40:25<gwern>Wraithan: wouldn't it be something like 'api_token $ r'?
18:40:32<frwmanners>Baughn: but I agree, that makes implementing it using current methods sort of unpleasant
18:40:44<gwern>Wraithan: since each field of a record has a getter function defined of the smae name
18:41:21<Wraithan>gwern: ok, so how would I access those getter fuctions?
18:42:26<gwern>Wraithan: or, looking at http://hackage.haskell.org/packages/archive/json/0.4.3/doc/html/Text-JSON-Types.html#v%3AfromJSObject
18:42:31<gwern>why not use get_field ?
18:43:00<gwern>offhand, it looks like 'get_field r "api_token"' might work?
18:43:03<frwmanners>Baughn: fyi, my original concern was that AddBounds (Improving t) hides all information when we don't know whether the occurrence is finite or not
18:43:30<frwmanners>Baughn: Improving (AddBounds t) is better; but as I say, this has already been done
18:44:58<Taejo>how do I delete a file from a Haskell program?
18:45:07<mauke>@hoogle removeFile
18:45:07<lambdabot>System.Directory removeFile :: FilePath -> IO ()
18:45:15<gwern>Taejo: too vague; say more
18:45:15<Taejo>thanks, mauke
18:46:01<Taejo>the web version of hoogle finds no results for removeFile (I already guessed that name)
18:47:19<int-e>Athas: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5450#a5452 may work better for you
18:47:44<int-e>Athas: where 'all' should be 'allWords'
18:48:08<Athas>int-e: thanks, I will try it out.
18:48:26<int-e>Athas: and 't' too. (darn. I should test the code after renaming an identifier twice)
18:50:12<cads_>the set C of infinite sequences of binary digits is searcheable. That means that in finite time, we can either return an element of it that satisfies a certain predicate, or say that the element does not exist in C.
18:50:24<cads_>this is a pretty shocking statement to me
18:50:30<Wraithan>Is there any way to strip that left and right crap off so I don't have to worry about both sides of the case returning the same value? just want to simplify things so I can get to actually trying to figure out how to do this, rather than running into typing issues because one side of a case returns something different (when I am just using it to strip left/right)
18:50:32<cads_>are you guys familiar with this result?
18:51:05<int-e>cads_: the point is that the predicate must be computable.
18:51:14<cads_>Exhaustible Sets in Higher-Type Computation: http://arxiv.org/abs/0808.0441
18:51:31<Twey>cads_: Of course it's true
18:51:50<int-e>http://www.cs.bham.ac.uk/~mhe/papers/seemingly-impossible.html
18:52:15<Twey>Up to any given element, the set is finite
18:52:41<PeakerWork>cads_: you're searching a finite element of it -- if you sort the infinite sequences by length, its enough to get to a higher-lengthed one than the one you search?
18:52:51<cads_>int-e: I was wondering how a function of infinite rank could be used as our predicate and still preserve searcheability
18:53:06<hackagebot>MonadCatchIO-mtl 0.2.0.0
18:54:00<yitz>hackagebot?
18:54:18<yitz>that's nice.
18:54:27<mauke>not nice enough
18:54:36<yitz>mauke?
18:54:39<mauke>it should use CTCP ACTIONs to announce stuff
18:54:47<cads_>so, Twey, I can't use this to create a representation of the binary number equal to the square root of two, for example?
18:55:31<Twey>Of course — that's irrational and is itself infinite
18:55:56<cads_>but it's a computable real
18:56:20<cads_>that is, there are reals that can't even be defined by a finite computational rule
18:57:17<Wraithan>@hoogle JSValue -> JSObject
18:57:17<lambdabot>Warning: Unknown type JSValue
18:57:18<lambdabot>Unsafe.Coerce unsafeCoerce :: a -> b
18:57:18<lambdabot>Prelude ($) :: (a -> b) -> a -> b
18:58:06<Wraithan>@hoogle Text.JSON.JSValue -> Text.JSON.JSObject
18:58:06<lambdabot>Parse error:
18:58:07<lambdabot> --count=20 "Text.JSON.JSValue -> Text.JSON.JSObject"
18:58:07<lambdabot> ^
18:58:13<Wraithan>bleh
18:58:22<crem>listAvg x = ( fromIntegral $ sum x ) / ( fromIntegral $ length x ) -- why do I need the second pair of parentheses?
18:58:27<cads_>hmm, I think I'll implement the algorithm in the paper and see what it gives me to play with
18:58:48<Jedai>@hoogle JSValue -> JSObject +json
18:58:48<lambdabot>Could not find file:
18:58:48<lambdabot> json
18:58:48<lambdabot>Searched:
18:58:56<int-e>Wraithan: pattern match on the JSObject constructor?
18:59:05<EvilTerran>crem, because / is tighter binding than $
18:59:10<Wraithan>int-e: huh?
18:59:15<crem>EvilTerran, thanks.
18:59:34<Wraithan>@hoogle String -> JSObject
18:59:35<lambdabot>Warning: Unknown type JSObject
18:59:35<lambdabot>Prelude error :: String -> a
18:59:35<lambdabot>Debug.Trace trace :: String -> a -> a
18:59:35<Jedai>Wraithan: http://www.haskell.org/hoogle/?hoogle=JSValue+-%3E+JSObject+%2Bjson
18:59:36<yitz>@info (/)
18:59:36<lambdabot>(/)
18:59:57<int-e>Wraithan: case jsvalue of JSObject jsobject -> jsobject; _ -> error "not an object"
18:59:58<yitz>urgh, no fixity info.
19:00:20<EvilTerran>@recall @info
19:00:20<lambdabot>Unknown command, try @list
19:00:21<cads_>aaack
19:00:26<EvilTerran>@quote @info
19:00:26<lambdabot> @info says: typo-corrects to @undo. it isn't a real command.
19:00:33<cads_>the predicate must be total
19:01:14<cads_>ACTION had really wanted to believe the stronger version he'd imagined
19:02:08<Jedai>cads_: Well if it takes infinite time to return, it sure won't find the searched element in finite time...
19:02:48<Baughn>cads_: Well, I dare say an incomputable predicate won't be very useful on a computer..
19:03:00<Baughn>Or anywhere in this universe, really
19:03:05<Heffalump>oh, hi kowey
19:03:10<Heffalump>I was just trying to email you, one-handed
19:03:23<Heffalump>The Darcs wiki used to have links like
19:03:23<Heffalump>http://wiki.darcs.net/index.html/Foo
19:03:23<Heffalump>and
19:03:23<Heffalump>http://wiki.darcs.net/DarcsWiki/Foo
19:03:23<Heffalump>(a) the front page of http://darcs.net points to these old URLs
19:03:25<cads_>Baughn: hyper-turings? :D
19:03:28<Baughn>ACTION wonders why join isn't part of the Monad class
19:03:35<Jedai>cads_: What was your stronger version like ? I can't really imagine
19:03:42<Heffalump>(b) we should probably use Apache redirect rules to deal with other links we don't know about
19:03:42<Baughn>cads_: Aren't incomputables beyond even them
19:03:45<gwern>@src join
19:03:45<lambdabot>join x = x >>= id
19:04:01<Baughn>cads_: No matter. Current physical law says the universe is turing-computable.
19:04:03<gwern>Baughn: if it can be defined using just the existing monadic typeclass, why add it?
19:04:08<cads_>:)
19:04:12<kowey>Heffalump: oh, yes
19:04:13<EvilTerran>Baughn, for the same reason Functor isn't a superclass of Monad?
19:04:18<Heffalump>sorry, wrong channel!
19:04:21<Heffalump>ACTION --> #darcs
19:04:30<Baughn>gwern: Because you can also define >>= in terms of join and fmap, and it's often easier to do it that way around
19:04:37<EvilTerran>gwern, but in some circumstances, it'd be nice to be able to define a monad in terms of fmap/join/return instead of >>=/return
19:04:38<cads_>I think the point of hyper-turings is to compute with complete real numbers or higher cardinalities
19:04:53<Jedai>gwern: to have specialized version (and we could have default definition for >>= in function of join and vice-versa
19:05:08<Baughn>gwern: Plenty of libraries first define join, then go on to implement >>= in terms of join, then have of course join in terms of >>=...
19:05:19<Baughn>That's not including reactive, which has >>= in terms of join and join in terms of >>=
19:05:43<Baughn>In that case it's the /same/ join. Knot-tying for the win? ^^;
19:05:53<EvilTerran>O.o
19:06:05<ray>join join fmap fmap fmap fmap join
19:06:21<EvilTerran>?type join join fmap fmap fmap fmap join
19:06:22<lambdabot> Occurs check: cannot construct the infinite type:
19:06:22<lambdabot> t = t -> t -> t1 -> t2 -> t3 -> t4 -> t5
19:06:22<lambdabot> Probable cause: `join' is applied to too few arguments
19:06:32<Baughn>Anyway, statements like " e >>= f = joinE (fmap f e)" are very common in monad instances..
19:06:33<EvilTerran>... actually, i think it's applied to too many. :P
19:06:36<cads_>Jedai: I thought we were somehow able to quantify over the binary numbers that have computable expressions in terms of partial fractions or something like that
19:06:49<ray>yeah, i'm just beatboxing
19:07:07<ray>:k Join
19:07:08<lambdabot>Not in scope: type constructor or class `Join'
19:08:26<cads_>that set would be compact in C
19:09:06<duaneb>could someone help me with my s-expr parser?
19:09:06<duaneb>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5453#a5453
19:09:07<cads_>or {0, 1}^|N|
19:09:11<duaneb>specifically parseCons
19:09:16<duaneb>There are two type errors
19:09:17<opqdonut>cads_: which set?
19:09:26<duaneb>at lines 42 and 47
19:09:32<duaneb>and I can't figure it out :/
19:09:44<cads_>the set of binary numbers generated by algorithms of finite length
19:09:53<opqdonut>ah
19:10:30<opqdonut>how would it be compact in {0,1}^N
19:10:49<duaneb>well
19:10:54<duaneb>I've figured out the problem
19:10:58<duaneb>I just don't know why it exists
19:12:08<Baughn>conal: I think I've figured out how to fix makeEvent. You had, of course, covered it in the paper, but you know about information which man was not meant to know? This is some of it.
19:12:13<Baughn>ACTION quietly goes insane
19:12:19<duaneb>anyone? :|
19:12:19<cads_>opqdonut: I think you could write a sequence of generated numbers approaching any incomputable number, as their generator algorithms tended towards infinite length
19:12:41<EvilTerran>duaneb, i think, around line 42, you need "case endMaybe of Just _ -> return Null; Nothing -> parseLispType ..."
19:12:46<Baughn>duaneb: Ah, add the type errors as a revision please
19:12:51<cads_>but that actually seems like it could be disastrously bad intuition on by part :)
19:12:53<Jedai>duaneb: are you aware that they're a tutorial that show you step by step how to write a parser (with Parsec) and interpreter for Lisp in Haskell ?
19:13:03<Jedai>*there is
19:13:04<duaneb>Jedai: yea, I don't like their parsing :P
19:13:06<EvilTerran>duaneb, and similarly around 47, i suspect
19:13:17<Jedai>duaneb: Oh, ok... :D
19:13:21<opqdonut>cads_: hmm, what was the criterion for sequentially compact <=> compact
19:13:27<opqdonut>cads_: was it hausdorff or T3?
19:13:37<duaneb>EvilTerran: isn't that what I wrotE?
19:13:40<duaneb>wrote*
19:14:11<EvilTerran>duaneb, i mean, the second branch is already a monadic action, so shouldn't be wrapped in a "return"
19:14:16<cads_>opqdonut: well for example the rational numbers are compact in the reals, even though they're countable. This is because between any two reals there's still a rational
19:14:27<EvilTerran>duaneb, so you should float the "return" wrapping the case to inside it
19:14:46<duaneb>EvilTerran: ok, but why?
19:14:51<EvilTerran>(and only to the Just/Null branch)
19:15:05<EvilTerran>duaneb, the type of >>=
19:15:07<EvilTerran>?type (>>=)
19:15:09<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
19:15:20<EvilTerran>the RHS has to result in a monadic value
19:15:25<opqdonut>cads_: my point was, there are sequentially compact (=> each sequence has a limit) spaces that are not compact (=> each open cover has a finite subcover)
19:15:48<EvilTerran>duaneb, in parseLispType >>= (\t -> Cons t parseCons'), you're not doing that
19:16:46<EvilTerran>duaneb, and, re-writing that to, say "liftM (`Cons` parseCons) parseLispType", that's also a monadic action
19:16:47<duaneb>ah, nm
19:16:48<duaneb>figured out
19:16:51<EvilTerran>duaneb, so you don't need to wrap it in return
19:17:06<duaneb>EvilTerran: no, the problem was I was passing Cons a monad
19:17:10<duaneb>instead of what was in the monad
19:17:21<duaneb>(parseCons' instead of what was in parseCons')
19:17:39<EvilTerran>uh
19:17:42<Jedai>duaneb: The objective of return is to lift an ordinary value into the monad, here the second branch of the case isn't an ordinary value but monadic (it's also different from the type of the first branch of the case which is an obvious error)
19:17:45<cads_>opqdonut: hmm, sec while I open my analysis book :)
19:17:50<EvilTerran>duaneb, parseLispType >>= (\t -> Cons t parseCons') still isn't going to work
19:17:57<EvilTerran>even if you deal with parseCons'
19:18:19<opqdonut>cads_: in metric spaces sequential compactness is the same as compactness, but not generally in topological spaces
19:18:30<opqdonut>cads_: however, there was a simple criterion for when they are the same
19:18:52<EvilTerran>because (>>=) :: Parser a -> (a -> Parser b) -> Parser b, and (Cons ...) does not fit "Parser b"
19:19:05<duaneb>ah.
19:19:20<EvilTerran>?type liftM
19:19:21<duaneb>I still don't get why putting the return inside each of the cases would help....
19:19:21<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
19:19:37<duaneb>the `case` type SHOULD be LispType
19:19:53<Jedai>duaneb: it won't be sufficient, but at least both branch of the case will have the same type
19:19:55<EvilTerran>duaneb, you're doing monadic stuff in one branch of the case
19:20:10<EvilTerran>duaneb, and "return (...)" has no monadic side-effects
19:20:22<duaneb>ahh, never mind
19:20:26<duaneb>I figured it out
19:20:59<Jedai>duaneb: the second branch should be something like do { lt <- parseLispType; c' <- parseCons'; return (Cons lt c') }
19:21:22<cads_>opqdonut: bleh, I can't make {0,1}^|N| into a metric space
19:22:09<cads_>wait yes i can
19:25:19<cads_>p(a, b) = sum (a_k + b_k)/2^k. a, b in {0,1}^|N|
19:26:02<conal>Baughn: glad to hear you're making progress. there's a lot packed into that paper. easy to miss things.
19:26:11<_JFT_>Is there some prescribed way to mix State and ST monads? Or is that a general don't? I have a specific application where I need to hold a few tables of "record" which are actually references. There are cyclical references.
19:26:46<_JFT_>So I was thinking of using an State monad for the topology containing the various tables and entry points
19:27:03<_JFT_>in these tables are record containing STRef
19:28:19<Baughn>conal: This time I'm carefully writing tests as I find problems, and coupling them to cabal test. I estimate the probability of this breaking in a future GHC update at 80-something percent.
19:28:36<int-e>_JFT_: StateT state (ST s) should work fine as a monad. Or you could store the state in an STRef.
19:29:18<_JFT_>int-e: I wanted to avoid stocking that state in an STRef since I want need to stack many maniupulation and wanted to avoid manually threading that state
19:29:49<Jedai>_JFT_: Then StateT state (ST s) should be perfect, no ?
19:30:06<int-e>_JFT_: or, meet in the middle, ReaderT (STRef s state) (ST s)
19:30:14<_JFT_>int-e: interesting...
19:30:33<duaneb>ok
19:30:38<duaneb>I got my sexpr working
19:30:39<duaneb>but
19:30:40<_JFT_>int-e: thanks for the ReaderT (STRef s state) (ST s) very clever!
19:30:47<_JFT_>int-e: I am going to try that route :)
19:30:55<duaneb>if there's trailing text, my parser ignores it
19:31:06<conal>Baughn: thanks a bunch for the tests! please include them in your next darcs patch. when unamb gets solid and efficient, i predict people will come up with lots of cool uses.
19:31:15<mauke><* eof
19:31:20<Jedai>duaneb: put eof at the end of your parser
19:33:12<duaneb>Jedai: yea, just figured that out :P
19:33:19<_JFT_>int-e: the part that was bugging me is how do I eval a combination of State and ST if 2 or more field of my state are ST s...
19:33:43<_JFT_>int-e: using the ReaderT approach i.e. should bypass that issue
19:34:17<hackagebot>uu-parsinglib 2.1.0
19:37:18<int-e>hackagebot should sat 'new package:' or something like that in addition to the package name.
19:38:09<mauke>hackagebot should /nick hackage and announce things in the format /me upload: uu-parsinglib 2.1.0
19:47:26<bakesz>hi guys!is there some way to look into a function,which is made by another function?(sorry for my english).thanks for help
19:48:07<Twey>Template Haskell says yes.
19:48:33<ray>templatehaskellsayswhat?
19:49:00<IRZ>hi
19:49:04<IRZ>can u have two foreign keys for one table (each with multiple columns) pointing to the same table.
19:49:44<Heffalump>IRZ: Haskell isn't a database
19:50:17<Botje>bakesz: "look into a function" ?
19:50:57<IRZ>i cant find an answer to my question, so i thought i would ask here
19:51:01<IRZ>wha tis haskel exactly ?
19:51:08<IRZ>alot of people in thsi room
19:51:09<Heffalump>it's a programming language
19:51:15<IRZ>i guessed that
19:51:25<IRZ>but umm whats it predominantly used for
19:51:32<Heffalump>there's URLs in the topic you can use to find out about it
19:51:49<tux_rocker>http://en.wikipedia.org/wiki/Haskell ?
19:51:57<IRZ>was looking for a one sentece answer
19:51:59<IRZ>i dotn really care
19:52:07<IRZ>thx tho
19:52:34<tux_rocker>does anyone know a way to serialize a System.Random.StdGen?
19:52:42<kynes>hi, I have a question about Test.QuickCheck
19:52:49<Heffalump>tux_rocker: it's just a pair of Integers, isn't it?
19:52:49<tux_rocker>there's Read and Show instances but they're asymmetric
19:52:55<Heffalump>that sucks
19:53:12<tux_rocker>Heffalump: it is, but you can't build a StdGen straight from the pair of integers
19:53:30<tux_rocker>kynes: alright, go ahead
19:53:30<Heffalump>I think asymmetric Read/Show is a bug.
19:53:46<kynes>it generates objects having random values to check a property, the question is, can I get these temporary objects ? I mean I want to report them
19:54:12<tux_rocker>kynes: you could use Debug.Trace in the code of your tests
19:54:13<kynes>tux_rocker, is there a way to see the object during the check ?
19:54:24<kynes>tux_rocker, can you give an example usage ?
19:54:37<kynes>tux_rocker, thank you btw
19:54:42<Heffalump>I think QuickCheck 2 might have hooks to help with this
19:55:51<bakesz>Botje: i mean like this: let sum_nums w=if w==0 then 0 else (\f x -> (f (x-1)) +x ) sum_nums w
19:55:52<tux_rocker>Heffalump: I see no hooks on a quic first glance
19:56:14<Heffalump>fair enough
19:56:18<bakesz>it generates function to every input argument,and i would like to see it
19:56:44<Botje>you can't print functions
19:57:24<bakesz>that's sad.
19:57:28<Botje>bakesz: you could put a trace inside that anonymous lambda, though
19:57:47<Botje>import Debug.Trace
19:57:48<tux_rocker>kynes: import Debug.Trace\nprop x y = trace ("x = " ++ show x ++ ", y = " ++ show y) $ x == y || x /= y\nmain = quickCheck prop
19:58:00<tux_rocker>kynes: replace \n by newline
19:58:24<Botje>let sum_nums w = if w == 0 then 0 else (\f x -> trace (show x) $ f (x-1) + x) sum_nums w
19:58:35<kynes>tux_rocker, thanks!
19:58:38<Botje>of course that fragment is pretty contrived
19:58:58<Botje>why bother with the lambda if you're going to apply it sitrectly after ...
19:59:15<Botje>let sum_nums w = if w == 0 then 0 else sum_nums (x-1) + x
19:59:23<Botje>err
19:59:28<Botje>let sum_nums w = if w == 0 then 0 else sum_nums (w-1) + w
19:59:52<Botje>and then you might use pattern matching
20:00:39<Twey>let sum_nums 0 = 0; sum_nums w = sum_nums (w - 1) + w
20:01:35<bakesz>sorry,what does "contrived" mean,because my dictionary doesn't find it
20:01:47<Botje>really really awkward and un-haskelly
20:01:58<Botje>not code any sensible person would write
20:02:42<bakesz>thank you
20:02:47<Wraithan>@type Text.JSON.decode
20:02:47<Tsion>arg
20:02:48<lambdabot>Couldn't find qualified module.
20:02:56<dolio>In general it means made-up and unrealistic.
20:03:01<Tsion>14:02:29 <@Tsion> @run 1 + 1
20:03:01<Tsion>14:02:31 <lambdabot`> L.hs:3:29: Module `Control.Arrow' does not export `pure'L.hs:3:29: Module `...
20:03:07<Tsion>my lambdabot won't work :/
20:03:10<tux_rocker>correction of myself: read/show for StdGen are not asymmetric
20:03:19<Wraithan>Bleh, anyway, it returns a Result a, how I do I get the value from the result/
20:03:22<tux_rocker>my program needed a type signature somewhere to work correctly
20:03:49<luqui>i'd like some help on the design of a library
20:04:25<luqui>i'm writing a proof tactics library, where a tactic takes a theorem and attempts to find a proof
20:04:27<trofi>Tsion: try remove hiding (pure) from L.hs
20:04:33<Tsion>trofi: It's not there
20:04:37<luqui>er, takes a statement and ...
20:04:43<trofi>Tsion: ~/.lambdabot/L.hs
20:05:05<luqui>but i would like the code that decides how to find the proof to be overloaded in some respect
20:05:07<Tsion>trofi: Whoa, thanks
20:05:20<Tsion>I was changing it in the source and recompiling
20:05:21<luqui>i.e. allowed to do I/O, or talk to an external context, etc. (not committing to any particular one)
20:05:44<luqui>but i don't want it to be able to return an invalid proof, so the "primitive constructors" are restricted
20:05:45<luqui>any ideas?
20:05:50<luqui>does that make sense?
20:06:00<_JFT_>int-e: can I bug you for one more question? I am trying to eval my ReaderT ST monad stack...
20:06:07<Wraithan>decode :: JSON a => String -> Result a -- How do I get the value of a? I am doing really bad at this haskell stuff so far lol
20:06:20<PeakerWork>luqui: hey.. Is this for an interactive theorem prover?
20:06:33<PeakerWork>luqui: or do you want to let your language's programs partially prove stuff?
20:06:41<PeakerWork>luqui: (and allow automated proof for the rest)
20:06:45<maltem>findProof :: (Monad m) => Tactic m a -> m (Proof a) -- ?
20:06:46<int-e>_JFT_: yes
20:06:47<luqui>PeakerWork, possibly-interactive. i.e. interactivity is one of the ways to instantiate it
20:07:09<PeakerWork>I don't think findProof can/should be in a polymorphic monad
20:07:31<_JFT_>int-e: thanks I could paste the code if you can get a look at it please
20:07:33<maltem>Fair enough
20:07:57<luqui>PeakerWork, well I'd like some way to communicate the proof context to the user from within the library
20:08:05<luqui>yeah, partiality is acceptable
20:08:17<PeakerWork>luqui: proof :: Theorem -> ErrorT ProofFailure IO Proof -- where Proof is represented in a form that is always valid?
20:08:26<luqui>I don't want IO in the type
20:08:29<PeakerWork>luqui: I guess it might be proving some *other* theorem, heh
20:08:36<luqui>right, that too
20:08:46<_JFT_>int-e: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2533#a2533
20:08:53<PeakerWork>luqui: so you do want the Monad to be polymorphic, as per maltem's suggestion?
20:08:56<luqui>so the primitive combinators only allow proofs of what you're actually trying to prove
20:09:24<luqui>PeakerWork, I think so...
20:09:27<PeakerWork>luqui: Sounds impossible in Haskell (that the type will guarantee that the result proof is of that theorem), but maybe I'm wrong
20:09:30<luqui>maltem, what is this a?
20:09:41<luqui>PeakerWork, should be possible using some variant of certificate
20:09:46<luqui>i just can't figure out that variant
20:09:50<PeakerWork>luqui: what's that?
20:09:51<_JFT_>int-e: I understand the problem is with my "s" state thread variable
20:10:04<luqui>restricting the constructors you expose only to allow valid proofs
20:10:18<_JFT_>int-e: but I have no idea how to fix it ( I guess I have to quantify it? forall s. etc?)
20:10:19<maltem>luqui, no idea, I thought you may want to put something resultish in there
20:10:27<PeakerWork>luqui: but they don't only have to be valid proofs, they also have to be proofs of some other argument
20:10:33<luqui>like, modusPonens :: Proof -> Proof -> Maybe Proof
20:10:55<PeakerWork>luqui: (of some theorem
20:11:23<_JFT_>int-e: I added missing part at the top http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2533#a2534
20:11:33<luqui>PeakerWork, well, yeah, that's the challenge. Thus exposing the type as a plain function isn't an option
20:11:49<luqui>i.e. Term -> Proof is no good, because that's allowed to return proofs that are not proofs of that term
20:11:57<luqui>so instead it's got to be an abstract type Tactic
20:12:04<luqui>whose structure I cannot figure out...
20:12:58<luqui>like, basic tactic combinators are easy. the problem is shoving that monad/whatever in there
20:13:06<PeakerWork>luqui: the caller can always validate the proof :-)
20:13:10<luqui>so that it can make decisions based on the context
20:13:19<luqui>PeakerWork, don't want them to have too
20:13:21<luqui>*to
20:14:06<luqui>i have a hunch that if it's guaranteed *locally* correct, then it will be easy to verify
20:14:07<int-e>_JFT_: give a type signature: evalTopology :: (forall s . Topology s v f a) -> a
20:14:08<luqui>formally
20:14:46<_JFT_>int-e: thank you VERY much :) I haven't played much with ST and constantly get into problem with the "s" :(
20:15:30<int-e>_JFT_: (requires Rank2Types or RankNTypes) The error message basically means that 'runST' wants to fix the type of 's' itself, but can't, because it's already fixed by the (inferred) type signature of evalTopology.
20:16:35<PeakerWork>luqui: can you show for example, some basic tactic combinators?
20:16:56<_JFT_>int-e: I read your explanation "loud and clear" but the original message wasn't as clear ;) I'll read it back with you interpretation! Thanks again!
20:18:25<luqui>PeakerWork, intro (\h -> assumption h) -- proves eg. A -> A
20:18:51<luqui>but i'd like to be able to: intro (\h -> interactive)
20:19:16<luqui>er, mentioning h in interactive so that it can add it to the context
20:20:31<_lilian_>ouvindo ( Francesco Napoli - Balla Balla.mp3 ) .: kikøscript :. http://kikoscript.blogspot.com
20:20:51<luqui>my intended usage may be flawed, too...
20:35:37<bnijk>http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=ghc&lang2=gnat&box=1 <-- ????
20:35:46<bnijk>what's with the memory use
20:48:38<mux>rah
20:48:39<mux>atsui!
20:49:09<Twey>Atsusugi :(
20:49:55<shapr>AKIRA!
20:50:03<mxc>nihon kara dete!
20:50:15<mxc>nihon no natsu ga taihen dane!
20:50:31<Jedai>bnijk: ? What's the problem ? Except the Mandelbrot bench, the factor compared to ADA are quite normal and even for the mandelbrot, the memory usage isn't that far fetched
20:50:40<shapr>Jag har ingen aning vad du säger!
20:51:01<xian>shapr: I have no idea what you say?
20:51:02<shapr>Minä haluan hampurilainen!
20:51:23<shapr>xian: Yup, you got the Swedish correct, now can you translate the Finnish?
20:52:19<Chile`>is there a common method of doing substring replaces in haskell? there doesn't seem to be a standard one, unless I'm just missing it in the docs
20:52:21<xian>shapr: Wow, Swedish is really similar to German :) As to the Finnish, I happen to know that minä means ``I'', so I guess it's also something along "I have no idea"
20:52:54<RayNbow>mxc: why use romaji? :p
20:52:58<shapr>xian: Actually I said "I want a hamburger."
20:53:13<shapr>xian: joda, svensk är mycket lika som tysk.
20:53:31<shapr>xian: Talar du tysk?
20:53:36<RayNbow>@users
20:53:37<lambdabot>Maximum users seen in #haskell: 658, currently: 601 (91.3%), active: 19 (3.2%)
20:54:01<xian>shapr: Yeah, that's my native language.
20:54:26<shapr>kul :-)
20:54:42<shapr>My native language is Southern. I'm from Alabama.
20:54:57<mxc>raynbow - does IRC support unicode?
20:55:06<mxc>テスト
20:55:17<mxc>試験
20:55:24<mxc>well, i see that, not sure if anyone else does
20:55:30<shapr>I see it.
20:55:58<xian>shapr: Ah, I see. It's interesting to know that there are Swedish speakers in AL.
20:56:05<Jedai>Chile`: not really
20:56:10<shapr>xian: I learned Swedish at the same time my German/French fiancee was learning it, she learned Swedish very quickly.
20:56:28<shapr>xian: Well, I'm in Boston these days, but I'm sure there must be at least one or two Swedish speakers in AL.
20:56:43<shapr>xian: Are you in Boston? Want to hang out?
20:56:53<Jedai>Chile`: it's not too hard to cook one for your specific need most of the time though
20:57:08<RayNbow>mxc: as long as two persons use the same appropiate encoding, they can use unicode over IRC
20:57:25<shapr>Sadly, IRC dös not specify an encoding.
20:57:33<shapr>So most channels choose one.
20:57:36<Chile`>Jedai: no, it's not difficult at all, but every time I rewrite something that fundamental i cringe a little bit :)
20:57:40<Jedai>mxc: I see it (assuming you see the same as me)
20:57:45<shapr>Er, most channels that aren't ASCII.
20:57:52<mxc>for some reason, i imagined that the irc servers would mangle it
20:58:07<xian>shapr: I'd love to, but for now it seems as if I'm stuck in Germany.
20:58:13<shapr>Well, you should come visit!
20:58:13<mxc>although, i guess if its UTF-8, there aren't any \0's in leading bytes
20:58:34<Jedai>Chile`: I agree that it's annoying, maybe someone should just put a module with some traditional variants on hackage
20:58:57<shapr>Jedai: Good idea! Go for it!
20:59:11<Jedai>shapr: I just may :)
20:59:13<wli>ACTION would love to be stuck in Germany
20:59:36<RayNbow>ACTION wouldn't :p
21:00:17<RayNbow>(but that's because I haven't practiced German in a long while)
21:02:24<monochrom>IRC is neutral to "does it support unicode or not". Two humans conversing with each other decide what the bytes mean.
21:03:33<monochrom>My stand is I insist on UTF-8 and you can bite me.
21:06:09<RayNbow>ACTION recently had a small UTF8 problem :p
21:08:40<RayNbow>(when I replaced xmonad with xmonad-darcs... xmobar was no longer displaying text correctly... replacing System.IO.UTF8.hPutStrLn with hPutStrLn in my config fixed it :p)
21:23:42<Chile`>kind of a best practices question.. is monadic parsing actually used in practice, or would basically everyone use Happy or such?
21:23:58<augustss>I wouldn't
21:24:04<augustss>use happy
21:24:04<Heffalump>I think most people use parser combinators
21:27:07<mmorrow>Chile`: mostly happy's used for language parsers and parser combinators for smaller stuff
21:27:08<luqui>though people seem to be moving toward applicative style
21:27:23<skorpan>is it okay to call constructors functions if the context makes it clear that they are indeed constructors?
21:27:57<luqui>skorpan, do you mean "is it okay to call functions constructors if ..." ?
21:28:09<skorpan>no, i meant what i said :)
21:28:13<luqui>constructors *are* functions
21:28:16<PeakerWork>luqui: can an Applicative parser be optimized in ways that a monadic parser can't?
21:28:23<luqui>PeakerWork, yeah
21:28:24<skorpan>yes, i know
21:28:35<skorpan>i'm just not sure whether it's a generally accepted fact
21:28:42<PeakerWork>luqui: I thought the fact applicatives were parameterized over functions destroyed that
21:29:26<Chile`>mmorrow: makes sense, I'll stick to that
21:29:43<luqui>PeakerWork, i'm no expert, but I think there are some optimizations possible
21:29:48<luqui>not *all* the context-free ones, though
21:31:03<mmorrow>Chile`: (and you usually use a monad along with happy, although you don't necessarily have to)
21:31:07<peanuts>i have a beginner question about my implementation of quicksort for list of lists, maybe someone could give me a pointer
21:31:21<peanuts>i'm getting a non-exhaustive pattern error
21:31:29<luqui>peanuts, paste
21:31:34<luqui>if you please
21:31:56<Chile`>mmorrow: alright. I haven't looked at happy at all past knowing of it's existence.
21:31:56<peanuts> sortLists :: Ord a => [[a]] -> [[a]]
21:31:56<peanuts> 8 sortLists [[]] = [[]] -- pattern matching instead of "null"
21:31:56<peanuts> 9 sortLists (x:xs) = sortLists shorterOnes ++(x:sortLists longerOnes)
21:31:56<peanuts> 10 where
21:31:56<peanuts> 11 shorterOnes = [y | y <- xs, length y < length x ]
21:31:56<peanuts> 12 longerOnes = [y | y <- xs, length y >= length x]
21:32:07<BONUS>[[]] is not an empty list :)
21:32:24<BONUS>it's a lsit that has one element (an empty list)
21:32:25<duaneb>ok
21:32:30<duaneb>how can I compare functions?
21:32:35<Twey>duaneb: You can't
21:32:36<duaneb>e.g. (not == not)
21:32:38<duaneb>:(
21:32:39<Twey>It doesn't make sense
21:32:43<PeakerWork>peanuts: why is a sort of lists different from a sort of values?
21:32:44<duaneb>yes it does
21:32:50<duaneb>you can compare variables
21:32:51<luqui>duaneb, (not in general. there are classes of function types that you can compare)
21:32:56<duaneb>"variables"
21:32:59<PeakerWork>Maybe if functions were total, you could compare them?
21:33:02<duaneb>and functions can be data
21:33:20<Twey>duaneb: If you have two functions that do the same thing in different ways, are they equal?
21:33:26<peanuts>oh I didn't realize that I could drop the inner empty list
21:33:29<BONUS>> sortBy (compare `on` length) [[1,2,3],[1],[1,2,3,4,5]]
21:33:30<PeakerWork>duaneb: but should (1+) == (+1) return True or False?
21:33:31<lambdabot> [[1],[1,2,3],[1,2,3,4,5]]
21:33:33<peanuts>I thought it would be a type error
21:33:36<luqui>PeakerWork, not always. you can compare functions with compact, overt domain
21:33:38<Twey>They may have different complexities
21:33:50<Chile`>luqui: applicative parsing referring to http://book.realworldhaskell.org/read/using-parsec.html#id652517 this sort of thing?
21:33:50<duaneb>peaker: well, are they the same function?
21:33:51<duaneb>probably not.
21:34:03<duaneb>it depends on how ghc compiles them
21:34:04<PeakerWork>duaneb: they have the same domain, range, and mapping between them
21:34:05<luqui>duaneb, we say two functions are the same if they do the same thing to every argument
21:34:11<PeakerWork>duaneb: but they might have different operational semantics
21:34:15<duaneb>well, yea
21:34:20<duaneb>just compare the pointers!
21:34:26<PeakerWork>duaneb: should (==) between functions compare just denotational semantics or also operational semantics?
21:34:30<luqui>duaneb, that violates a fundamental premise of haskell
21:34:38<duaneb>no, it really doesn't.
21:34:39<peanuts>thanks for the help!
21:34:43<Chile`>peanuts: what part of OR?
21:34:54<luqui>duaneb, maybe you should come back after you have researched a little
21:35:02<PeakerWork>duaneb: what's the point of comparing functions by pointer to the implementation?
21:35:03<duaneb>luqui: maybe you could help
21:35:09<duaneb>I need to compare two functions
21:35:10<peanuts>Corvallis
21:35:13<PeakerWork>duaneb: what for?
21:35:17<Chile`>peanuts: what part of Corvallis? :)
21:35:19<duaneb>I have a lambda data type
21:35:22<duaneb>for an interpreted language
21:35:26<luqui>duaneb, sure, but don't reply with "no it really doesn't" without knowing what you're saying
21:35:26<duaneb>that has a function in haskell
21:35:28<copumpkin>duaneb: if the input is enumerable and the output has equality, then you can ;)
21:35:33<copumpkin>enumerable in the non
21:35:36<BONUS>also is (head == foldr const undefined)
21:35:36<copumpkin>-Enum sense
21:35:51<duaneb>luqui: I understand what you're saying
21:35:55<mmorrow>, id .==. id
21:35:56<peanuts>Chile
21:35:58<lunabot> True
21:35:58<Twey>Under purity laws, optimisation means that the same name may not refer to the same function
21:35:59<mmorrow>ACTION ducks
21:36:04<PeakerWork>duaneb: (+1) and (1+) do the exact same thing to every input, but they might have different "function pointers", should they not compare equal? Note that the result of (4+4) and 8 may be different "pointers" in the implementation but (==) will still return True
21:36:13<copumpkin>mmorrow: lol, what is that comparing? stablenames?
21:36:15<duaneb>but at the same time, there's nothing stopping haskell from testing for equality between two arbitrary functions
21:36:19<Twey>And two entirely different names may refer to the same function
21:36:23<Twey>You never know
21:36:29<peanuts>Chile`: north west, 10 min from OSU ;)
21:36:31<duaneb>PeakerWork: yes, they should not be the same function!
21:36:33<luqui>duaneb, well, if you're okay with the comparison returning inside IO
21:36:45<luqui>there is a comparison a -> a -> IO Bool, but it is not to be trusted
21:36:49<mmorrow>copumpkin: a .==. b == a `seq` b `seq` I# (reallyUnsafePtrEquality# a b)
21:36:49<PeakerWork>duaneb: under same logic, 4 + 4 /= 8
21:36:53<copumpkin>lol
21:36:54<mmorrow>copumpkin: ;)
21:37:01<duaneb>also, let f = 5; g = 5; f `funccomp` g should equal False
21:37:03<luqui>depending on details of the garbage collector, concurrency, etc., it might give different answers for the same arguments
21:37:03<Twey>Haskell does not do identity checking — purity means that everything must be checked by value only
21:37:12<duaneb>PeakerWork: No, you're not reading what I'm saying
21:37:16<duaneb>I don't care what the functions do
21:37:21<duaneb>I'm trying to test identit
21:37:23<duaneb>y
21:37:26<mmorrow>copumpkin: err, maybe this one doesn't have the `seq`s, i can't remember
21:37:28<PeakerWork>duaneb: Haskell has no notion of "identity", really
21:37:34<duaneb>well
21:37:37<Twey>duaneb: If you want identity, make your own
21:37:37<duaneb>that's very inconvenient.
21:37:39<mmorrow>, id [] .==. []
21:37:42<lunabot> False
21:37:42<luqui>duaneb, how about this. haskell doesn't like identity. what are you trying to do, in the larger scheme of things?
21:37:45<mmorrow>no seqs
21:37:56<duaneb>compare two functions
21:37:59<Twey>For example a Data.Unique ID attached to your language object
21:37:59<luqui>duaneb, why?
21:38:01<duaneb>that are stored in a datatype
21:38:09<duaneb>luqui: let's say I'm building a tree
21:38:18<duaneb>a sorted tree
21:38:35<duaneb>of functions
21:38:45<duaneb>how can I sort it if I can't test for equality at the very least?
21:38:49<luqui>duaneb, but you don't care what the sort is, just sorted at all?
21:39:09<duaneb>luqui: look, do you understand what I'm saying?
21:39:25<luqui>duaneb, kind of, but I'm questioning your motivations for putting functions in a sorted tree
21:39:31<luqui>when it's unclear when one function should be less than another...
21:39:33<luqui>what does that mean?
21:39:33<duaneb>luqui: I'm not actually
21:39:44<mmorrow>duaneb: even with ptr equality, you don't get an Ord on functions.. since haskell is garbage collected
21:39:50<hatds>sorted containers are useful because it speeds up lookup. What you want to achieve can be done by insert (Int, func) pairs instead of just functions into your tree
21:40:00<mmorrow>(the Ord would change every GC)
21:40:31<luqui>duaneb, it's hard for newcomers, but haskell actually prevents you, by design, from doing certain things. most languages don't. you buy some nice properties this way, but it does cause you to rethink how you might approach some problems...
21:40:40<duaneb>luqui: well, just compare pointers
21:40:41<duaneb>so
21:40:42<luqui>chances are, if you want to compare functions, you are not doing it "the haskell way"
21:40:44<duaneb>I just can't do this?
21:40:44<duaneb>Ok
21:40:48<duaneb>this is what I'm doing
21:41:33<duaneb>I have a lisp
21:41:35<duaneb>I have two lambdas
21:41:38<duaneb>built-in
21:41:48<duaneb>defined internally as haskell functions
21:41:56<luqui>you're writing a lisp interpreter?
21:42:00<duaneb>I need to implement the scheme function "equal?"
21:42:18<duaneb>part of that entails testing built-in functions for equality
21:42:21<PeakerWork>Does Scheme have eq? and equal?
21:42:23<duaneb>there is NO WAY to do this with haskell?
21:42:26<duaneb>PeakerWork: yes
21:42:37<PeakerWork>duaneb: the "built-in" functions are actually free to be *any type you choose*
21:42:38<luqui>duaneb, there is a way, but scheme is less pure than haskell
21:42:39<kpreid>duaneb: you have to *give* an identity to the builtin functions
21:42:48<luqui>so you'll have to simulate the impurities manually
21:42:51<Twey>duaneb: Like I said: data SchemeType a = SchemeType Id a
21:42:51<PeakerWork>duaneb: they don't have to be Haskell functions
21:42:53<luqui>as kpreid says
21:42:55<duaneb>I am not happy.
21:43:09<kpreid>duaneb: in your table of builtins attach unique ids along with the haskell functions
21:43:18<duaneb>I suppose....
21:43:24<PeakerWork>duaneb: You're trying to map Scheme functions directly to Haskell functions, despite the semantics of them being very dissimilar
21:43:35<gwern>duaneb: if you're stuck, iirc, there's a Scheme in 21 days or something you could crib from
21:43:37<Twey>Haskell functions are pure. Scheme functions are not.
21:43:39<copumpkin>duaneb: as I said, you can do it if your input is enumerable and the output is an instance of Eq
21:43:53<luqui>copumpkin, that is completely irrelevant to his problem :-)
21:44:07<copumpkin>ACTION puts his tail between his legs and runs away
21:44:11<copumpkin>*stem
21:44:11<Twey>Yeah, that's not nearly the answer in this case.
21:44:16<Twey>Hehehe
21:44:20<copumpkin>I haven't really followed context :P
21:44:22<Twey>Copumpkins have legs?
21:44:26<copumpkin>just keep hearing "OMG function equality"
21:44:27<Twey>They really are different
21:44:44<Phyx->hmmm http://www.cafepress.com/doitmonad.7154442
21:44:48<mmorrow>duaneb: imagine if someone implemented vmware in the game of life, ptr equality there would still be ptr equality, but not equality on the ptrs use to implement the life which implements vmware which implements hardware which provides the memory cells which programs running on the hosted os see as ptrs
21:45:12<Phyx->i wonder how many people would get that if i walk through an airport with it on
21:45:15<luqui>Phyx-, :-)
21:45:29<Twey>ACTION laughs.
21:45:32<Twey>Nice T-shirt, Phyx-
21:45:49<duaneb>mmorrow: well, I understand the problem
21:45:54<duaneb>I just don't understand why that's necessary
21:45:58<gwern>Phyx-: they wouldn't have time to read it
21:46:08<Phyx->lol, i'm thinking of getting it
21:46:15<Phyx->or http://www.cafepress.com/classyhaskell.7154232
21:46:22<luqui>duaneb, when you see f :: Int -> Int in haskell, you already know certain things about f
21:46:28<mmorrow>duaneb: why what's necessary? (no comparison of the ptrs to haskell objects? (because of the gc))
21:46:36<Phyx->gwern: well, some are going to be in a 10hour flight with me :)
21:46:39<luqui>for example, it will not do any IO, and if you call it twice with the same argument you'll get the same result.
21:46:46<mmorrow>duaneb: you can use StableName though
21:46:48<gwern>luqui: yeah. like, it could be bottom, it could be using unsafePerformIO, it could...
21:46:51<luqui>if you could willy-nilly compare objects, then it might violate the latter constraint
21:46:58<copumpkin>duaneb: can't you just use a wrapper type for your functions you want to expose in your lisp? data LispFunction = LispFunction String (LispType -> LispType) or something
21:47:02<gwern>actually, we don't get a whole lot of guarantees in real haskell do we -_-
21:47:08<luqui>gwern, I reject your unsafePerformIO and substitute my own
21:47:24<gwern>ACTION sees luqui and raises with an unsafeCoerce#
21:47:26<hatds>lol
21:47:35<duaneb>copumpkin: I have that
21:47:36<copumpkin>ACTION applies StrictAnal
21:47:39<copumpkin>ah
21:47:39<Twey>duaneb: Because what you're saying doesn't make sense in a pure language
21:47:50<Twey>A function is a mapping from one set of values to another
21:47:54<duaneb>data LispType = Lambda (LispType -> LispType)
21:47:58<gwern>ACTION invokes the function 'lub' on copumpkin's StrictAnal
21:48:03<copumpkin>lol
21:48:05<PeakerWork>gwern: if its using unsafePerformIO to break referential transparency, then its buggy -- it cannot under any circumstance do it behind a legitimate interface
21:48:13<hatds>ACTION looks at code using pointer equality. Goes "well there's your problem".
21:48:19<duaneb>Twey: well, it may not make sense, but it's also not prohibited by a pure language
21:48:21<Phyx->ACTION voilates gwern referential transparency
21:48:23<Twey>In mathematics, it would make sense to say that any functions that could provably yield the same results for all inputs are equal
21:48:34<gwern>ACTION is now impure! damn you Phyx-
21:48:52<Twey>In Haskell, though, that's not necessarily true, since we're running on real hardware and that means that there's computational complexity to consider
21:48:53<copumpkin>we could get a referential transparency violation chain going in here
21:49:00<luqui>Twey, (even unprovably, but that gets yucky)
21:49:03<Phyx->hahah
21:49:05<Twey>Additionally, that can't be proven anyway
21:49:10<Twey>(by a machine)
21:49:14<mreh>Loading package unix-2.3.2.0 ... <command line>: can't load .so/.DLL for: rt (/usr/lib/librt.so: symbol __librt_multiple_threads, version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference)
21:49:15<Phyx->ACTION goes to bash.org
21:49:20<kpreid>duaneb: yes it is prohibited. trying to define function identity gives you all sorts of interesting problems with preserving referential transparency, particularly because functions can close over values
21:49:21<mreh>that's exciting
21:49:22<hatds>yea, operational equality and denotational equality would both be somewhat functions to have... if only they weren't so hard to compute!
21:49:32<hatds>*somewhat nice functions
21:49:33<mmorrow>usually in math a function if a function by definition, a priori
21:49:39<PeakerWork>duaneb: That LispType seems kind of useless
21:49:42<mmorrow>because you said it's a function
21:49:43<mreh>i've had so many errors trying to cabal install yi
21:49:44<kpreid>duaneb: it might be possible to define "good enough equality" but it wouldn't be predictable over multiple compiles due to optimization
21:50:00<PeakerWork>duaneb: how do you form an arg for the input of LispType?
21:50:26<kpreid>I assume that was just an example of one of the constructors
21:50:58<luqui>duaneb, anyway, probably looks like this: data LispType = Lambda Unique (LispType -> LispMonad LispType)
21:51:11<duaneb>PeakerWork: well, it's not the only constructor :P
21:51:27<luqui>(LispMonad because lisp functions have more side-effects than just comparing for equality, and you need to get your uniques from somewhere)
21:51:59<mmorrow>i think we're talking about two different things here... so ignoring referential transparency, purity, and letting "anything go", you still can't get Ord on the ptrs to haskell values (you can get Eq though) because of the GC
21:52:13<luqui>PeakerWork, of course, newtype L = L (L -> L) is the scott domain. hard to *do* anything with it :-)
21:52:23<luqui>but it is the foundation of our entire language
21:53:12<PeakerWork>duaneb: I think if you want mutations on values, you can't just attach an Id tag to values and copy the pair around. You have to have some global Map Id LispType
21:53:17<hatds>mmorrow: wait, what? wouldn't GC mess up Eq and Ord equally?
21:53:21<PeakerWork>duaneb: Then you can place all the lisp values in there
21:53:45<mmorrow>hatds: yeah, it destroys any chance for Ord, but you can haz Eq
21:53:47<luqui>PeakerWork, and do manual GC (!)
21:53:50<hackagebot>uuid 1.0.2
21:53:54<luqui>PeakerWork, probably better to use STRefs
21:53:59<hatds>mmorrow: Eq how?
21:54:05<PeakerWork>luqui: can an STRef be compared for identity?
21:54:11<luqui>PeakerWork, yep
21:54:12<mmorrow>hatds: reallyUnsafePtrEquality#
21:54:17<PeakerWork>luqui: how?
21:54:19<hatds>mmorrow: oh
21:54:23<luqui>@info STRef
21:54:23<lambdabot>STRef
21:54:27<luqui>thanks, lambdabot
21:54:31<PeakerWork>STRef's have an Eq instance?
21:54:42<mmorrow>hatds: which is dependent on what state of evaluation a value happens to be in..
21:54:58<PeakerWork>oh cool
21:55:06<mmorrow>hatds: (which is why the "unsafe", because it's not referentially transparent)
21:55:45<luqui>duaneb, okay, so using STRef (or IORef if ST scared you) seems like a good bet?
21:56:15<mmorrow>(and the "really" because you have to "really" figure out what's going on to be almost sure it's working like you want it to)
21:57:05<PeakerWork>duaneb: You can have: data LispType = LispValue (IORef Lisp) ; data Lisp = BuiltinFunction (LispType -> LispType) | Atom String | List [LispType]
21:57:55<luqui>PeakerWork, BuiltinFunction (LispType -> IO LispType) ?
21:58:24<dmwit>No, let all the built-in functions be pure! ;-)
21:58:30<dmwit>?instances-importing Data.STRef Eq
21:58:31<lambdabot>(), (a, b), (a, b, c), (a, b, c, d), (a, b, c, d, e), All, Any, Bool, Char, Double, Dual a, Either a b, First a, Float, Int, Integer, Last a, Maybe a, Ordering, Product a, STRef s a, Sum a, [a]
21:58:40<dmwit>luqui: There you go.
21:58:48<dmwit>luqui: Also, for your future information:
21:58:50<PeakerWork>equal compares identity or eq?
21:58:57<PeakerWork>luqui: Yeah
21:58:58<dmwit>?info do { x <- foo; return (bar y) }
21:58:58<lambdabot>foo >>= \ x -> return (bar y)
21:59:14<luqui>info = undo?
21:59:23<dmwit>ACTION nods
21:59:27<luqui>how... strange
21:59:32<PeakerWork>I think its accidental
21:59:40<copumpkin>the edit distance is short?
21:59:43<dmwit>right
21:59:47<dmwit>?botsmuck
21:59:47<lambdabot>:)
21:59:59<luqui>oh lame
22:00:06<copumpkin>?batstack
22:00:06<lambdabot>:)
22:00:10<luqui>lol
22:00:14<PeakerWork>which of eq/equal are equality and which are identity?
22:00:16<PeakerWork>(in Scheme)
22:00:17<PeakerWork>heh
22:00:22<dmwit>ACTION censors himself
22:00:41<sjanssen>been such a long time since I've used Scheme
22:00:47<sjanssen>I think eq is identity
22:01:16<luqui>there are so many different kinds of equality. *hugs haskell for clearing up the situation*
22:01:32<augustss>equal is equality
22:01:45<augustss>in scheme
22:02:02<augustss>eq is identity, eqv is in between
22:02:08<dmwit>Do any Haskell implementations use unsafe pointer equality as a fast-path for Eq instances?
22:02:20<Phyx->i tried F# last week... i couldn't make head or tails of it... I was trying to figure out how to make a function signature.. epic fail...
22:02:22<augustss>dmwit: not that I know
22:02:32<augustss>dmwit: it's tricky
22:02:35<Trollinator>what is the $ operator for? after all, f $ x is the same as f `id` x
22:02:59<dmwit>augustss: What, really?
22:03:36<Chile`>Trollinator: just convenient syntax to avoid lots of nested parens
22:03:43<luqui>Trollinator, um... i dunno, readability?
22:03:53<dmwit>augustss: What if we restrict it to derived instances, where we know pointer equality will never steer us wrong?
22:04:31<dmwit>Trollinator: ($) has lower precedence than `id`.
22:04:32<Trollinator>right! i hear $ screaming "I'm the function application operator!"
22:04:42<mreh>I've got a dependancy issue while installing yi, for a package that isn't listed on the hackage dependancy list
22:04:49<luqui>infixr 0 `id`
22:04:52<mreh>unix-2.3.2.0
22:05:13<mreh>I can't work out which version yi needs, there's some kind of bug in the one I haver
22:05:15<mreh>have*
22:10:16<PeakerWork>luqui: hmm.. trying this approach to Lisp, but how can you create global IORefs for true/false without unsafePerformIO on a newIORef? I guess the entire Lisp thing can be in a ReaderT of an environment with all the necessary builtins, but its not nice
22:11:05<PeakerWork>luqui: (have to return Lisp's true/false inside functions like equal, but they are also inside IORefs. Maybe immutable stuff should have Ids and mutable stuff should be in IORefs
22:11:30<luqui>PeakerWork, yeah i think so
22:11:40<luqui>true/false aren't mutable so they shouldn't be in IORefs
22:11:49<copumpkin>:o
22:11:56<luqui>true := 42
22:12:14<luqui>> let 1 = 2 in 2+2
22:12:15<lambdabot> 4
22:14:17<copumpkin>> let !1 = 2 in 2 + 2
22:14:18<lambdabot> * Exception: <interactive>:1:153-158: Non-exhaustive patterns in pattern bi...
22:14:25<copumpkin>zomg what will I do
22:20:25<telemachus>do I need to load a special library to have access to ord and chr?
22:20:44<sjanssen>telemachus: import Data.Char
22:20:52<telemachus>that would be it
22:20:53<telemachus>sighs
22:20:57<telemachus>thanks, sjanssen
22:21:23<telemachus>the book I'm using neglected to mention that
22:21:47<telemachus>(and most searches on Google for ord gave tons of hits for Ord)
22:22:32<aavogt>@hoogle chr -- likely better than google for functions
22:22:32<lambdabot>Parse error:
22:22:32<lambdabot> --count=20 "chr -- likely better than google for functions"
22:22:32<lambdabot> ^
22:22:37<aavogt>@hoogle chr
22:22:38<lambdabot>Data.Char chr :: Int -> Char
22:22:38<lambdabot>Text.PrettyPrint.HughesPJ Chr :: Char -> TextDetails
22:22:38<lambdabot>System.Posix.Internals c_s_ischr :: CMode -> CInt
22:23:47<telemachus>hoogle bookmarked, thanks aavogt
22:24:18<sjanssen>oh jeez, don't tell me we have a shell injection vulneratiblity here
22:24:37<sjanssen>@hoogle chr" ; echo busted
22:24:37<lambdabot>Parse error:
22:24:37<lambdabot> --count=20 "chr" ; echo busted"
22:24:37<lambdabot> ^
22:25:20<centrinia>@hoogle chr\" ; echo busted
22:25:21<lambdabot>Parse error:
22:25:21<lambdabot> --count=20 "chr\" ; echo busted"
22:25:21<lambdabot> ^
22:26:06<sjanssen>nope, safe
22:26:09<centrinia>@hoogle ; ls -l
22:26:10<lambdabot>Parse error:
22:26:10<lambdabot> --count=20 "; ls -l"
22:26:10<lambdabot> ^
22:26:17<sjanssen>the parse error comes from the Hoogle program
22:26:49<sjanssen>we don't go via sh when calling hoogle
22:29:02<Phyx->@url hoogle
22:29:02<lambdabot>http://haskell.org/hoogle
22:43:07<aavogt><ghc> My brain just exploded. I can't handle pattern bindings for existential or GADT data constructors. Instead, use a case-expression, or do-notation, to unpack the constructor.
22:54:02<PeakerWork>Why does ghc need to preface that message with "My brain just exploded."? :P
22:54:10<PeakerWork>its funny the first time, but then its annoying for the rest
22:54:48<monochrom>It has a second purpose in addition to being funny.
22:54:50<Phyx->@src :P
22:54:50<lambdabot>Source not found. Just try something else.
22:54:54<Phyx->@src (+)
22:54:54<lambdabot>Source not found. Listen, broccoli brains, I don't have time to listen to this trash.
22:55:06<Phyx->PeakerWork: why does @src try to be funny
22:55:20<PeakerWork>@src is lambdabot, and the above is a ghc error
22:55:20<lambdabot>Source not found. That's something I cannot allow to happen.
22:55:30<monochrom>Let's say you're writing your program but you haven't implemented some planned feature yet, but you leave stub in your code for it. What do you write in the stub?
22:55:44<centrinia>@src -- Please insult me gently with a chainsaw.
22:55:45<lambdabot>Source not found. And you call yourself a Rocket Scientist!
22:55:51<aavogt>it is a trivial change to make my code comply with this arbitrary restriction
22:56:02<monochrom>You probably write like f x = error "I haven't implemented f yet".
22:56:20<Phyx->PeakerWork: well, i appreciate ghc's attempt at humor though :)
22:56:35<monochrom>So they write "My brain has exploded". It means something is not implemented yet.
22:57:10<centrinia>@let f x = error "I haven't implemented f yet"
22:57:12<lambdabot> Defined.
22:57:15<centrinia>@src f
22:57:16<lambdabot>Source not found. Just try something else.
22:57:24<centrinia>@src L.f
22:57:25<lambdabot>Source not found. Take a stress pill and think things over.
22:57:35<centrinia>That doesn't make sense.
22:57:41<monochrom>src is a static database, and very incomplete.
22:57:52<aavogt>@src src
22:57:53<lambdabot>Source not found.
22:58:06<monochrom>Let's just say what src knows is pretty much hardcoded.
22:58:39<monochrom>It's also somewhat out of touch with reality, too.
22:58:44<centrinia>How do we make the @src database dynamic?
22:58:51<wpearson>@src reality
22:58:52<lambdabot>Source not found. I've seen penguins that can type better than that.
22:59:04<centrinia>@src clue
22:59:05<lambdabot>Source not found.
22:59:07<monochrom>@src length
22:59:07<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
22:59:17<monochrom>@src foldl
22:59:18<lambdabot>foldl f z [] = z
22:59:18<lambdabot>foldl f z (x:xs) = foldl f (f z x) xs
22:59:22<aavogt>@src lambdabot
22:59:22<lambdabot>Source not found. The more you drive -- the dumber you get.
22:59:23<centrinia>@src (>>=)
22:59:24<lambdabot>Source not found. Where did you learn to type?
22:59:32<centrinia>@src sqrt
22:59:33<lambdabot>Source not found. :(
22:59:40<monochrom>For example foldl. It is not what GHC uses.
22:59:56<centrinia>At least @src should have the entire Prelude. :(
23:00:18<monochrom>Did you know that "sqrt" and ">>=" are typeclass methods?
23:00:30<centrinia>Oh.
23:00:39<centrinia>@src sqrt :: Double -> Double
23:00:40<lambdabot>Source not found. Sorry.
23:00:45<monochrom>Did you know that therefore asking for the source code of "sqrt" is ambiguous? Like which instance would you really want?
23:00:47<dmwit>?src Double sqrt
23:00:47<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
23:00:51<dmwit>?src [] (>>=)
23:00:52<lambdabot>xs >>= f = concatMap f xs
23:00:58<centrinia>Ah.
23:01:13<centrinia>?src IO (>>=)
23:01:14<lambdabot>m >>= k = bindIO m k
23:01:20<dmwit>sqrt = sqrtDouble# ;-)
23:01:20<centrinia>?src bindIO
23:01:21<lambdabot>bindIO (IO m) k = IO ( \ s ->
23:01:21<lambdabot> case m s of (# new_s, a #) -> unIO (k a) new_s)
23:01:35<centrinia>?src unIO
23:01:36<lambdabot>Source not found. Just what do you think you're doing Dave?
23:01:53<aavogt>@quote not funny
23:01:53<lambdabot>No quotes for this person. Sorry.
23:02:05<aavogt>@quote exploded
23:02:06<lambdabot>tessier says: After the last newbies head exploded trying to read everything on that monad link there was a lot of paperwork. We'd like to avoid doing that again.
23:02:23<monochrom>unIO is the inverse of IO. By IO I mean the data constructor you just saw in "bindIO (IO m) k".
23:03:01<monochrom>The source code probably had "data IO a = IO { unIO :: ... }". And of course src would not know that one.
23:03:22<mauke>@src IO
23:03:23<lambdabot>newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
23:03:35<monochrom>Yeah I mean newtype. :)
23:04:24<monochrom>You are better off finding GHC library source code elsewhere than asking src. It knows nothing.
23:09:01<Botje>it's from barcelona!
23:09:26<dmwit>oh no!
23:26:34<frogman>Is there a way to test the type of something within a function--like if a function has a return type of either, can I see if the output of another function on the input is one type or another?
23:27:00<mauke>what
23:27:04<mauke>'either' is not a type
23:27:13<frogman>Either Int String
23:27:26<mauke>case x of Left i -> ...; Right s -> ...
23:27:42<frogman>ok thanks!
23:28:34<kpreid>frogman: those are not different types, they're different values (constructors, you could say)
23:32:54<christastrophe>good evening everyone
23:33:38<christastrophe>i'm having some confusion with a little code snippet
23:34:12<christastrophe>this seems to cause an overflow: foldl' (\(l,s) v -> (l+1,s+v) (0,0) [1..1000000]
23:34:29<christastrophe>but computing each of the sub parts works just fine
23:34:51<mauke>makes sense
23:34:58<christastrophe>what could cause the overflow in the combined version?
23:35:08<mauke>the usual laziness
23:35:08<Botje>christastrophe: foldl' only forces the outer constructor
23:35:14<mauke>forcing a pair doesn't force its contents
23:35:14<Botje>which is (,)
23:35:48<christastrophe>ah I see, so I'm still building up a chain of thunks here
23:35:49<Botje>either use a strict pair or call seq yourself
23:36:00<mauke>(,) $! l+1 $! s+v
23:36:37<christastrophe>ok let me give that a try...
23:40:20<christastrophe>ha. that did work. seems I am not yet 'evaluating' haskell properly in my head
23:54:20<hatds>lazy pairs of numeric types always messed with my head :)
23:55:47<christastrophe>I was reading foldl simmilar to SmallTalks inject, but forgetting the laziness of Haskell

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