Experimental IRC log haskell-2009-05-26

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:12:27<dibblego>why do I have Test.QuickCheck at ghci but it is missing if I try to create an executable with ghc?
00:15:32<FunctorSal>are you using ghci-haskeline by chance?
00:15:51<FunctorSal>it confused me by being still linked to an older ghc once :)
00:16:42<dibblego>who?
00:16:57<FunctorSal>you :)
00:17:24<dibblego>I mean who is ghci-haskeline?
00:17:49<FunctorSal>it's a ghci that uses haskeline
00:18:00<FunctorSal>(I think ghc-6.10.3 does this by default now)
00:18:16<dibblego>I'm using ghc 6.10.2
00:20:43<dibblego>how can I determine if I am using ghci-haskeline?
00:20:50<deech>Hi all, Is there anyway to embed an evaluation into Haddock documentation?
00:21:54<dibblego>actually it's the linking where QuickCheck is missing
00:22:08<dibblego>(.data+0x178): undefined reference to `QuickCheckzm1zi2zi0zi0_TestziQuickCheck_variant_closure'
00:25:56<dibblego>I suppose CABAL would resolve this, but was hoping to avoid that
00:29:56<Peaker>Cale: about removing Eq constraint from Num -- how do you pattern-match against numbers? What's the type of f 0 = 1 ; f n = n*f (n-1) ? Just (Eq a, Num a) => a -> a ?
00:30:59<jmcarthur>i see nothing wrong with that
00:31:15<FunctorSal>isn't that a pseudo-constructor match rather than an equality-guarded match?
00:31:32<FunctorSal>(can you even match on arbitrary Nums?)
00:31:48<jmcarthur>FunctorSal: a number literal is converted implicitly using fromIntegral
00:33:24<jak>> foldl1 (+1) []
00:33:25<lambdabot> Occurs check: cannot construct the infinite type: a = a -> a
00:33:28<jak>@src foldl
00:33:29<lambdabot>foldl f z [] = z
00:33:29<lambdabot>foldl f z (x:xs) = foldl f (f z x) xs
00:33:35<FunctorSal>jmcarthur: but you'd have to invert formIntegral unless I'm missing something
00:33:46<jak>@src foldr
00:33:46<lambdabot>foldr f z [] = z
00:33:46<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
00:33:48<Cale>Peaker: Yeah, when you pattern match, you'll need Eq
00:34:39<jmcarthur>:t fromIntegral
00:34:40<lambdabot>forall a b. (Integral a, Num b) => a -> b
00:34:54<jmcarthur>Num also requires Eq, right now
00:34:56<Peaker>pattern-matches against numbers seem to be a special case in Haskell (as (==) . fromInteger is applied)
00:35:15<jak>> (+1) 3
00:35:16<lambdabot> 4
00:35:18<FunctorSal>"f @LITERAL = ..." <-> "f x | fromIntegral @LITERAL == x = ..." ?
00:35:20<jak>> 3 (+1)
00:35:20<lambdabot> Add a type signature
00:35:25<jmcarthur>:t fromInteger
00:35:26<jak>> 3 (+1) ::Int
00:35:27<lambdabot>forall a. (Num a) => Integer -> a
00:35:28<lambdabot> No instance for (GHC.Num.Num ((a -> a) -> GHC.Types.Int))
00:35:28<lambdabot> arising from t...
00:35:36<jak>> (1+) 3
00:35:37<lambdabot> 4
00:35:39<jmcarthur>yeah, fromInteger, not fromIntegral, my bad
00:35:45<jak>> 3 (1+)
00:35:46<lambdabot> Add a type signature
00:36:00<jak>> (5-3*) 7
00:36:02<lambdabot> The operator `GHC.Num.*' [infixl 7] of a section
00:36:02<lambdabot> must have lower prece...
00:36:18<jak>> ((5-3)*) 7
00:36:19<lambdabot> 14
00:43:00<Cale>dons: if you're around, you might find the discussion that gwern and I had comparing core between versions of the pidigits code somewhat interesting
00:43:28<Cale>dons: It seems that there are some big differences between how 6.10.2 compiles list comprehensions to 6.10.3
00:44:59<aavogt>:t ((?f .) .)
00:45:00<lambdabot>forall b c a a1. (?f::b -> c) => (a1 -> a -> b) -> a1 -> a -> c
00:46:24<Cale>:t fmap (fmap f)
00:46:26<lambdabot>forall a b (f :: * -> *) (f1 :: * -> *). (Show a, SimpleReflect.FromExpr b, Functor f, Functor f1) => f1 (f a) -> f1 (f b)
00:46:30<Cale>er
00:46:32<Cale>:t fmap (fmap ?f)
00:46:34<lambdabot>forall a b (f :: * -> *) (f1 :: * -> *). (?f::a -> b, Functor f, Functor f1) => f1 (f a) -> f1 (f b)
00:46:53<Cale>That's how I like to think of it.
00:47:11<Cale>(f .) is the same as fmap f for the (e ->) functor.
00:47:20<dibblego>how can I get cabal to build an executable with the run target?
00:47:23<dibblego>oops build target
00:50:14<aavogt>@pl \x -> (+ map return x)
00:50:15<lambdabot>(+) . map return
00:50:33<aavogt>@pl \x -> (map return x +)
00:50:33<lambdabot>(+) . map return
00:50:51<aavogt>@pl \x y -> (map return x + y)
00:50:52<lambdabot>(+) . map return
00:50:59<aavogt>@pl \x y -> (y+map return x)
00:51:00<lambdabot>(+) . map return
00:51:22<aavogt>shouldn't there be a flip in there somewhere?
00:52:00<aavogt>:t (+) . map return
00:52:01<lambdabot>forall a (m :: * -> *). (Num [m a], Monad m) => [a] -> [m a] -> [m a]
00:52:08<aavogt>:t flip (+) . map return
00:52:10<lambdabot>forall a (m :: * -> *). (Num [m a], Monad m) => [a] -> [m a] -> [m a]
00:52:19<dibblego>@pl \x y -> ((+) y (map return x))
00:52:20<lambdabot>(+) . map return
00:52:41<dibblego>@pl \x y -> (+) y (map return x)
00:52:42<lambdabot>(+) . map return
00:52:55<aavogt>going by the types, the flip does nothing
00:53:06<Gracenotes>(+) is commutative
00:53:31<Gracenotes>for Int and Integer, at least. Float+Double might have some corner cases
00:53:50<aavogt>:t flip (.) (+) (map return)
00:53:52<lambdabot> Couldn't match expected type `a -> a' against inferred type `[a1]'
00:53:52<lambdabot> In the third argument of `flip', namely `(map return)'
00:53:52<lambdabot> In the expression: flip (.) (+) (map return)
00:53:55<Gracenotes>maybe pl knows this?
00:54:17<aavogt>@pl flip . flip . flip
00:54:18<lambdabot>flip
00:54:43<aavogt>@pl flip (+)
00:54:43<lambdabot>(+)
00:55:06<aavogt>@pl flip (\x y -> (y,x)))
00:55:07<lambdabot>(line 1, column 21):
00:55:07<lambdabot>unexpected ")"
00:55:07<lambdabot>expecting variable, "(", operator or end of input
00:55:11<aavogt>@pl flip (\x y -> (y,x))
00:55:12<lambdabot>(,)
00:56:10<aavogt>@pl flip ((+) . map return)
00:56:11<lambdabot>(. map return) . (+)
00:56:15<Gracenotes>yes, it seems pl is allowed to flip those
00:56:20<Gracenotes>commutativeOps = ["*", "+", "==", "/=", "max", "min"]
00:56:26<Gracenotes>from the source code. it considers these commutative
00:57:09<Gracenotes>x+y == y+x
00:57:17<aavogt>yeah
00:57:40<vininim_> openFile: resource exhausted (Too many open files)
00:57:40<roconnor>@type infinity
00:57:41<lambdabot>Natural
00:57:42<ziman>@pl flip (+)
00:57:42<lambdabot>(+)
00:57:43<vininim_>baaawwww
00:57:48<roconnor>> 1 + infinity > 1
00:57:49<lambdabot> True
00:57:55<roconnor>> infinity + 1> 1
00:57:56<lambdabot> True
00:58:35<Gracenotes>Natural uses lazy comparisons and such
00:58:36<jbauman>> 1 + infinity > infinity
00:58:41<lambdabot> mueval-core: Prelude.read: no parse
00:58:41<lambdabot> mueval: ExitFailure 1
00:59:00<aavogt>@src infinity
00:59:00<lambdabot>Source not found. You speak an infinite deal of nothing
00:59:01<vininim_>why mapM readFile listOfFiles doesn't garbage collect file handles?
00:59:09<Gracenotes>hm
00:59:09<aavogt>mapM_
00:59:16<Gracenotes>> genericLength [1..] > (5 :: Natural)
00:59:18<lambdabot> True
00:59:51<aavogt>might be better, but I'd expect the handles to be thrown away in either case
01:00:12<aavogt>plus, mapM_ readfile is quite pointless :)
01:00:44<Gracenotes>vininim_: it should GC the file handles once they're out of scope
01:00:53<Gracenotes>like most other languages
01:00:58<Gracenotes>that GC
01:01:15<Gracenotes>aavogt: oooooh. I see the issue. readFile is lazy.
01:02:08<Gracenotes>http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#v:readFile
01:02:57<aavogt>@type foldl' (\a x -> ?f x =<< a)
01:02:58<lambdabot>forall b (m :: * -> *) b1. (?f::b -> b1 -> m b1, Monad m) => m b1 -> [b] -> m b1
01:03:23<Asdfgh11>hello , how can i define a data type which can accept Char
01:03:34<aavogt>@type foldl' (>>=)
01:03:36<lambdabot>forall (m :: * -> *) b. (Monad m) => m b -> [b -> m b] -> m b
01:04:06<Gracenotes>too bad there isn't a non-lazy hGetContents
01:04:10<Asdfgh11>i have done that
01:04:56<Asdfgh11>example data K = And Int Int | Char . i need the Char to be without a name
01:05:16<aavogt>Gracenotes: so use a stricter sequence function?
01:05:21<Berengal>Gracenotes: hGetContents >>= return . seq <$> last <*> id
01:05:42<Gracenotes>Berengal: that don't look like a function to me
01:05:51<Gracenotes>>_>
01:06:06<Berengal>Gracenotes: foo handle = hGetContents handle >>= return . seq <$> last <*> id
01:06:13<Asdfgh11>what is that
01:06:29<Gracenotes>Asdfgh11: data types must have a constructor
01:06:43<Asdfgh11>yh b but i have to do it
01:06:50<aavogt>@type fmap (liftA2 seq last id) . hGetContents
01:06:51<lambdabot>Not in scope: `hGetContents'
01:07:00<aavogt>@type fmap (liftA2 seq last id) . const getContents
01:07:01<Gracenotes>but you can have multiple constructors. So: data Foo = Bar Int Int | Baz Char
01:07:01<lambdabot>forall a. a -> IO [Char]
01:07:02<Asdfgh11>exmaple and(and 'a' 'b')
01:07:19<Asdfgh11>and i will put the input as ture wro false
01:07:34<roconnor>@bab nl en geweigerd
01:07:34<lambdabot>Plugin `babel' failed with: Prelude.head: empty list
01:07:41<Gracenotes>eek.
01:08:38<Asdfgh11>i can not use the a constructer for the character
01:08:46<Berengal>Asdfgh11: All values need a constructor, no exceptions
01:09:08<Asdfgh11>what should i do ?
01:09:56<Berengal>Give the constructor a name
01:10:15<Asdfgh11> (And( And 'a' 'b'))
01:10:47<Berengal>Your And constructor takes two ints only...
01:11:14<Asdfgh11>YH
01:11:46<Asdfgh11>its going to be replace by a number given by the user
01:11:47<Berengal>Because that's what you defined it to do
01:12:22<Asdfgh11>i should replace the chars with ints
01:12:37<Asdfgh11>thnak u for heloing
01:12:50<Berengal>What exactly are you trying to do?
01:14:25<Asdfgh11>Add( 'a' 'b') while a=2 and b=3
01:15:11<Berengal>I assume you meant 'where' there...
01:15:36<Asdfgh11>what does where do
01:15:49<Berengal>> x + y where x = 2; y = 3
01:15:50<lambdabot> <no location info>: parse error on input `where'
01:16:13<Berengal>lambdabot no do where? :(
01:16:27<FunctorSal>oh dear. I just jumped to the beginning of the "Do we really need FPLs? We can do everything with the imperative languages. " comp.lang.functional thread we had earlier
01:16:41<Berengal>Anyway, where is like let, except it comes after the expressions
01:17:21<Cale>I find it interesting that the naive-looking Haskell pidigits on the shootout is beating the brutally unreadable C version.
01:17:22<Berengal>'while' generally doesn't make much sense in haskell
01:17:23<jeffwheeler>I went to the UIL state meet (the primary academic competition in Texas), and there was a kid named Tsz Ling Kong from I guess the city of Haskell, Texas (or maybe Haskell high school?) in the Mathematics competition.
01:17:44<Asdfgh11>evaluate (Add(Add('a' 'b') ('c' 'd')) 1 2 3 4
01:18:14<Asdfgh11>1 2 3 4 should replace the chars
01:18:43<Cale>FunctorSal: That sounds like a waste of time thread.
01:18:44<Berengal>Asdfgh11: That needs to look like 'evaluate (Add (Add 'a' 'b') (Add 'b' 'c'))) [1,2,3,4]'
01:19:15<Berengal>Or 'evaluate (Add (Add 'a' 'b') (Add 'b' 'c'))) [('a',1),('b',2),('c',3),('d',4)]'
01:19:16<FunctorSal>yes. must... resist...
01:19:50<Asdfgh11>yes
01:19:54<Asdfgh11>sry my mistake
01:20:12<Asdfgh11>what shoudl i do
01:20:19<Berengal>Asdfgh11: I assume the datatype you're looking for is something like 'data Expression = Add Expr Expr | Sub Expr Expr | Var Char | Val Int |...'
01:20:36<Berengal>s/Expr/Expression
01:21:11<Berengal>Then you could have have a function 'evaluate :: Expression -> [(Char, Int)] -> Int'
01:21:49<Asdfgh11>var Char how will it work
01:22:19<Berengal>And pattern match on the expression constructors, like 'evaluate (Add a b) env = evaluate a env + evaluate b env; evaluate (Var c) env = let Just val = lookup c env in val; ...'
01:22:44<crutex>grill $ burgers :: Delicious
01:22:47<Berengal>env is the "environment", or the bindings
01:23:44<crutex>grill $ burgers :: Delicious Food
01:23:56<Asdfgh11>if i created a var c i have to write in the expression var c
01:24:09<Berengal>Asdfgh11: Yes
01:24:36<Asdfgh11>but i cant , that problem
01:24:47<crutex>guys is that proper syntax?
01:24:51<Berengal>So you'd have 'Add (Var 'a') (Var 'b')'
01:25:18<Berengal>Asdfgh11: In that case you need to write a parser or something
01:25:26<Asdfgh11>i should have : Add ('a' 'b') [1 ,2]
01:25:43<crutex>Asdfgh11 are you sure that's proper syntax?
01:25:48<Asdfgh11>i should have : Add (var ' a' var 'b') [1
01:25:51<Asdfgh11>yes i am
01:25:53<crutex>...
01:25:55<crutex>i think it's not
01:25:57<Berengal>Asdfgh11: You could do that if you wanted, but then you'd only be able to add variables
01:26:37<Asdfgh11>what do u mean
01:26:41<crutex>that's what i meant
01:26:55<Berengal>Asdfgh11: Actually, you can't have the parenthesis there...
01:27:46<crutex>it's elementary how could you f that up
01:27:53<Asdfgh11>so it cant be done
01:28:08<tompledger>Re Add 'a' 'b': Could you use a class to span both Char and the datatype with Add/Sub/etc?
01:28:20<Berengal>Asdfgh11: ('a' 'b') means "apply the function 'a' to the value 'b'), which can't be done since 'a' isn't a function
01:28:23<crutex>tompledger are you sure that's proper syntax?
01:28:45<crutex>99% of errors are syntax aerors.
01:29:07<Asdfgh11>what do u mean by spanning
01:29:24<crutex><span> is like a div but with inline display by default
01:29:28<tompledger>crutex: if Add is a data constructor taking 2 args, then yes
01:29:29<crutex>it's just for partitioning content
01:29:47<Berengal>tompledger: You could have a class Expr e where evaluate :: [...]
01:29:55<crutex>Berengal are you sure that's proper syntax?
01:30:11<Berengal>crutex: I'm sure it's not.
01:30:16<crutex>that's what i thought
01:30:21<tompledger>The [...] is metasyntax ;-)
01:30:29<crutex>i knew it looked strange
01:30:38<Berengal>tompledger is right
01:30:47<crutex>i'm new to this
01:30:58<crutex>forgive if i ask too many questions
01:31:01<Asdfgh11>can you tell me how to write a parser
01:31:14<crutex>ehh maybe in a few years once i learn
01:31:23<crutex>what are you trying to parse
01:31:26<crutex>haskell grammar?
01:31:43<Asdfgh11>i have expression wich i want to be accepted as char also
01:31:59<crutex>hmm
01:32:15<crutex>well what do you mean by "tell you how to write a parser"
01:32:45<Asdfgh11>i want data Exp to accept chars
01:32:57<Berengal>Asdfgh11: A parser takes a string as input. You can't use it directly in source, unless you put a string literal in there...
01:33:32<Asdfgh11>berengal do understand my problem
01:33:47<Berengal>Asdfgh11: Not completely, I'm afraid...
01:33:57<gwern>'Possibly it should use instead "validating constructors" that return a Maybe type. But note that some minutes have 61 seconds, and given that TimeOfDay might be local civil time (UTC + time zone offset), it can be any minute. So these must be allowed:'
01:34:02<gwern>arrghhh
01:34:03<crutex>gwern are you sure that's proper syntax?
01:34:21<gwern>ACTION hates units. units are insane! a minute has 60 seconds, end of discussion
01:34:30<crutex>well technically not
01:34:30<skorpan>what's wrong with ()
01:34:36<crutex>leap seconds
01:34:50<crutex>!google leap seconds
01:34:55<Gracenotes>go!
01:35:01<gwern>crutex: not listening!
01:35:08<crutex>eh ?
01:35:10<Gracenotes>hrm. I might have to use UUIDs to implement "listeners" here. Otherwise I can't remove listeners -- because functions are not Eq
01:35:21<roconnor>bot: A leap second is a positive or negative one-second adjustment to the Coordinated Universal Time (UTC) time scale that keeps it close to mean solar time.
01:35:21<Gracenotes>at least, not in a sane way
01:35:49<Gracenotes>although there must be a better name than listeners. perhaps "hooks"
01:35:54<roconnor>Gracenotes: why use UUIDs
01:36:04<roconnor>just have the listener return the delistening function
01:36:12<Berengal>Gracenotes: Put them in a structure, give them a name. Why UUID?
01:36:15<Berengal>Or use slots...
01:36:19<roconnor>the listener insertion function return the ...
01:36:24<roconnor>you know what I mean
01:36:32<Gracenotes>Berengal: well. a name would be an ID in this case :)
01:36:44<Berengal>roconnor's idea is also sound
01:37:13<Gracenotes>roconnor: well. a delistening function would have to identify the listener somehow
01:37:22<Gracenotes>UUIDs aren't a bad way to do this, eh?
01:38:03<roconnor>Gracenotes: sure, but that doesn't need a universally unique id. Just a locally unique one.
01:38:24<Gracenotes>roconnor: well. yes. perhaps I went too crazy with acronyms
01:38:27<roconnor>there is probably a clever way that needs no ids at all
01:38:31<Gracenotes>just some sort of counter
01:38:38<crutex>are you sure that's proper syntax?
01:38:39<Berengal>How are these listeners stored?
01:39:22<Gracenotes>Berengal: data Listener s = forall a. Listener (MyEvent -> MyMonad s a)
01:39:22<vininim_>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5242#a5242
01:39:36<crutex>oh Gracenotes you're such a dullard
01:39:47<Gracenotes>I could easily add an Integer there
01:39:54<roconnor>some sort of IORef ought to work as ID.
01:39:54<Gracenotes>crutex dear, you know I can't help it!
01:39:56<vininim_>previous paste gets a sleeping process with 0 seconds runtime
01:40:04<roconnor>or MVar
01:40:07<roconnor>or whatever
01:40:13<Berengal>Gracenotes: I meant how are they stored after they're hooked in?
01:40:16<Gracenotes>roconnor: and storing it in a [Listener s]
01:40:21<crutex>how would you represent categorical hierarchy in a rdbms
01:40:33<Gracenotes>er, @Berengal
01:41:10<Gracenotes>adding an Integer would provide a way to use delete, which requires Eq, or even better -- a Set -- which requires Ord
01:41:33<crutex>Gracenotes are you by chance a woman
01:41:46<Gracenotes>and when an Event is received the idea is to cycle through 'em all
01:41:59<crutex>that is not meant to sound passive aggressive
01:42:06<crutex>pure inquery
01:42:19<Gracenotes>crutex: isn't all gender by chance?
01:42:35<crutex>at some level everything is by chance
01:42:45<crutex>are you by chance /a woman/ though
01:42:54<Gracenotes>no.
01:42:56<Berengal>Gracenotes: Okay, go ahead, an id couldn't hurt
01:42:57<vininim_>how dare you talk about chance on a pure fuctional language channel?
01:43:22<crutex>Gracenotes are you denying that you are a woman because you are afraid of #haskell thinking less of you
01:43:24<Gracenotes>vininim_: in a nondeterminism monad
01:43:26<Berengal>ACTION still wonders if there could be a functional answer
01:43:30<crutex>you can answer me in PM if you want
01:43:44<Gracenotes>I don't think this is the case
01:43:54<crutex>ok
01:44:40<crutex>sorry didn't mean for that to be awkward
01:44:57<crutex>sooo
01:45:02<crutex>how would you represent categorical hierarchy in a rdbms
01:45:34<Gracenotes>Berengal: it all is very imperative, an IRC bot with a lot of functionality. I think FRP might provide a way to do it nicely, but I don't understand it very well, and I think most people don't
01:46:35<Cale>crutex: I don't understand your question? Is it in any way related to Haskell?
01:46:43<crutex>cale not necessarily
01:46:46<crutex>does it have to be
01:46:52<crutex>to talk here
01:46:53<Cale>crutex: Categorical hierarchy?
01:47:09<crutex>eh yes like a hierarchy of categories is what i meant, not sure if my english was correct
01:47:30<Cale>Well, in this channel when people use the word 'category', they tend to mean something other than the usual English meaning.
01:47:31<Berengal>Gracenotes: If dropping into IO isn't too much a bother, [IORef (Maybe Listener)] ?
01:47:39<Cale>(it has a mathematical definition)
01:47:44<crutex>i see
01:48:11<crutex>i meant a category as ... a category that items could belong to, and if you belong to a category you belong to all the parents of that category
01:48:21<Gracenotes>Berengal: well.. the monad I'm using is a MonadIO.
01:48:24<Cale>yeah
01:48:25<Cale>okay
01:48:34<Gracenotes>Berengal: what's the Maybe for?
01:48:57<Gracenotes>hm.. removing references to Listeners?
01:49:04<crutex>Cale surely a parent child column for each would not be an efficient way, at least the querying would be inefficient?
01:49:22<Cale>Well, relational databases are supposed to make joins of that kind efficient.
01:50:08<Cale>(If they didn't there wouldn't be much point in calling them relational)
01:50:13<olivierp>is there anything that would prevent me from exporting a type constructor from a module? when I list the constructors in the where () clause of the module they're reported not to be in scope. The two constructors are for GADTs, maybe that's related? i can access them from the outside when exporting everything (no where clause) though.
01:50:35<crutex>Cale i'm having a hard time visualizing what the table(s) would look like
01:50:39<Berengal>Gracenotes: Right, so addListener :: Listener -> ListenerList -> IO (ListenerList, IO ()); addListener listener list = do ref <- newIORef (Just listener); let derefListener = writeIORef ref Nothing; return (ref:list, derefListener)
01:51:00<crutex>i'm kind of nub @ it
01:51:30<Gracenotes>hm
01:51:48<p_l>crutex: It's quite easy to model a tree using tables. Define fields: ID and parent, and you can have it done.
01:51:58<crutex>right
01:52:05<crutex>but how would the queries look :X
01:52:36<crutex>if the items are linked to only 1 category
01:53:06<crutex>depending on the level of inheritence that would be a low of work for 1 query wouldn't it
01:53:10<crutex>*lot
01:53:11<hatds>constructors are exported as 'subordinate' names, could that be the problem?
01:53:19<p_l>crutex: for finding all members of given category... SELECT * FROM table WHERE parent = (SELECT id FROM table WHERE name='name');
01:53:45<hatds>i.e. you aren't accidentally exporting just the typename
01:53:59<p_l>crutex: that however requires a serious RDBMS - I heard MySQL 5.x still fails performance hard with that kind of query
01:54:14<crutex>p_l what if it is say 4 or 5 levels deep
01:54:28<Cale>crutex: So you have a table of categories along with their parent, and then you have a table of items along with the smallest category in which they belong.
01:54:38<crutex>yes cale
01:55:31<p_l>crutex: that was if you know the node whose leafs you wanted, assuming your category was shaped into a tree
01:56:34<Cale>Hmm, it seems that plain SQL isn't really good for taking transitive closures.
01:56:59<Cale>I suppose you could just maintain another table with the transitive closure.
01:57:12<Cale>But that's a bit ugly.
01:59:07<p_l>crutex: you can maintain all links in one table, and various kinds of objects in other tables
01:59:54<crutex>http://i39.tinypic.com/sxmbro.jpg
01:59:56<crutex>here's a pic
02:01:11<Cale>crutex: Right, you need a table which has two columns, parentID and childID, and which expresses not just the direct relationships between categories, but all of them. That is, it'll have an entry with parentID = 2 and childID = 7
02:01:30<crutex>hehe, seriously
02:01:39<crutex>all possible paths? O_O
02:01:42<vininim_>ok, just completly ignore me
02:01:43<Cale>yeah
02:01:48<crutex>ok
02:01:53<crutex>wasn't sure if there was a pretty way of doing this
02:01:54<vininim_>my example expected the list from standard input heh
02:02:02<hatds>how does the time/allocation report determine the number of entries of a cost center? If you pass a function as a parameter and call it a zillion times at different arguments you won't get more than 1 'entry' ?
02:02:04<vininim_>so of course it was sleeping
02:02:25<Cale>crutex: There are various nonstandard ways of constructing the transitive closure automatically, but plain standard SQL doesn't have one.
02:03:04<crutex>how would it be done then
02:03:28<Cale>It can be constructed somewhat efficiently in stages, where you find all the new relationships you can at each stage, and insert them into the table until there's nothing more to add.
02:04:15<crutex>it seems like this would be a fairly common problem
02:04:16<crutex>is it?
02:04:47<crutex>is mysql/postgre even a good solution for it
02:07:32<grncdr>crutex: I didn't get your whole question but...
02:07:51<grncdr>representing trees in a database is a fairly common problem/practice
02:08:10<grncdr>and a relation database is in fact a terribly inelegant way to store a tree
02:08:14<grncdr>*relational
02:08:59<Cale>It's too bad that there isn't a good way to express the transitive closure in SQL.
02:09:23<Cale>But if you have another language handy which you're manipulating your database with, it's fairly easy to construct.
02:09:27<tompledger>Some SQL engines have it as an extension, don't they?
02:09:32<Cale>tompledger: It seems so.
02:09:34<crutex>cale what do you mean
02:09:38<crutex>this is with postgre and php
02:14:34<vininim_>uh.. I wonder why hmatrix doesn't export joinVert and joinHoriz
02:15:07<tompledger>#type joinVert
02:15:19<duaneb>hi people
02:15:24<duaneb>I'm trying to have an instance of Read
02:15:29<duaneb>and I'm not sure how to go about it
02:15:34<Cale>crutex: Create a new table and start by copying into it the direct tree edges obtained from the other table. Then, insert into the new table (x,x) for each category ID (making it reflexively closed), and then repeatedly insert into it (x,z) where (x,y) and (y,z) are already in it, which is the same as inserting into it an inner join of it with itself where the appropriate columns match
02:15:38<duaneb>I guess
02:15:40<vininim_>joinVert :: Element t => [Matrix t] -> Matrix t
02:15:42<duaneb>there's readsPrec
02:15:48<duaneb>but It's not clear how that works
02:16:00<olivierp>hatds: sorry, didn't notice your reply. both the data types and the constructors are exported, and they have different names
02:16:40<hatds>olivierp: maybe hpaste it if you still have problems
02:16:45<crutex>ok thank you a lot for your awesome input cale
02:17:12<olivierp>hatds: hmm, it seems I only need to export the data types, and the constructors are exported automatically
02:17:46<olivierp>hatds: it works fine if i just remove the constructors from the module where clause
02:17:53<hatds>olivierp: that should only happen with Typename(..) syntax
02:18:09<olivierp>hatds: do you know what the rules for this are?
02:18:18<tompledger>vininim_: thanks, I haven't got the hang of lambdabot yet. Perhaps joinVert is only for use by trusted callers within its module, because its return type doesn't cover the "Oi! Incompatible height/width" situation?
02:18:24<duaneb>ahh, nm
02:18:25<duaneb>I got it
02:18:27<hatds>olivierp: http://www.haskell.org/onlinereport/modules.html
02:18:40<hatds>probably the one place where the gory details of the haskell report are often needed
02:18:42<olivierp>hatds: no i didn't use typename(..), but they're GADTs
02:18:47<olivierp>thanks
02:18:55<vininim_>tompledger: it does
02:19:05<vininim_>joinVert ms = case common cols ms of Nothing -> error "joinVert on matrices with different number of columns" Just c -> reshape c $ join (map flatten ms)
02:19:26<tompledger>Oh, OK
02:19:56<BMeph>Sounds like a snap to do in Q (the DB stuff). :)
02:20:03<Cale>So it'd be like (untested, and I only infrequently use SQL), INSERT INTO cats_tc SELECT tc1.parentID, tc2.childID FROM cats_tc AS tc1 INNER JOIN cats_tc AS tc2 ON tc1.childID=tc2.parentID
02:20:09<vininim_>@type common
02:20:10<lambdabot>Not in scope: `common'
02:20:25<Cale>crutex: ^^ have a look at that and see if it works/makes sense :)
02:20:42<crutex>yes cale i will have to digest it later :}
02:20:44<olivierp>hatds: hmm ok got it. I think i don't actually need the constructors exported, they're only used in a Template Haskell splice that's defined in the same module (but used outside)
02:21:10<duaneb>ahh, never mind
02:21:11<duaneb>got it
02:21:20<olivierp>hatds: i guess TH isn't quite the same as copy/pasting the code at the splice location
02:25:26<kniu>:t (.) (.)
02:25:27<lambdabot>forall b c a a1. (a1 -> b -> c) -> a1 -> (a -> b) -> a -> c
02:25:48<crutex>Thanks again!
02:26:31<vininim_>> foldl1 f [x y z w]
02:26:32<lambdabot> Couldn't match expected type `SimpleReflect.Expr
02:26:39<Cale>It seems really silly that SQL, being based on relational algebra, would not include something such basic things as the transitive or reflexive closure of a relation...
02:26:45<vininim_>> foldl1 f [x y z]
02:26:46<lambdabot> Couldn't match expected type `SimpleReflect.Expr
02:26:56<Cale>-something
02:27:04<vininim_>> foldl1 f [x, y, z]
02:27:06<lambdabot> f (f x y) z
02:27:17<vininim_>heh
02:31:22<vininim_>tompledger: just in case you are interested <|> is joinH and <-> is joinV in hmatrix
02:32:22<tompledger>A rows by any other name...
02:32:32<duaneb>anyone know parsec?
02:32:38<duaneb>I have this thing: liftM (Number . (read::String->Int)) (optional (oneOf "-+") >> many1 digit)
02:32:45<duaneb>where data Number = Number Int
02:32:55<kniu>so I'm trying to install reactive-glut.
02:33:04<duaneb>and yet, (read::String->Number) "-89" leads to Number -89
02:33:08<duaneb>err, Number 89
02:33:11<kniu>one of the dependencies depends on two different versions of quickcheck.
02:33:21<kniu>indirectly.
02:33:47<Cale>duaneb: you appear to be discarding the sign
02:33:54<kniu>how do I fix that?
02:34:13<Cale>duaneb: remember that >> discards the result of its left parameter
02:34:15<duaneb>Cale: I do indeed
02:34:32<duaneb>Cale: yea, but doesn't '>>=' pass the result to the next function?
02:34:37<Cale>kniu: Just install the deps one by one.
02:34:38<duaneb>I'm not sure how to manage this....
02:34:52<kniu>huh
02:34:58<Cale>kniu: But it can be tricky, since the latest version of everything doesn't all work together.
02:35:09<Cale>kniu: The dependencies for reactive are a mess right now.
02:35:11<kniu>well then.
02:36:38<Cale>duaneb: Oh, the other problem is that optional unconditionally discards the result of the parser you apply it to
02:36:47<duaneb>great.
02:36:53<Cale>You can use optionMaybe
02:37:12<duaneb>ACTION thinks this is too complicated
02:37:47<duaneb>whatever, I'll just do it :P
02:37:48<Gracenotes>hm. Is there an MVar with a timer?
02:37:54<Cale>do sign <- optionMaybe (oneOf '+-'); rest <- many1 digit; return (Number (read (fromMaybe '+' sign : rest)))
02:38:03<Gracenotes>well. "timeout", that is
02:38:08<Cale>duaneb: ^^ how about that?
02:38:22<duaneb>that's what I was writing
02:38:23<duaneb>so
02:38:25<duaneb>I agree!
02:38:31<Gracenotes>( ≖‿≖)
02:38:41<duaneb>Gracenotes++
02:38:51<Gracenotes>okay, so would it be possible to implement an MVar lookup with a timeout?
02:39:09<Gracenotes>ACTION doesn't see one in the docs
02:39:14<Cale>Gracenotes: Like, try to take the MVar, and if it's empty, block for so long before giving up and returning Nothing?
02:39:24<Gracenotes>yes
02:39:35<Cale>You can do that with an extra thread...
02:39:38<Gracenotes>it is somewhat important here
02:40:35<Gracenotes>Cale: I think I may have threads being created left and right here :) At least Haskell threads a "green" so to say
02:40:37<Gracenotes>are
02:40:52<Cale>Hmm, there's also tryTakeMVar...
02:41:24<Gracenotes>well. that would amount to crude sleeping blocks
02:42:02<duaneb>Cale: works great
02:42:13<SamB>yes, but you could use tryTakeMVar to avoid spawning the thread when you can just take the MVar right off ...
02:42:40<Berengal>Isn't there a timeout :: Int -> IO a -> IO a somewhere?
02:43:13<Gracenotes>SamB: this is very unlikely in my case
02:43:23<Cale>yeah...
02:43:41<Cale>System.Timeout might do it
02:43:48<Cale>timeout :: Int -> IO a -> IO (Maybe a)
02:43:55<SamB>so, why do you want to do that anyway ?
02:44:26<Cale>The Int is in microseconds...
02:45:08<Berengal>Cale: Looks like picoseconds or something to me...
02:45:23<Cale>Multiply by 10^6...
02:45:39<Gracenotes>SamB: an empty MVar is created, a listener is added to a list which only puts in the MVar if a particular event is received, and once the MVar is filled the idea is to remove the listener and yield the event
02:45:45<Berengal>Ah, yes, micro..-
02:46:19<Cale>Gracenotes: So, you should be able to timeout (10^6) (takeMVar v)
02:47:13<Gracenotes>Cale: hm, ingenious! Functional programming for the win.
02:47:19<Gracenotes>except, it is the same as your previous idea
02:47:25<Gracenotes>it creates a new "kill thread"
02:47:28<Cale>yeah
02:47:28<Gracenotes>but at least it is in the stdlib
02:47:37<Cale>http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/System-Timeout.html#timeout
02:47:49<Gracenotes>right
02:47:50<hackagebot>MemoTrie 0.4.5
02:47:52<Cale>The implementation is careful, but straightforward :)
02:48:36<Cale>The behaviour for negative parameters seems out of place though.
02:48:40<Gracenotes>it does seem limited though.
02:48:50<Gracenotes>particularly with IO. As noted in the docs.
02:49:45<Cale>It does the best that's reasonable for it to do.
02:49:55<Gracenotes>overall, concurrency needs more fine-tuning, more concurrency primitives and concurrent data structures. but this'll do
02:50:00<Gracenotes>:)
02:50:12<Cale>C code doesn't have a notion of async exceptions which could be relied on.
02:50:12<dons>more concurrency primitives?
02:50:12<lambdabot>dons: You have 1 new message. '/msg lambdabot @messages' to read it.
02:50:24<dons>more concurrent data structures? (mutable ones?)
02:50:26<Cale>So FFI calls are always going to be strange...
02:50:43<Cale>Actually, I think the comment in the docs is fairly positive about how well it works.
02:50:48<dons>or you mean things like Chan et al? (concurrent queues)
02:51:42<Gracenotes>by primitives: explicit locks, conditions, etc. Even if they are just wrappers around MVar, a clean interface is good.
02:52:00<Cale>http://picturesforsadchildren.com/index.php?comicID=266
02:52:05<dons>what kinds of locks and conditions are missing?
02:52:06<Gracenotes>STM and TVar takes care of compare-and-swap-like operations nicely, which does put Haskell ahead of many things
02:52:15<Cale>Gracenotes: locks are worse than MVar...
02:52:27<Cale>Gracenotes: you can just use MVar ()
02:52:36<Gracenotes>Cale: yes. But, as I said, a wrapper.
02:52:55<Cale>Does something that simple really need a wrapper?
02:53:00<dons>MVars and TVars will be the primitive thread-aware shared memory abstraction primitives for the next few years.
02:53:29<Cale>Concurrency is important, but it's much less important than pure parallelism, I think.
02:53:30<Gracenotes>Conditions, as in waiting and signalling.
02:53:31<dons>there's fairly regular releases on hackage of things on top, though i'm hard pressed to find uses for some of them
02:53:41<Gracenotes>Chan needs more control over blocking and whatnot.
02:53:52<Cale>Gracenotes: There's an implementation of concurrent ML if you'd like :)
02:53:55<jmcarthur>Cale: and much harder than pure parallelism, too
02:54:09<Gracenotes>there aren't many ways to ensure atomic operations other than using an MVar ()
02:54:10<jmcarthur>actually
02:54:14<Berengal>It'd be nice to have a clean message-passing interface
02:54:17<Gracenotes>for instance, you could run into race conditions with Chan functions
02:54:23<jmcarthur>maybe the other way around, with STM :)
02:54:25<dons>Berengal: tried the actors library?
02:54:31<dons>pretty much identical syntactically to erlang.
02:54:42<Berengal>dons: No I haven't. Thanks for the tip
02:54:44<dons>Gracenotes: there's a bounded Chan on hackage.
02:55:02<dons>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/BoundedChan
02:55:06<dons>by a colleague of mine
02:55:14<dons>actors, http://hackage.haskell.org/cgi-bin/hackage-scripts/package/actor
02:55:43<Gracenotes>still, no reason that regular ol' Chan shouldn't be able to support more fine-tuned blocking options.
02:55:44<dons>actors compared w/ erlang, http://gist.github.com/111482
02:55:53<dons>Gracenotes: what do you want to be able to do?
02:57:13<Cale>dons: Does that come with an Erlang version?
02:58:01<Gracenotes>essentially, act as a queue where you can poll, retrieve an element on top as a (Maybe a), etc.
02:58:07<dons>yeah, on matthew's blog. http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx
02:58:29<dons>Gracenotes: sounds like a different library. maybe upload it?
02:58:39<Gracenotes>I think any linked blocking queue should be able to handle it
02:59:18<Gracenotes>also... there's not much support for timeout operations. System.Timeout is neat, although I'm not sure it's the best general-purpose solution :/
02:59:27<dons>you want to poll, rather than just sleeping until a value arrives (i.e. you want access to the top MVar's tryTake?
03:00:15<Gracenotes>dons: yeah. I'm not sure why there isn't more MVar functionality exposed >_>
03:00:26<dons>no one has needed it?
03:00:32<pumpkin>Gracenotes: write it and expose it!
03:00:40<pumpkin>it can be called Gracenotes' exposé
03:00:43<dons>or: it is trivial to roll your own, so people write that, and upload it.
03:00:49<Gracenotes>pumpkin: but that would be indecent!
03:00:59<dons>yay MVars. the great shared memory sync primitive
03:01:08<Cale>Gracenotes: It's fairly trivial to write a function which races a number of IO actions concurrently and takes the result of the first one to complete as well.
03:01:16<Gracenotes>at least I'm pretty happy with the MVar functionality.
03:01:42<Gracenotes>ACTION wonders if there have been any thread pools implemented, other than with the shootout
03:01:53<pumpkin>I saw something recently on hackage
03:01:56<gwern>Gracenotes: what, like the threadpool package on hackage?
03:02:03<Gracenotes>@hackage threadpool
03:02:03<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/threadpool
03:02:03<gwern>the 1000th package uploaded?
03:02:12<dons>Gracenotes: on hackage.
03:02:15<dons>gwern: months ago
03:02:24<Gracenotes>;_;
03:02:27<gwern>Gracenotes: incidentally, that feature is just a concatenation - it doesn't actually tell you if it exists
03:02:30<Cale>The cml library also has some very general operations for message protocols.
03:02:36<dons>gwern: 1299 packages.
03:02:43<gwern>the @hackage shortcut I've long felt is nonsense on stilts
03:02:56<dons>commit the change you want to see :)
03:03:00<gwern>dons: yeah, but the discuessions and cabalization of threadpool was months ago as well...
03:03:03<sbahra>"threadPool: Runs other programs in the manner of a thread pool"
03:03:10<sbahra>"Takes a single, optional argument which is the number of threads (the default is three). Give it the commands to run, one per line, through standard input. You may use blank lines to divide the commands into sections. The commands in a section will not be started until all the commands in previous sections are complete. "
03:03:11<sbahra>...
03:03:24<Gracenotes>hrm
03:03:26<gwern>dons: eh. can lb plugins do http lookups?
03:03:26<dons>dph also has a worker pool at the bototm
03:03:30<dons>sure
03:03:30<Gracenotes>so the thread pool is fixed, too
03:03:33<dons>?google woot woot
03:03:34<lambdabot>http://www.woot.com/
03:03:34<lambdabot>Title: Woot : One Day, One Deal (SM)
03:03:34<Cale>http://hackage.haskell.org/packages/archive/cml/0.1.1/doc/html/Control-Concurrent-CML.html
03:03:37<Gracenotes>no cached make-as-you-go thread pools
03:03:40<monochrom>The two commands @hackage and @faq are supposed to teach you basic combinator programming, i.e., the I and K combinators.
03:03:51<dons>Gracenotes: there's a lib for that. dph also has precisely that.
03:04:04<pumpkin><3 dph
03:04:09<gwern>monochrom: I always saw @faq as a demonstration of 'const'
03:04:24<monochrom>Yes that's K.
03:04:26<Gracenotes>for now, though, I would just be happy if someone made timeout support built into MVars :)
03:04:37<Cale>Gracenotes: why should it be built in?
03:04:45<BMeph>ACTION wonders how tough a Hoogle-like utility for Hackage packages would be...
03:04:52<Gracenotes>why shouldn't it be? I would find it useful.
03:05:03<Cale>Because System.Timeout does it perfectly
03:05:19<Gracenotes>by creating a thread.
03:05:25<pumpkin>a green thread
03:05:25<Cale>Huh?
03:05:33<Cale>Threads are like 24 bytes or something
03:05:34<sbahra>Gracenotes, the package is pretty useless.
03:05:42<Cale>It's not like it's expensive to make one :)
03:05:45<Gracenotes>pumpkin: yes, a green thread, I realize, but one nonetheless
03:05:58<Cale>Gracenotes: Threads are the natural way to do a timeout
03:06:05<pumpkin>a green thread is probably cheaper than any code you could write that simulated it
03:06:06<pumpkin> :P
03:06:07<Cale>Gracenotes: Even if it was built-in, it would use a thread.
03:06:12<gwern>BMeph: what would a hoogle for hackage be besides hoogle itself?
03:06:32<jinho>http://haskell.pastebin.com/m3973d6ff : can someone explain to me what's going on at line 21, specifically with (map renderJValue vs), thanks
03:07:05<Cale>jinho: That applies the function renderJValue to each of the elements of the list vs giving a new list
03:07:36<Cale>actually, that code seems excessive, doesn't it?
03:07:42<Cale>> intercalate ", " []
03:07:44<lambdabot> ""
03:07:45<pumpkin>:o http://blog.plt-scheme.org/2009/05/typed-scheme-20.html
03:07:48<jinho>Cale: taken from "Real World Haskell"
03:07:56<Cale>jinho: hmm, that's funny then :)
03:07:57<jinho>Cale: maybe it's not so real world
03:07:59<Cale>dons: !
03:08:00<Cale>hehe
03:08:05<Gracenotes>eh. It'd be nice if something were built straight into Control.Concurrent.MVar. For a concurrent primitive, it seems it should suppose timeouts
03:08:23<monochrom>map renderJValue [x,y,z] = [renderJValue x, renderJValue y, renderJValue z] if it helps.
03:08:23<Gracenotes>*support
03:08:25<pumpkin>Gracenotes: why build in special-case support when you have something more general?
03:08:30<Cale>renderJValue (JArray a) = "[" ++ intercalate ", " (map renderJValue vs) ++ "]"
03:08:35<Cale>would work just as well
03:08:40<Gracenotes>pumpkin: because it's annoying to work with two interfaces at the same time?
03:08:53<pumpkin>it shouldn't be :/ things are supposed to be composable
03:09:19<pumpkin><=< it!
03:09:22<pumpkin>:P
03:09:24<Gracenotes>>=>
03:09:26<Gracenotes><=<
03:09:29<Cale>Gracenotes: Consider that System.Timeout works not only with MVars but also with Chans and every other blocking concurrency structure
03:09:46<Cale>(including ones which have not yet been invented)
03:10:06<jinho>Cale: can you tell me what's going on with the renderJValue (JObject o) part? I can't wrap my head around (map renderPair ps)
03:10:07<Cale>As long as it's not making blocking FFI calls, it will work :)
03:10:14<codebliss>ACTION waits for the following to be legal. (:=) = (=)
03:10:29<Cale>jinho: Do you know what map is?
03:10:44<Cale>> map show [1,2,3,4,5]
03:10:46<lambdabot> ["1","2","3","4","5"]
03:10:53<jinho>right
03:11:05<Cale>jinho: So, if ps is a list of pairs
03:11:08<jinho>ok I'm an idiot
03:11:23<Cale>jinho: map renderPairs ps is the list of results of applying renderPair to each of those
03:11:32<jinho>Cale: I didn't realize a JSON object could hold a list of pairs
03:11:36<Cale>ah, okay
03:12:13<Gracenotes>well. I guess I still am a bit suspicious, and I'll see what I can do about Chan not refusing to expose (:O)
03:12:17<Cale>It seems whoever wrote that code for RWH didn't realise that intercalate gives an empty string when given an empty list.
03:12:20<mmorrow>Gracenotes: newtype MVarT a = MVarT (Mvar a); takeMVarT :: Int -> MVarT a -> IO (Maybe a); takeMVarT t (MVarT mv) = timeout t (takeMVar mv)
03:12:21<jinho>Cale: thanks though
03:12:40<pumpkin>Gracenotes: maybe it's a coverup!
03:12:47<mmorrow>Gracenotes: Chans are borked
03:12:50<mmorrow>Gracenotes: do:
03:12:57<Cale>"not refusing to expose"?
03:13:03<Gracenotes>sorry. cut out the "not"
03:13:19<pumpkin>b0rked
03:13:33<pumpkin>b0rk b0rk b0rk
03:13:35<Gracenotes>I have a knack for the worst against-my-original-meaning typos
03:13:36<Cale>mmorrow: Are they?
03:13:57<mmorrow>ghci> ch :: Chan Int <- newChan
03:13:57<mmorrow>ghci> forkIO (readChan ch >> return ())
03:13:57<mmorrow>ghci> isEmptyChan ch
03:14:01<Cale>http://hackage.haskell.org/packages/archive/cml/0.1.1/doc/html/Control-Concurrent-CML.html -- I'd like someone to try this library and see how it is :)
03:14:03<mmorrow>(it blocks!!)
03:14:15<Cale>Oh, right. That is pretty dumb.
03:14:32<pumpkin>:o
03:14:35<mmorrow>and it's an artifact of the implem... so the only solution is a different one
03:14:41<pumpkin>isEmptyCan can block?
03:14:45<pumpkin>*Chan
03:14:45<Cale>The equivalent written with TChan doesn't do that stupid thing though.
03:14:56<Gracenotes>isEmptyChan is an invitation for race conditions
03:14:58<pumpkin>isn't that just a bug that needs fixing?
03:15:04<Cale>Yes, it's just a bug.
03:15:08<mmorrow>(this is mine: http://moonpatio.com/repos/vacuum-gl/System/Vacuum/OpenGL/Q.hs)
03:15:21<pumpkin>much cooler name
03:15:25<mmorrow>pumpkin: the only way to fix it is a different implmentation though
03:15:27<pumpkin>I want to use a Q
03:15:28<Cale>and an easy workaround is just to use TChan with everything wrapped in atomically :)
03:15:37<pumpkin>your Q feels more rational ;)
03:15:42<monochrom>QChan?
03:15:54<mmorrow>it has a non-blocking getChanContents too!
03:16:03<Gracenotes>Q. Chan: sounds like an awesome name. for a person.
03:16:09<pumpkin>Quentin Chan
03:16:14<Gracenotes>make it so
03:16:15<pumpkin>Quentin Charantino
03:16:22<Cale>You should replace Chan with it...
03:16:23<mmorrow>ACTION was just thinking that
03:16:25<monochrom>"QChan is a channel for requesting the Q community to do magic for you, for example change the user's input so it no longer triggers a bug in your program"
03:16:35<mmorrow>(thinking Quentin Charantino)
03:16:40<pumpkin>:D
03:17:45<pumpkin>Cale: did lambdabot forget quotes recently?
03:17:57<Gracenotes>hm. I suppose I can live with timeouts being inexact. after all, an amount like "10 seconds" is rather arbitrary in the scheme of things
03:17:57<Cale>pumpkin: It is possible?
03:18:04<monochrom>It forgets quotes every year.
03:19:45<mmorrow>Gracenotes: at the second scale Control.timeout should be more than ok
03:19:55<mmorrow>(or threadDelay for that matter)
03:21:23<mmorrow>Cale: i was reading somewhere that STM updates are fundamentally O(n), where n is the size of the structure being updated
03:21:34<mmorrow>(something about transaction logs or something)
03:21:52<Cale>mmorrow: whaaat... that sounds implausible...
03:21:57<mmorrow>or something to the effect that there's an inherent limitation
03:22:06<mmorrow>ACTION looks for quote
03:22:15<mmorrow>i think it was in that new ghc-rts paper
03:22:56<monochrom>If you keep running into contentions yes.
03:23:45<QtPlaty[HireMe]>The "default" keyword is a ghc extention?
03:23:53<Cale>mmorrow: Do you mean that every part of the structure is being updated?
03:23:59<Cale>QtPlaty[HireMe]: no
03:24:07<monochrom>The "default" keyword is in Haskell98.
03:24:40<monochrom>http://www.haskell.org/onlinereport/decls.html#sect4.3.4
03:25:14<roconnor>@roll 1300000d6
03:25:14<lambdabot>Consider it noted.
03:25:18<roconnor>damn it
03:25:20<roconnor>I always do that
03:25:26<mmorrow>hmm, not that one. i think i know which one exactly that quotes (or the quote i remembered incorrectly) is from
03:25:32<monochrom>http://www.hck.sk/users/peter/HaskellEx.htm is a very useful page for looking up Haskell98 grammar and where to find details in the Haskell98 report.
03:25:47<mmorrow>Cale: i'm not sure exactly what that remark meant in particular
03:26:24<monochrom>@roll
03:26:25<lambdabot>Plugin `tell' failed with: Prelude.head: empty list
03:26:29<Cale>mmorrow: It certainly takes O(n) time to commit a transaction log which has n entries in it.
03:26:36<monochrom>Oh, roll = tell
03:26:54<Cale>@dice 1300000d6
03:26:55<lambdabot>1300000d6 => 4549630
03:27:00<mmorrow>oh nice. this might be very interesting to anyone that wants to get up to speed with haskell concurrency stuff http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/AFP08-notes.pdf
03:27:52<mmorrow>Cale: the context was comparing concurrent algo speed/complexity between implems using {IORef+atomicModifyIORef, MVar, STM}
03:28:11<mmorrow>(can anyone think off-hand what paper that is?)
03:28:14<pumpkin>@quote pumpkin
03:28:14<lambdabot>pumpkin says: makes the next internet hit video, 2 natural transformations, 1 functor
03:28:30<pumpkin>oh I guess lambdabot quotes are room-specific?
03:28:58<mmorrow>Cale: found it
03:29:09<mmorrow>www.haskell.org/~simonmar/papers/concurrent-data.pdf
03:31:54<gwern>pumpkin: no, quotes are all from a single file
03:32:01<gwern>which contains no info about origin
03:32:21<vininim_>@src endBy
03:32:21<lambdabot>Source not found. :(
03:32:30<pumpkin>gwern: it's odd, someone did @quote pumpkin four times in a row, in #haskell-blah and got the same quote each time
03:32:39<pumpkin>gwern: did you figure out your list comprehension thing by the way?
03:32:42<gwern>that's randomness for you
03:33:14<gwern>pumpkin: Cale figured that it was conflicting rules resulted in a call to a library map versus an inlined map, but he got different results on 6.10.3
03:33:16<Twey>‘Nine... nine... nine... nine... nine... nine... nine... nine...’
03:34:03<Cale>gwern: The results I got in 6.10.3 were similar enough not to worry about
03:34:17<gwern>@qoute Hobbes
03:34:17<lambdabot>Maybe you meant: quote vote
03:34:19<Cale>gwern: But on 6.10.2 I can imagine those performing differently, do they?
03:34:30<gwern>oh come on, that's obviously closer to quote than vote -_-
03:34:37<gwern>@quote Hobbes
03:34:37<lambdabot>thetallguy says: Using and advocating Haskell is like being Calvin (and Hobbes). To you, it's alive, real, a true delight. To those who know better, it's a stuffed tiger.
03:34:40<pumpkin>are there any things that need figuring out to replace foldr/build fusion with stream fusion in GHC?
03:34:53<pumpkin>or does it just need someone to implement it?
03:35:30<Cale>pumpkin: I thought it was implemented at least in part...
03:35:39<pumpkin>well, as a library
03:35:52<pumpkin>but there was talk of replacing existing fusion with the library
03:37:11<mmorrow>what's the difference? (not rhetorical)
03:37:32<pumpkin>stream fusion helps with many more operations, I think
03:37:42<pumpkin>and seems simpler conceptually, to me at least
03:37:47<mmorrow>is there a description of it somewhere?
03:37:52<mmorrow>@type build
03:37:53<lambdabot>Not in scope: `build'
03:37:55<pumpkin>stream fusion?
03:37:58<pumpkin>or foldr/build?
03:37:59<mmorrow>, build
03:38:00<lunabot> luna: Not in scope: `build'
03:38:03<mmorrow>stream
03:38:12<dmwit>It's buildr.
03:38:21<pumpkin>it is?
03:38:32<pumpkin>mmorrow: http://www.cse.unsw.edu.au/~dons/papers/stream-fusion.pdf
03:38:41<pumpkin>http://hackage.haskell.org/trac/ghc/ticket/915
03:39:52<mmorrow>, [$ty| build |]
03:39:56<lunabot> forall a . (forall b . (a -> b -> b) -> b -> b) -> [] a
03:40:03<pumpkin>see, that isn't a friendly function signature :P
03:40:10<gwern>(wow, version changed from 6.4.2)
03:40:20<pumpkin>stream fusion is a lot prettier in my opinion :)
03:40:22<gwern>-> [] a
03:40:23<gwern>?
03:40:28<pumpkin>[a]
03:40:30<mmorrow>pumpkin: oh nice, i've actually looked at this paper when i first started with haskell
03:40:42<pumpkin>it's a cool idea
03:41:07<mmorrow>it should be interesting to go over it again
03:41:22<pumpkin>"To replace GHC's existing list fusion, we'll need to work out how concatMap is optimised, and push the desugaring for list comprehensions into GHC."
03:41:34<pumpkin>so I guess concatMap is the painful one
03:44:06<Cale>pumpkin: I don't think that build is so bad...
03:44:17<Cale>pumpkin: But stream fusion is indeed better.
03:45:02<Cale>It might be even nicer to have some extremely general implementation of fusion as part of the compiler though, I think.
03:45:26<mmorrow>ghc uses either build/foldr or this http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2260 method to desugar list comps
03:45:27<Cale>(that works across all algebraic types, say)
03:45:36<mmorrow>i don't think it actually uses concatMap
03:45:51<pumpkin>wow
03:45:59<mmorrow>that'd be pretty cool to have *-comprehensions
03:46:05<mmorrow>(where * can be array, vector, whatever)
03:46:08<pumpkin>Cale: I agree
03:49:49<mmorrow>pumpkin: here's that listcomp desugaring code (here done on the TH ast) if you're interested http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2490#a2490
03:49:58<mmorrow>this is the "classic" method apparently
03:50:05<mmorrow>(the other being build/foldr)
03:51:07<hackagebot>LslPlus 0.4.1.1
03:52:30<pumpkin>cool :)
03:52:41<mmorrow>pumpkin: i followed along with http://moonpatio.com/repos/LIBS/Language/ghc/compiler/deSugar/DsListComp.lhs for that algo
03:53:12<mmorrow>i wish darcs.haskell.org sent .l?hs as text/plain
03:53:28<pumpkin>I wish my browser wouldn't download the .gz patches
03:53:39<mmorrow>heh, i actually like that "feature"
03:53:57<mmorrow>err, you mean it doesn't decode them?
03:54:01<pumpkin>yeah
03:54:04<mmorrow>heh
03:54:10<pumpkin>I'd love to see them in the browser without downloading and unpacking them
03:55:51<mmorrow>still have to fill in the case for
03:55:53<mmorrow>, 'LetS
03:55:55<lunabot> Language.Haskell.TH.Syntax.LetS
03:55:59<mmorrow>now that i look at that
03:56:21<mmorrow>(go e (LetS decs : ss) xs = error "don't do LetS")
03:56:23<pumpkin>I wonder what projects people will work on at the hackathon
03:56:27<pumpkin>there are so many things I want to work on
03:57:50<pumpkin>is there a package out there that builds "tied knot" graphs?
03:57:56<pumpkin>that seems like it would be pretty cool
03:58:41<ray>hackathons are filled with boring people who disapprove of crashing drunkenness
03:58:47<pumpkin>:o
03:58:51<pumpkin>so I take it you won't be going to this one?
03:59:27<ray>not unless there's an open bar
04:00:20<mmorrow>ray: just bring a waterbottle
04:00:35<ray>or a flask :)
04:00:55<mmorrow>(i wasn't meaning to put water in the waterbottle ;)
04:01:26<ray>naturally
04:01:32<pumpkin>151bottle
04:02:54<pumpkin>@seen bsp
04:02:54<lambdabot>I haven't seen bsp.
04:02:56<SamB>ray: what, no alcohol-fueled coders attend hackathons, you say?
04:03:08<pumpkin>does anyone know what his nick on IRC is, or if he just never comes online?
04:03:19<shapr>who?
04:03:34<pumpkin>max bolingbroke
04:03:46<gwern>don't know of him on irc, sry
04:03:47<shapr>I don't know if he shows up on irc.
04:04:00<shapr>Not that I've been online much the past year.
04:05:55<pumpkin>ah :)
04:08:08<Gracenotes>hm.
04:08:13<pumpkin>hm. indeed
04:08:39<ray>philadelpha's not unreachable from here i guess
04:08:56<pumpkin>you should go!
04:08:59<ray>which is good, otherwise it'd be garbage collected
04:09:07<pumpkin>geek.
04:09:16<pumpkin>nerd?
04:09:18<pumpkin>what's the difference
04:09:45<ray>i'm not sure
04:09:52<pumpkin>anyway, one of those
04:09:55<Gracenotes>quizas
04:09:55<ray>i'm not either, just the victim of an unfortunate series of events
04:10:24<pumpkin>Gracenotes: zomg foreign languidge
04:10:53<dmwit>ray: You should definitely come!
04:11:19<dmwit>Also, geek is anyone obsessed with sci-fi or fantasy; nerd is anyone obsessed with technology. You're welcome.
04:11:20<ray>i'll certainly consider it, since it's not tomorrow or anything
04:11:22<Gracenotes>..
04:11:24<Gracenotes>quiza
04:11:25<Gracenotes>s
04:11:29<pumpkin>Gracenotes will only go if we speak spanish there
04:11:32<pumpkin>dmwit: thanks :)
04:12:10<Gracenotes>dmwit: to the contrary. I think geek is someone obsessed with technology; nerd is obsessed with culture
04:12:25<dmwit>Uh, culture?
04:12:30<Gracenotes>my connotations vs. yours seem reversed >_>
04:12:39<lament>so there's still no way to split a string given a separator? :(
04:12:41<Gracenotes>dmwit: yes. e.g. Star Wars nerd, WoW nerd, etc.
04:12:45<pumpkin>@hackage split
04:12:46<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split
04:13:02<dino->lament: Funny you should mention, I was tinkering with something today..
04:13:06<Gracenotes>vs. programming geek, rocket science geek
04:13:22<dmwit>Well, for what it's worth, the dictionary says a geek is a person with an unusual or odd personality, and a nerd is a student who studies excessively.
04:13:34<lament>ACTION mumbles
04:13:57<lament>pumpkin: :(
04:14:00<dino->If you have Parsec instanced into Applicative: p target = (,) <$> (manyTill anyChar $ try $ string target) <*> many anyChar
04:14:06<pumpkin>lament: it's a nice package :)
04:14:18<pumpkin>:o
04:14:29<lament>pumpkin: splitting lists is not a package. It's not even a source file.
04:14:33<dino->You get the (before, after) pair without the target string
04:14:36<lament>It's a couple functions and they should reside in Data.List
04:14:37<pumpkin>lament: ?
04:14:43<mmorrow>lament: i rewrite the it every day probably at least 3 times if that counts :/
04:14:44<pumpkin>lament: look at the package I linked to
04:14:47<mmorrow>s/the//
04:14:55<lament>pumpkin: that's what i'm saying.
04:15:01<lament>pumpkin: installing a whole package for this is crazy.
04:15:03<pumpkin>lament: there are several different ways of doing it... it's not just a couple of functions
04:15:13<Gracenotes>dmwit: mm. Well those are vague. I tend to view a nerd's obsessions as more popular-culture-y than a geek's. But you can only splice meaning so much... hm.
04:15:17<mmorrow>(actually chunk is what i rewrite every day)
04:15:29<pumpkin>do you keep the separators, discard them, do you split based on conditions or constants, or lengths
04:15:33<ray>splitting combinators! =D
04:15:33<pumpkin>things like that
04:15:36<mmorrow>@let chunk _ [] = []; chunk n xs = let (ys,zs) = splitAt n xs in ys : chunk n zs
04:15:38<lambdabot> Defined.
04:15:40<Gracenotes>they can't really be viewed as opposites.
04:15:42<pumpkin>ray: that's what it is
04:15:46<mmorrow>i can do that in mah sleep now
04:15:50<lament>pumpkin: it's a single function in both Python and C#.
04:15:50<Gracenotes>anyway. </personal connotations>
04:15:58<pumpkin>lament: that isn't as flexible :D
04:16:11<pumpkin>lament: and doesn't work on arbitrary lists
04:16:19<mmorrow>> plit
04:16:20<lament>:\
04:16:21<mmorrow>> split
04:16:21<lambdabot> Not in scope: `plit'
04:16:23<lambdabot> Overlapping instances for GHC.Show.Show (g -> (g, g))
04:16:23<lambdabot> arising from a use...
04:16:46<dmwit>> split (0, 0)
04:16:47<lambdabot> No instance for (System.Random.RandomGen (t, t1))
04:16:47<lambdabot> arising from a use of ...
04:17:03<dmwit>:t mkStdGen
04:17:04<lambdabot>Int -> StdGen
04:17:09<dmwit>> split (mkStdGen 0)
04:17:09<mmorrow>@let splat _ [] = []; splat p xs = case break p xs of ([],zs) = zs; (ys,zs) = ys : splat p zs
04:17:10<lambdabot> (2 40692,40014 2147483398)
04:17:10<lambdabot> Parse error
04:17:13<lament>pumpkin: there's a kind of fine balance between flexibility and usability
04:17:18<pumpkin>lament: split :: Splitter a -> [a] -> [[a]] is nice, I think
04:17:26<mmorrow>@let splat _ [] = []; splat p xs = case break p xs of ([],zs) -> zs; (ys,zs) -> ys : splat p zs
04:17:28<lambdabot> <local>:13:80:
04:17:28<lambdabot> Occurs check: cannot construct the infinite type: a = [a...
04:17:30<dmwit>mmorrow: needs more {}
04:17:47<dmwit>Oh, I guess not.
04:17:55<pumpkin>lament: it's pretty usable :P but if you can decide on a single good meaning (with justification) of split to add to the std lib, maybe they'll add it?
04:18:01<mmorrow>@let splat _ [] = []; splat p xs = case break p xs of ([],zs) -> [zs]; (ys,zs) -> ys : splat p zs
04:18:03<lambdabot> Defined.
04:18:12<mmorrow>can haz cowbell?
04:18:30<lament>> splat "," "hello,world"
04:18:32<lambdabot> Couldn't match expected type `a -> GHC.Bool.Bool'
04:18:38<lament>er
04:18:41<ray>i should write some mahjong combinators
04:18:43<dmwit>mmorrow: I think it needs more drop now.
04:18:46<pumpkin>GHC.Bool.Bool :o
04:18:47<mmorrow>> splat (==',') "hello,world"
04:18:47<lament>> splat ',' "hello,world"
04:18:49<lambdabot> Couldn't match expected type `a -> GHC.Bool.Bool'
04:18:50<lambdabot> ["hello",",world"]
04:18:51<pumpkin>where did that come from?
04:18:53<mmorrow>crapp
04:18:56<dmwit>> splat (==',') "hello,bad,world"
04:18:58<lambdabot> ["hello",",bad,world"]
04:19:11<mmorrow>@let splatter _ [] = []; splatter p xs = case break p xs of ([],zs) -> [zs]; (ys,zs) -> ys : drop 1 (splatter p zs)
04:19:13<lambdabot> Defined.
04:19:20<pumpkin>you need a wrangle in there
04:19:20<mmorrow>> splatter (==',') "hello,world"
04:19:22<lambdabot> ["hello"]
04:19:26<mmorrow>gah!
04:19:30<mmorrow>oh, n/m
04:19:32<dmwit>hehehe
04:19:33<mmorrow>that worked
04:19:38<mmorrow>heh
04:19:51<dmwit>> splatter (==',') "hello,good,world"
04:19:53<lambdabot> ["hello"]
04:19:58<dmwit>fail
04:20:02<mmorrow>the song rawhide plays in my head whenever i write a function named wrangle
04:20:06<pumpkin>ACTION wants to make a new SCM based on darcs
04:20:24<mmorrow>grrr
04:20:30<dmwit>mmorrow: splatter p (drop 1 zs) instead
04:20:39<mmorrow>kill!
04:20:46<mmorrow>im running out of names
04:20:50<dmwit>And change the first branch of the case.
04:20:53<dmwit>To be (zs, [])
04:20:56<mmorrow>yeah, true
04:21:02<mmorrow>guess it's time to pull out wrangle
04:21:08<pumpkin>:D
04:21:16<dmwit>:t splattest
04:21:16<lambdabot>Not in scope: `splattest'
04:21:26<pumpkin>wrangle always works
04:21:32<lament>splat, splatter, splattest!
04:21:42<mmorrow>@let wrangle _ [] = []; wrangle p xs = case break p xs of (ys,[]) -> [ys]; (ys,zs) -> ys : wrangle p (drop 1 zs)
04:21:44<lambdabot> Defined.
04:21:45<mmorrow>wooo
04:21:48<pumpkin>ACTION grins
04:22:01<Raynes>I can't believe I was just stupid enough to type init [1..10000000000] into GHCi. :|
04:22:02<lament>> wrangle (== ',') "what,the , hell"
04:22:04<lambdabot> ["what","the "," hell"]
04:22:10<lament>woo!
04:22:10<pumpkin>Raynes: just ctrl+c it?
04:22:16<dmwit>> wrangle isSpace " "
04:22:17<lambdabot> ["","","","","","","","","","","","","","","","","","",""]
04:22:30<mmorrow>wrangle them isSpaces!
04:22:39<mmorrow>ACTION cues rawhide
04:22:40<dmwit>...rawhide?
04:22:45<Raynes>pumpkin: By time I noticed my computer was freezing it was too late.
04:22:52<pumpkin>> wrangle even [1..]
04:22:53<lambdabot> [[1],[3],[5],[7],[9],[11],[13],[15],[17],[19],[21],[23],[25],[27],[29],[31]...
04:22:55<Raynes>Pop goes the weesle.
04:22:58<dmwit>Raynes: ^z always works here
04:23:08<dmwit>Raynes: ^zkill %1 is burned into my fingers
04:23:17<dmwit>Which is bad, because it's not always %1. =/
04:24:04<pumpkin>ray: http://www.haskell.org/haskellwiki/Hac_φ
04:24:46<ray>ghci needs an option to only show a certain number of characters a la lambdabot
04:24:47<Gracenotes>> wrangle even ([1..] >>= \x -> [x, x])
04:24:49<lambdabot> [[1,1],[],[3,3],[],[5,5],[],[7,7],[],[9,9],[],[11,11],[],[13,13],[],[15,15]...
04:24:55<Gracenotes>o_O
04:24:59<pumpkin>that's useful
04:25:21<dmwit>> wrangle even ([1..] >>= join replicate)
04:25:22<lambdabot> [[1],[],[3,3,3],[],[],[],[5,5,5,5,5],[],[],[],[],[],[7,7,7,7,7,7,7],[],[],[...
04:25:33<dmwit>YES! I've always wanted that!
04:25:46<Gracenotes>ever since I was a little girl!
04:26:14<Gracenotes>er. boy. (as applicable)
04:26:53<dino->@paste
04:26:53<lambdabot>Haskell pastebin: http://hpaste.org/new
04:27:46<dmwit>Alright... bed and a decent night's rest, or code and never sleep?
04:28:14<dino->http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5244#a5244
04:28:38<pumpkin>dmwit: I'd get some sleep
04:28:53<dino->substAll and splitAll, with applicative parsec. Have I mentioned how excited I am lately with applicative functors?
04:28:59<dmwit>Yeah, that's definitely what I should do.
04:29:12<pumpkin>I love applicative
04:29:14<Gracenotes>dino-: they are very neat
04:29:21<Gracenotes>@where applicativeparsec
04:29:22<lambdabot>http://www.serpentine.com/blog/2008/02/06/the-basics-of-applicative-functors-put-to-practical-work/ and http://book.realworldhaskell.org/read/using-parsec.html#id652399
04:29:23<Gracenotes>^ you've read?
04:29:35<dino->Gracenotes: No, thank you!
04:29:37<mxc>applicative has been getting some love in this channel in the past few days..
04:29:55<mxc>i wonder if 'learn you a haskell' adding a chapter on it helped
04:29:59<pumpkin>but monoids for parsing also seems cool
04:30:02<dino->I only read The Paper, wikibook and parts of RWH a-la Applicoparsec
04:30:13<pumpkin>I guess they aren't mutually exclusive :)
04:30:19<pumpkin>and Alternative is just monoid
04:30:22<Gracenotes>righto
04:31:12<dino->Also, I have a naggy feeling those split* functions should be folds.
04:31:19<pumpkin>folds?
04:31:45<pumpkin>oh in your paste?
04:31:52<dino->Instead of recursing until Left. yes
04:32:45<Gracenotes> dino-: hm. In general, one would use Parsec with one "parse" call for the whole expression, and everything else composed of smaller Parsers
04:32:49<Gracenotes>a la combinators
04:33:06<Gracenotes>and there are built-in Parsec fold combinators
04:33:10<dino->Gracenotes: I found the iterativeness of this difficult to do that way.
04:33:17<tompledger>@type unfoldr
04:33:18<dino->But I could be Doing It Wrong, absolutely
04:33:18<lambdabot>forall b a. (b -> Maybe (a, b)) -> b -> [a]
04:33:34<dino->ah, parsec fold
04:33:38<dino->mm, must read
04:42:25<roconnor>@free sortBy
04:42:26<lambdabot>(forall x. g x = h (f x) . f) => $map f . sortBy g = sortBy h . $map f
04:42:35<pastorn>what function does this?
04:42:37<dino->mm, unfold
04:42:39<pastorn>f "hhhheeello" == ["hhhh","eee","ll","o"]
04:42:44<roconnor>group
04:42:50<pastorn>thanks :)
04:42:54<Cale>> group "mississippi"
04:42:56<lambdabot> ["m","i","ss","i","ss","i","pp","i"]
04:43:07<Cale>> group . sort $ "mississippi"
04:43:09<lambdabot> ["iiii","m","pp","ssss"]
04:43:10<pumpkin>roconnor: what do the $ mean in @free output?
04:43:32<pastorn>is there a more general version of group?
04:43:40<pumpkin>groupBy?
04:43:45<pastorn>one that might also take a function (a -> Eq b)
04:43:51<pastorn>@type groupBy
04:43:52<lambdabot>forall a. (a -> a -> Bool) -> [a] -> [[a]]
04:44:01<pastorn>cool, win
04:44:04<roconnor>pumpkin: $map is the appropriate map for whatever datatype
04:44:07<roconnor>I think
04:44:09<pumpkin>ah
04:44:23<pumpkin>seems like it would need to be list though
04:44:56<dmwit>$map is Prelude.map, to avoid clashes with names you provide in lets.
04:45:03<roconnor>g x y = h (f x) (f y) is probably a more clear hypothesis.
04:45:05<pumpkin>ah :)
04:45:09<dmwit>?free let map = id in map
04:45:09<lambdabot>Pattern match failure in do expression at /tmp/ghc25834_0/ghc25834_59.hspp:54:20-34
04:45:18<dmwit>...or something like that.
04:45:29<roconnor>@free fst
04:45:30<lambdabot>f . fst = fst . $map_Pair f g
04:45:41<roconnor>dmwit: interesting
04:46:18<roconnor>@free Left
04:46:18<lambdabot>Pattern match failure in do expression at /tmp/ghc25834_0/ghc25834_59.hspp:54:20-34
04:46:24<pumpkin>@free loop
04:46:25<lambdabot>Expected variable or '.'
04:46:33<dmwit>?free map :: a -> a -> a
04:46:34<lambdabot>f . map x = map (f x) . f
04:46:53<dmwit>There, that shows how you might get a clash.
04:47:08<dmwit>:t sortBy
04:47:10<lambdabot>forall a. (a -> a -> Ordering) -> [a] -> [a]
04:47:19<pumpkin>@free loop :: (a, b) -> (c, b) -> a -> c
04:47:19<lambdabot>h . loop x y = loop ($map_Pair f g x) ($map_Pair h g y) . f
04:47:21<dmwit>?free map :: (a -> a -> Ordering) -> [a] -> [a]
04:47:22<lambdabot>(forall x. g x = h (f x) . f) => $map f . map g = map h . $map f
04:47:27<pumpkin>fun :)
04:47:56<pastorn>@pl (\c0 c1 -> (xPos c0) == (xPos c1))
04:47:56<lambdabot>(. xPos) . (==) . xPos
04:48:01<pastorn>nah...
04:48:12<dmwit>(==) `on` xPos
04:48:35<dmwit>Though note that this has a more restrictive type than the lambda you wrote.
04:48:41<dmwit>(very slightly more restrictive)
04:48:57<pumpkin>it'd be nice if it were possible to write on that took typeclasses
04:49:11<dmwit>yeah
04:50:49<pastorn>dmwit: is that the reader monad?
04:50:53<pastorn>@type on
04:50:54<lambdabot>forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
04:51:00<pumpkin>sort of similar
04:51:09<dmwit>pastorn: No, there's no monad involved, but it does seem Reader-ish. =)
04:51:17<pumpkin>:t liftM2 (==)
04:51:18<pastorn>indeed it does
04:51:18<lambdabot>forall a1 (m :: * -> *). (Eq a1, Monad m) => m a1 -> m a1 -> m Bool
04:51:30<pastorn>gaddamn ((->) a)
04:51:34<pumpkin>I love it :)
04:51:50<pumpkin>could just be the reader applicative I guess
04:52:26<pastorn>ACTION is writing recursive list functions like it's 1998!
04:52:32<vininim_> hGetBufNonBlocking: illegal operation (handle is closed)
04:52:35<vininim_>baaaawwww
04:53:33<pumpkin>http://imgur.com/k27q8.jpg
04:54:37<Gracenotes>er
04:54:47<Gracenotes>subtraction. there is only addition and negation
04:55:19<pumpkin>division. there is only multiplication and multiplicative inversion ?
04:55:29<Gracenotes>I was about to say, yes :o
04:55:44<pumpkin>it's a stupid question :P
04:56:34<vininim_>Is there any alternative to bracket that is ByteString friendly?
04:57:09<pumpkin>in the sense that it'll finalize the underlying buffer of the bytestring?
04:57:46<vininim_>@type ($!)
04:57:48<lambdabot>forall a b. (a -> b) -> a -> b
04:57:59<vininim_>@src ($!)
04:57:59<lambdabot>f $! x = x `seq` f x
04:58:45<vininim_>pumpkin: something like that
05:00:01<vininim_>uh.. it seems unrelated...
05:00:06<pumpkin>?
05:02:07<vininim_>the problem is Data.ByteString.Lazy.Char8.hGetContents not liking bracket and seq
05:02:35<Gracenotes>hm. it is lazy after all.
05:03:49<mmorrow>vininim_: *GetContents puts the Handle in a "half-closed" state
05:04:19<mmorrow>why are you bracketing?
05:05:21<Cale>You should *never* call hClose on a handle which has already had hGetContents run on it.
05:06:00<Cale>The handle will close automatically at some point after you're done with the string
05:06:36<vininim_>that ``some point'' might lead to resource exhaustion, no?
05:06:41<Cale>yes
05:06:41<dmwit>Yes.
05:06:50<dmwit>If you're worried about it, don't use hGetContents.
05:06:51<Cale>So hGetContents is bad if you're opening many files
05:07:23<vininim_>hm.. what is the recommended way?
05:08:01<Cale>Well, actually you could use the strict bytestring library's version of it, which does completely read the file all at once.
05:08:45<Cale>Or you can read a line or other chunk at a time with the other primitives, and close when you're done
05:08:46<mmorrow>vininim_: or you can just not use hGetContents..
05:09:15<BMeph>What's "$map_Pair"? Is it like "curry (map . uncurry (***))"?
05:09:24<dmwit>vininim_: Are you actually opening lots of files?
05:09:29<dmwit>(Like, thousands?)
05:10:04<dmwit>$map_Pair f g (x, y) = (f x, g y)
05:10:09<vininim_>yes, 8k
05:10:33<dmwit>Okay, so yeah, you'll want to do your own handle management.
05:10:35<dmwit>:t openFile
05:10:35<BMeph>> curry (map . uncurry (***)) f g (x,y)
05:10:36<lambdabot>Not in scope: `openFile'
05:10:37<lambdabot> Couldn't match expected type `(SimpleReflect.Expr,
05:10:48<dmwit>BMeph: I don't think that type-checks.
05:11:02<BMeph>@type curry (map . uncurry (***))
05:11:04<lambdabot>forall b c b' c'. (b -> c) -> (b' -> c') -> [(b, b')] -> [(c, c')]
05:11:28<dmwit>BMeph: I think it's just (***)
05:11:37<dmwit>$map_Pair = (***) -- I mean
05:11:41<BMeph>Oh, never mind, the "map" is an analogy. Got it. :)
05:12:02<BMeph>dmwit: Ah, right. Thanks. :)
05:12:41<dmwit>?hoogle FilePath -> IO Handle
05:12:41<lambdabot>System.IO openBinaryFile :: FilePath -> IOMode -> IO Handle
05:12:41<lambdabot>System.IO openFile :: FilePath -> IOMode -> IO Handle
05:12:41<lambdabot>Distribution.Simple.Utils die :: String -> IO a
05:12:48<dmwit>Oh, so I did get the name right.
05:12:58<dmwit>I guess it makes sense not to import System.IO in \bot, though.
05:15:39<walter_>Could someone give me the haskell paste URL, please?
05:15:45<dmwit>?hpaste
05:15:45<lambdabot>Haskell pastebin: http://hpaste.org/new
05:16:05<walter_>thanks
05:16:10<walter_>?hpasete
05:16:10<lambdabot>Haskell pastebin: http://hpaste.org/new
05:16:45<elbar>that looks like cheating ;)
05:18:08<walter_>Why do I get "match(es) are overlapped" http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5245#a5245
05:18:31<dmwit>isTagText and isTagOpen both match any value.
05:18:43<dmwit>They bind that value to the name isTagText and isTagOpen, respectively. =)
05:19:09<dmwit>(i.e. these do not test whether x is text or open, as you seem to be expecting them to)
05:19:33<mmorrow>vininim_: withFile = flip bracket hClose . flip openFile ReadWriteMode
05:19:39<walter_>dmwit, thank you, then , How can I distict Tag and TagText?
05:20:03<mmorrow>pattern matching
05:20:07<jeff_s_>cast x of x | isTagText x ->
05:20:07<jeff_s_>| isTagOpen x ->
05:20:19<jeff_s_>er, case x of rather
05:20:45<dmwit>walter_: case x of TagOpen tagName attributes -> ...; TagText text -> ...
05:20:59<jeff_s_>nm
05:21:21<dmwit>Guards also work, but it's a good idea to understand how to use patterns. ;-)
05:21:43<dmwit>(jeff_s_'s suggestion would be the guards route; my suggestion would be the patterns route)
05:21:44<walter_>dmwit, your are right.
05:23:34<walter_>I dont really quite understand, thanks. will try both.
05:24:38<jeff_s_>The guards way looks a little sloppy, I'd use pattern matching whenever possible
05:25:11<jeff_s_>but I'm still used to thinking in terms of what looks good in ML. Haskell's been a challenge
05:25:14<pastorn>@src unlines
05:25:14<lambdabot>unlines = concatMap (++ "\n")
05:25:51<Gracenotes>:O
05:25:57<Cale>Haha, from an oldish Onion video: "New CIA intelligence indicates Al-Queda may be linked to Al-Qaida, Al-Qaeada"
05:30:21<jeff_s_>@src lines
05:30:23<lambdabot>Source not found. Are you on drugs?
05:30:28<jeff_s_>haha
05:30:45<jeff_s_>this lambdabot fellow is really smart, clever and resourceful. Oh and reliable
05:30:48<jeff_s_>and dependable
05:31:14<Cale>The source is more reliably linked from the documentation
05:31:36<jeff_s_>ah, then I take back the resourceful part
05:31:57<Cale>for example, from here, http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Alines you can click the source link, and you'll get http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#lines
05:32:29<Cale>I think lines was left out for being a little long for @src
05:33:03<jeff_s_>I see
05:48:27<jeff_s_>oh heh, the toplevel isn't very smart about things like cycle [1,2,3]
05:49:26<vininim_>mmorrow: that's bracket point-free =P
05:49:58<vininim_>except that bracket is not only about file input
05:51:27<Vq^>jeff_s_: you're thinking about the memory usage?
05:51:53<pumpkin>shouldn't cycle [1,2,3] run in constant memory?
05:51:56<pumpkin>unless you build something else off it
05:53:11<Vq^>pumpkin: if you assign it to a top-level name and try to evaluate a large chunk of it, it probably takes a lot of memory
05:53:27<pumpkin>why?
05:53:37<Vq^>not sure what jeff_s_ meant by toplevel thought
05:54:58<Vq^>pumpkin: because it gets memoized, and the top-level name has to keep it alive
05:55:16<pumpkin>nope?
05:55:33<dmwit>Vq^: ...so?
05:56:06<dmwit>The memory for memoizing "cycle [1,2,3]" is what, 50 bytes? That's not exactly "a lot".
05:56:11<pumpkin>Vq^: I just wrote a simple program... running in constant space
05:56:28<Vq^>i guess im mistaken then
05:56:31<pumpkin>Vq^: x = cycle [1,2,3] at top level, main = print . length $ x
05:56:43<dmwit>I assume jeff_s_ meant that if you type it into ghci, it loops printing it.
05:57:09<dmwit>Which is true, and I'd be sad if it did anything else. =)
05:57:09<Vq^>or it's some optimization that kicks in for simple programs
05:58:03<dmwit>Optimization? Yes, there's a slight optimization in the source for cycle...
05:58:04<dmwit>?src cycle
05:58:05<lambdabot>cycle [] = undefined
05:58:05<lambdabot>cycle xs = xs' where xs' = xs ++ xs'
05:58:33<dmwit>That extra name "xs'" is what makes the magic.
06:00:55<Vq^>interesting, i thought x would be stored in pumpkins example, since it shouldn't be recomputed if it's needed again
06:01:03<pumpkin>it is stored
06:01:06<pumpkin>but it's a circular list
06:01:39<pumpkin>now if you did cycle (cycle [1,2,3]) that might be a problem, I think
06:01:43<pumpkin>actually, not even
06:01:56<Vq^>no, that one is the same thing
06:02:10<sjanssen>cycle on an infinite list will leak memory
06:02:25<pumpkin>because the outer call doesn't see the structure of the inner one?
06:03:06<dmwit>sjanssen: I think not this particular infinite list, right?
06:03:19<dmwit>Usually it can leak because we're keeping a reference around to it.
06:03:21<Vq^>i think i get it, it simply doesn't have to construct more data
06:03:25<dmwit>i.e. to the beginning of it.
06:03:36<dmwit>But here that's okay, because the whole damn list is only 50 bytes or so.
06:03:42<sjanssen>dmwit: for any infinite list
06:03:52<pumpkin>yup, definitely problematic :)
06:03:54<pumpkin>I just tried it
06:04:02<sjanssen>pumpkin: yes, the cycle knows nothing about its input
06:05:15<dmwit>Yep, it does seem to be wreaking havoc here.
06:05:33<dmwit>That's odd, and I don't understand it.
06:06:14<sjanssen>dmwit: in "xs' = xs ++ xs'" the end of xs is never reached
06:06:18<dmwit>aah, I do understand it
06:06:25<dmwit>Yeah, that's bad.
06:06:54<dmwit>Well, there's not much you can do about that, I suppose.
06:07:02<sjanssen>right
06:10:26<BMeph>ACTION looks for an interesting article... on Real Anal. Exchange
06:12:51<pumpkin>:o
06:14:49<Gracenotes>BMeph: sorry, it may be too late to use craigslist for that
06:15:49<Adamant>Gracenotes: I was gonna go with a joke about UCSF, but I figured it was borderline bigoted
06:18:12<BMeph>Hmm, rather "Real Analysis Exchange"
06:47:31<Baughn>> (fmap.fmap.fmap
06:47:33<lambdabot> <no location info>: parse error (possibly incorrect indentation)
06:48:34<Baughn>> ((fmap.fmap.fmap) (+) [Just 4,Nothing,Just 5]) 3
06:48:35<lambdabot> Couldn't match expected type `t -> f (f1 a)'
06:58:58<Baughn>> ((fmap.fmap.fmap) (+3) [Just (+4),Nothing,Just (*5)])
06:59:00<lambdabot> Overlapping instances for GHC.Show.Show (a -> a)
06:59:00<lambdabot> arising from a use of `...
06:59:18<Baughn>> ((fmap.fmap.fmap) (+3) [Just (+4),Nothing,Just (*5)]) 10 -- Geez, thought it could show those
06:59:19<lambdabot> Couldn't match expected type `t -> f (f1 a)'
06:59:29<Baughn>ACTION groans
06:59:43<Baughn>> ((fmap.fmap.fmap) ($3) [Just (+4),Nothing,Just (*5)])
06:59:45<lambdabot> No instance for (GHC.Num.Num (a -> b))
06:59:45<lambdabot> arising from the literal `4' at <...
07:00:25<vininim_>anyone played with attoparsec?
07:03:16<Baughn>> fmap (+2) (+3) 5
07:03:18<lambdabot> 10
07:03:39<Baughn>> ((fmap.fmap) (+2) [(+3),(+6)]) 5
07:03:40<lambdabot> Couldn't match expected type `t -> f a'
07:03:58<Baughn>:t (fmap.fmap) [(+3)]
07:04:00<lambdabot> Couldn't match expected type `a -> b' against inferred type `[a1]'
07:04:00<lambdabot> In the first argument of `(fmap . fmap)', namely `[(+ 3)]'
07:04:00<lambdabot> In the expression: (fmap . fmap) [(+ 3)]
07:04:16<pumpkin>:t (fmap.fmap) (+2)
07:04:17<lambdabot>forall (f :: * -> *) a (f1 :: * -> *). (Functor f, Functor f1, Num a) => f (f1 a) -> f (f1 a)
07:04:43<Baughn>:t (fmap.fmap) (+2) [(+3)]
07:04:44<lambdabot>forall a. (Num a) => [a -> a]
07:04:47<pumpkin>> ((fmap.fmap) (+2) [(+3),(+6)]) <*> [5]
07:04:48<lambdabot> [10,13]
07:04:58<Baughn>:t ((fmap.fmap) (+2) [(+3)]) <*> 6
07:05:00<lambdabot>forall a. (Num a, Num [a]) => [a]
07:05:03<Baughn>> ((fmap.fmap) (+2) [(+3)]) <*> 6
07:05:05<lambdabot> No instance for (GHC.Num.Num [a])
07:05:05<lambdabot> arising from the literal `6' at <inter...
07:05:49<Baughn>Uguuu~
07:06:10<pumpkin>?
07:08:24<pumpkin>@pl \x -> map ($x)
07:08:24<lambdabot>map . flip id
07:08:30<pumpkin>@pl \x -> fmap ($x)
07:08:30<lambdabot>fmap . flip id
08:14:31<pumpkin>@type unfoldr
08:14:33<lambdabot>forall b a. (b -> Maybe (a, b)) -> b -> [a]
08:18:01<QtPlaty[HireMe]>Is it correct to say "Function application in haskell is left associative"
08:18:06<QtPlaty[HireMe]>?
08:21:03<fasta>I am using some functional dependencies, but it appears that type Foo = Double and then depending on Foo gives a different result than directly depending on Double (which does work). Is there some extension which can cause this behaviour? If so, which one?
08:25:34<Gracenotes>QtPlaty[HireMe]: I'd say that.
08:26:17<Gracenotes>in all lambda calculi that I know of
08:26:36<Gracenotes>...er, and there aren't that many of them, really >_>
08:29:10<Gracenotes>there aren't many other languages where you could say application is associative at all
08:29:36<Gracenotes>hm.
08:33:00<Cale>fasta: That is surprising...
08:33:14<Bacta>@fag can Haskell cure me of my social awkwardness?
08:33:15<lambdabot>The answer is: Yes! Haskell can do that.
08:33:21<Bacta>Awesome!
08:36:10<BrokenClockwork>hey, is there a n-root function in the prelude? :)
08:36:34<ziman>> 27**(1/3)
08:36:35<lambdabot> 3.0
08:36:53<BrokenClockwork>thanls alot mate
08:36:57<ziman>yw :)
08:42:16<fasta>Cale: I think it was something else. It is solved now, anyway.
08:45:02<dancor_>if i am tracking data length already somewhere else for some binary data, is it still more correct to use (fst <$> newCStringLen x) than (newCString x)
08:59:07<fasta>dancor_: either it is correct or it is not, if you are talking about maintainability and how obviously correct it is, then storing the length and the string in one data structure seems better than to distribute it like you seem to be doing now.
09:05:13<dancor_>fasta: takusen splits it up i guess because postgres accepts the parts in different arguments
09:05:28<dancor_>the postgres c lib
09:05:44<mjrosenb>does rwh cover talking with a database and/or ffi stuff at all?
09:06:18<kynky>thought it did ,but would have to check
09:07:00<fasta>dancor_: and postgres does it that way because the std c lib does it that way.
09:07:25<dancor_>i'm going to go with (fst <$> newCStringLen x). idk if (newCString x) would work.
09:08:04<kynky>ch 7 deals with ffi
09:08:24<kynky>ch21 deals with databases
09:08:46<kynky>ch17 with ffi i mean
09:09:05<fasta>mjrosenb: there are also quite some blog posts on using the FFI.
09:09:26<fasta>mjrosenb: and of course the documentation, which is fairly good.
09:33:28<Berengal>Say you've got a class (Show b) => Foo a b | a -> b, is it possible to constrain b using type families?
09:39:00<pumpkin>Berengal: you mean to replace that fundep with type families?
09:39:53<Peaker>what can type families do that fundeps can't?
09:40:04<doserj>Berengal: in theory, you can do sth. like class (Show b, B a ~ b) => Foo a b where type B a
09:40:14<yitz>Peaker: work well.
09:40:33<Peaker>yitz: ?
09:40:53<doserj>Berengal: but I seem to remember that ghc has some issues with these kind of equality constraints.
09:41:10<yitz>Peaker: it's not clear how the compiler should handle fundeps to make their behavior "unsurprising" to users.
09:41:47<Peaker>yitz: so are they equivalent in power? I thought type families added power
09:43:03<yitz>Peaker: I like the idea of fundeps, but ghc often seems somewhat broken with them. It doesn't seem to be the fault of the ghc team - they seem to be really hard to implement fully.
09:44:03<Peaker>I wonder about the difference in power "in theory"
09:44:07<yitz>Peaker: could be, I don't know, but I haven't run into anything else I need them for in practice. What I said is the reason I like type families.
09:44:45<pumpkin>I've brought this up before, but has anyone thought about "existential typeclass quantification" if that makes sense?
09:44:55<pumpkin>is there a more correct name for that?
09:46:11<Peaker>pumpkin: what do you mean?
09:46:20<pumpkin>well the typical example is generalizing the on function
09:46:26<Peaker>@type on
09:46:27<lambdabot>forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
09:46:49<Peaker>@type flip on -- nicer
09:46:50<lambdabot>forall b c a. (a -> b) -> (b -> b -> c) -> a -> a -> c
09:46:57<pumpkin>I'm fine with the order :)
09:47:04<Peaker>just as a btw :)
09:47:09<pumpkin>but do you see what I mean?
09:47:12<Peaker>its a double-arg CoFunctor :)
09:47:19<Peaker>nope, not sure -- what is the more general type?
09:47:41<Berengal>For me the main reason to use type families is at the moment readability
09:47:42<pumpkin>well, I can't write it, but it's a typeclass that has a method Class a => a -> b
09:48:09<Berengal>Instead of class Foo a b c d | a -> b c d you get class Foo a where type B a; type C a; type D a
09:48:17<yitz>Peaker: the motivation for the order was things like compare `on` sqrt, which reads nicely in English. Why do you like the oposite order better?
09:48:19<pumpkin>Peaker: so the last two a's in the type of on don't need to be the same... the only important thing is that you have some kind of mapping from each of them to b
09:49:06<Peaker>I'd call it argument2 or bothArgs or something like that
09:49:07<pumpkin>Peaker: and that mapping could be through a typeclass-constrained function
09:49:14<Peaker>sqrt `bothArgs` compare
09:49:47<pumpkin>Peaker: see what I'm saying?
09:50:06<Peaker>pumpkin: ah, I see
09:50:43<yitz>pumpkin: so you want some kind of "uncurried" ***?
09:51:46<pumpkin>something like forallclass C. forall c d. C c, C d => (b -> b -> e) -> (C a => a -> b) -> c -> d -> e
09:51:57<pumpkin>if that makes any sense whatsoever :P
09:52:34<Peaker>pumpkin: trying to find a way to write the type myself, indeed a problem :)
09:53:05<yitz>@type \f g g' x y -> f (g x) (g' y)
09:53:05<pumpkin>it is pretty monstrous :P
09:53:07<lambdabot>forall t t1 t2 t3 t4. (t2 -> t3 -> t4) -> (t -> t2) -> (t1 -> t3) -> t -> t1 -> t4
09:53:21<yitz>@pl \f g g' x y -> f (g x) (g' y)
09:53:22<lambdabot>((flip . ((.) .)) .) . (.)
09:53:32<pumpkin>yeah, if you accept that you have two functions, then it's not a problem
09:53:55<yitz>just a little messy
09:53:59<pumpkin>yeah
09:54:49<Peaker>(ia -> ia -> r) -> (? -> ia) -> (ib -> ic -> o)
09:55:19<Peaker>(ia -> ia -> r) -> (forall i. Convertible i ia => i -> ia) -> (ib -> ic -> o) ?
09:55:39<Peaker>class Convertible a b where apply :: a -> b ?
09:55:45<yitz>@type \f g g' -> curry $ uncurry f . (g *** g')
09:55:48<lambdabot>forall a b a1 b1 c. (a1 -> b1 -> c) -> (a -> a1) -> (b -> b1) -> a -> b -> c
09:55:53<Peaker>pumpkin: what about that type?
09:55:54<mebbel>ia -> ia -> fhtagn
09:56:13<pumpkin>Peaker: then you'd need to write a bunch of instances
09:56:21<pumpkin>Peaker: wouldn't you?
09:56:35<Berengal>Where would I find (~)?
09:56:59<Peaker>pumpkin: isn't that inherent?
09:57:14<Peaker>Berengal: I think ~ is a language extension of type families meaning type equality
09:57:19<pumpkin>well, with the forallclass thing I was hoping to exploit existing classes and instances
09:57:41<Peaker>pumpkin: call any random class method to convert?
09:57:42<pumpkin>but I guess if more than one worked, you'd have to choose which one somehow
09:57:44<pumpkin>:P
09:57:49<pumpkin>which would be ugly
09:58:02<mebbel>forget the type; how would you write the function body?
09:58:08<pumpkin>hmm, maybe not such a good idea :)
09:58:10<pumpkin>mebbel: not a clue :P
09:58:25<Peaker>pumpkin: oh, I see what you mean now
09:58:46<pumpkin>probably not a very good idea now that I've gone over it more :)
09:58:47<Peaker>something like: (ia -> ia -> r) -> (forall i. i -> ia) -> (ib -> ic -> o) -- except you want i to just be as polymorphic as necessary and not fully polymorphic
09:59:24<Peaker>so that there should be (forall i. all_restrictions_that_still_catch ib and ic ...)
09:59:31<pumpkin>sort of, yeah :)
09:59:41<Peaker>or maybe (Either ib ic -> ia) :)
10:00:10<Peaker>heh, in the case of wanting to catch just a finite set of types, I guess the best way is just to provide a finite set of functions
10:00:43<Peaker>> (show *** show) (1, 2)
10:00:44<lambdabot> ("1","2")
10:00:49<Peaker>> (show *** show) (1, 'c')
10:00:51<lambdabot> ("1","'c'")
10:01:02<Peaker>@let both = join (***)
10:01:03<lambdabot> Defined.
10:01:08<Peaker>> both show (1, 'c')
10:01:09<lambdabot> No instance for (GHC.Num.Num GHC.Types.Char)
10:01:09<lambdabot> arising from the literal `1...
10:01:10<pumpkin>yeah :/
10:01:23<pumpkin>what's with lambdabot spitting out low-level types in its errors now?
10:01:36<Peaker>so it may be a little weird to use (show *** show) instead of join (***) show... working around type system weakness
10:02:02<Peaker>@type join (***)
10:02:03<lambdabot>forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c)
10:02:52<pumpkin>what would have to change to make join (***) as polymorphic as (f *** f) ? the whole monomorphic function application thing?
10:03:15<pumpkin>because even \f -> (f *** f) would be equivalent to join (***) I think?
10:03:20<Peaker>It is equivalent
10:03:42<Peaker>now I understand what dolio (I think it was him) said about let binding and argument binding having different type restriction
10:03:59<Peaker>let show = ... -- show is polymorphically typed whereas \f -> (f *** f) -- f is singly-typed
10:04:07<pumpkin>yup
10:04:23<pumpkin>@let showBoth = (show *** show)
10:04:24<lambdabot> Defined.
10:04:26<pumpkin>:t showBoth
10:04:27<lambdabot>forall b b'. (Show b, Show b') => (b, b') -> (String, String)
10:04:36<hackagebot>fclabels 0.1.2
10:05:31<pumpkin>I guess that's a pretty fundamental aspect of the language
10:05:44<pumpkin>and changing it would have all sorts of nasty effects
10:05:50<Peaker>pumpkin: if arguments had been polymorphic, then they could not be unified with anything
10:05:53<Peaker>I think
10:06:09<Berengal>class (Show b, B a ~ b) => Foo a where type B a -- doesn't work :(
10:06:18<Peaker>I mean, the type of \x -> (x,x) would not have been a -> (a, a)
10:06:25<pumpkin>yeah :)
10:06:29<pumpkin>it'd be a big mess
10:06:59<doserj>Berengal: class (Show b, B a ~ b) => Foo a b where type B a
10:07:00<pumpkin>I've often wanted that function by the way
10:07:07<pumpkin>should be called duplicate or something
10:07:15<pumpkin>in Control.Arrow, maybe, as an arrow
10:07:18<doserj>Berengal: Foo needs both a and b as parameter
10:07:19<pumpkin>along with both
10:07:29<Berengal>doserj: Yes, but it shouldn't be neccessary to have b as a parameter
10:07:43<doserj>Berengal: if you want to constrain it, it has to
10:07:53<pumpkin>you want some sort of existential b?
10:08:10<Peaker>pumpkin: call it both
10:08:17<Peaker>pumpkin: in consistency with first and second
10:08:20<Berengal>pumpkin: Yes
10:08:27<pumpkin>PeakerWork: I'd want both to be first f >>> second f or something
10:08:47<Peaker>@type \f -> first f >>> second f
10:08:48<lambdabot>forall (cat :: * -> * -> *) b c. (Arrow cat) => cat b c -> cat (b, b) (c, c)
10:08:49<pumpkin>as first and second apply functions to pairs
10:08:56<Peaker>@type \f -> join (***)
10:08:57<yitz>pumpkin: it already exists. it's called join.
10:08:57<lambdabot>forall t (a :: * -> * -> *) b c. (Arrow a) => t -> a b c -> a (b, b) (c, c)
10:08:59<Peaker>oops
10:09:02<Peaker>@type join (***)
10:09:03<lambdabot>forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c)
10:09:08<pumpkin>yeah, I know :)
10:09:13<pumpkin>I use that all the time, but I think it should be named
10:09:29<Peaker>pumpkin: I mean both = join (***) = first f >>> second f
10:09:34<pumpkin>yeah, I know
10:09:36<yitz>@type join (,)
10:09:38<lambdabot>forall a. a -> (a, a)
10:10:00<pumpkin>I was just going to define it in terms of first and second to be more explicit about the ordering (as the functions in Arrow tend to do)
10:10:06<pumpkin>but yeah, that works too
10:10:09<yitz>of course (,) is just sugar for curry id
10:10:39<pumpkin>:t curry id
10:10:41<lambdabot>forall a b. a -> b -> (a, b)
10:10:58<pumpkin>I've never found myself using curry much
10:11:06<pumpkin>I guess not many functions take pairs
10:11:33<pumpkin>ick, the sun is coming up
10:11:39<yitz>pumpkin: I guess you're not into indian cuisine
10:11:49<pumpkin>I actually make curry a lot :)
10:11:57<pumpkin>I love cooking
10:12:04<Peaker>pumpkin: uncurry is useful though
10:12:10<pumpkin>oh yeah, I use that all the time
10:12:25<pumpkin>especially with the arrow functions
10:15:27<pumpkin>alright, bedtime
10:27:44<Fred320>@src nub
10:27:44<lambdabot>nub = nubBy (==)
10:27:51<Fred320>@src nubBy
10:27:51<lambdabot>nubBy eq [] = []
10:27:52<lambdabot>nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs)
10:28:36<Fred320>@pl \ y -> not (eq x y)
10:28:37<lambdabot>not . eq x
10:28:37<dev312>Hi, I have a question that may just indicate my lack of experience.
10:28:53<dev312>If I have a return type of a function, that is wrapped in a monad, how can I get direct access to the data?
10:29:04<dev312>or is that not possible, like private variables in a class in OO languages?
10:29:19<mebbel>dev312: what data?
10:29:20<yitz>hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version?
10:29:34<QtPlaty[HireMe]>dev312: Something liike IO Foo?
10:29:36<pumpkin>dev312: it's not always meaningful, as not all monads "contain" data
10:29:52<dev312>It is of the CGI module... getVars..it returns (MonadCGI m)=> m ( [(String,String)] )
10:29:56<Peaker>how hard would it be for ghci to allow data declarations?
10:29:59<mebbel>and then you say "the x in M x" and then I say "that's just a type, not data"
10:30:07<Zao>pumpkin: The Id monad? :)
10:30:14<mebbel>and then I tell you how "<-" in a do block is a virtual unwrap
10:30:29<Peaker>dev312: you can access the data directly in a monad, but only in a computation that is itself also in the monad..
10:30:40<dev312>I see.
10:31:13<dev312>So I would have to create my own monad, then can somehow release the data after combining with this monad?
10:31:18<dev312>Or am I still on the wrong track?
10:31:21<Peaker>dev312: if you have an Monad m =>(m a) which is an "a wrapped in a Monad m", then you can use >>= to access the "a" but your result will be an "m b"
10:31:24<dev312>is the fact that I can never just have a plain list?
10:31:34<dev312>ahh ok
10:31:54<Peaker>dev312: note that its all the same monad type, no mixing of different monads here, just different values of the same monad-type
10:32:06<dev312>ok :(
10:32:07<dev312>gotcha
10:32:09<dev312>makes sense
10:32:55<foobaer>i don't know the CGI monad, but often you start a monad computation with a runFoo function and this function also returns the result of the monad computation unwrapped
10:32:59<yitz>pumpkin: go to sleep, otherwise you'll be sorry later
10:33:08<Peaker>dev312: you can think of a monad as a description of some "special" computation -- you can only access the value, which is namely to "sequence another same-special computation on top of the existing one"
10:33:13<pumpkin>yeah :(
10:33:27<pumpkin>sleep feels like such a waste of time, even though I know it isn't
10:33:45<dev312>PEaker, ok thanks..that makes sense
10:33:56<dev312>I guess it is better for me not to be able to mess with the internals anyway
10:34:32<Peaker>dev312: What do you mean by "mess with the internals"?
10:34:33<dev312>That being said, if the writer of a Monad wanted to provied a convenience function to get data out of a monad, they could
10:34:34<dev312>?
10:34:44<mebbel>depends on the monad
10:34:45<Peaker>dev312: No, the whole point of the Monad is that there's no escaping it
10:34:55<mebbel>Peaker: I strongly disagree
10:34:56<dev312>Well, flatly, so it is understood what I am saying, I just want the list
10:35:04<Peaker>well, not the whole point, one of the points :-)
10:35:07<dev312>I want to discard the monad and just have the list that it contains
10:35:10<mebbel>I still disagree
10:35:15<yottis>but that's exactly what those run*, exec* and eval* functions do
10:35:22<mebbel>dev312: >>=
10:35:40<Peaker>dev312: First, you should understand that Monad is just a type-class, or a "common interface" that various types provide an implementation for. Each type may provide any extra functions specific to that type in addition to the monad interface
10:35:45<yottis>there's just not anything that works for all monads, but nothing prevents you from creating one for a particular instance
10:35:46<foobaer>Peaker: what about the Maybe monad. there you can escape :)
10:35:50<dev312>hmm ok mebbel
10:35:53<dev312>let me check that out
10:35:53<Peaker>dev312: so some types may provide the Monad interface AND a way to exit the monad, but the Monad interface itself provides no such way
10:35:58<Peaker>foobaer: what if its Nothing?
10:36:10<foobaer>Peaker, well you have to check it of couse
10:36:15<doserj>dev312: I guess "<-" in a do-block is what you want
10:36:24<pumpkin>some monads you can escape from reliably, like ST
10:36:28<Peaker>dev312: If you want to write code that is *general* to all monads, you can't even assume that there's actually a list of values "in" it
10:36:37<dcoutts>yitz: what was the HP question?
10:36:52<mebbel>data W a = W; instance Monad W where return _ = W; W >>= _ = W
10:37:05<dev312>Peaker, I understand
10:37:11<dev312>I understand that not all monads are the same
10:37:16<dev312>and not all monads are "containers"
10:37:17<dev312>etc
10:37:20<pumpkin>class EscapableMonad m where escape :: m a -> a
10:37:24<dev312>Well I do now
10:37:26<dev312>anyway
10:37:42<pumpkin>Comonad
10:39:25<Peaker>dev312: anyway - remember that Monad is just an "interface" that you can program with to get generality of your code -- generality always means you can assume less. In the case of Monads, you can only assume that you can "sequence computations". Once you use a specific type, you can assume much more
10:40:03<Peaker>dev312: Its probably better to first understand Functor, then Applicative, then Monads, because they form natural extensions of each other, and Monads are the most complicated
10:40:23<dev312>ok, well yeah functors I have an understanding of
10:40:29<dev312>and even Monads, to a degree
10:40:36<Peaker>dev312: Well, how do you "exit" a Functor?
10:40:42<Peaker>dev312: how do you extract the value from a Functor?
10:40:44<dev312>What I am probably doing is wrong is simply not being ablt to find the proper convenience functions in this library
10:40:57<dev312>Right, being tested now.
10:41:03<dev312>Ill pass, no pun intended.
10:42:43<Peaker>dev312: I want to help you understand Monad by understanding the class hierarchy above it
10:55:32<Berengal>Success!
10:55:45<Berengal>class (Show (B b)) => Foo b where type B b :: *
10:57:18<dev312>ok Peaker, I have decided to slow down and study Applicative functors.
10:57:37<dev312>Not that this will solve my problem, but I do agree, in principle , it is best to understand fundamentals
11:07:51<yitz>dcoutts: hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version?
11:07:59<yitz>dcoutts: hmm... the haskell platform contents page just links to the current hackage page for each package. how do you see at a glance exactly which version of each package is included in a specific HP version?
11:09:24<dcoutts>http://hackage.haskell.org/platform/2009.2.0/haskell-platform.cabal
11:09:45<dcoutts>yitz: yeah the package list should say, but it's also in the .cabal file for the platform meta-package
11:10:03<yitz>I see. thanks.
11:10:58<araujo>ACTION just released new himerge version1
11:11:03<araujo>!
11:13:05<yitz>araujo: link?
11:14:41<araujo>@where himerge
11:14:41<lambdabot>http://www.haskell.org/~luisfaraujo/himerge/
11:14:45<araujo>err
11:14:51<araujo>www.haskell.org/himerge
11:14:54<araujo>that one
11:15:39<yitz>araujo: nice!
11:16:02<araujo>:D
11:16:07<yitz>araujo: that page makes it look like himerge is only for haskell users
11:16:11<mebbel>@where+ himerge http://www.haskell.org/himerge/
11:16:12<lambdabot>It is forever etched in my memory.
11:16:29<yitz>araujo: but in reality I'll bet it's userful for all gentoo users
11:16:32<yitz>useful
11:16:34<araujo>yitz, think so? ... why?
11:16:45<araujo>yeah, I know many gentoo users in general using it
11:17:07<araujo>I like when people who don't even know haskell use it :)
11:17:18<araujo>we needm or of those types around
11:17:24<araujo>more*
11:18:12<yitz>araujo: maybe you should just write at the bottom that it is implemented in haskell/gtk2hs, where it says Himerge is Free Software...
11:18:39<mebbel>"Himerge is a graphical user interface (GUI) for the Gentoo portage system written entirely on Haskell using the Gtk2Hs library." <- looks fine to me
11:18:50<yitz>araujo: so you won't scare away any haskephobics :)
11:19:05<araujo>yeah, it is explained in the first paragraph ... it is indeed an important thing to miss
11:19:51<araujo>yitz, my experience (luckily?) has been the opposite ... many of them seem curious about it and at least give it a try
11:19:56<yitz>mebbel: if it were written in C using gtk+, you wouldn't mention that in the first paragraph. possibly not at all on the front page
11:20:05<araujo>when they know what haskell is
11:20:23<mebbel>yitz: yes, I would
11:20:53<yitz>ok, i guess it's a matter of style
11:20:57<araujo>ACTION likes that kind of information at first if possible
11:21:35<araujo>yeah, i guess it is a matter of design and how the developer tries to reach the community
11:22:02<araujo>in my case with himerge, I wanted to show Haskell can indeed be used for daily GUI apps
11:22:12<araujo>so the language is written is very important
11:22:17<yitz>araujo: yeah, that's really great!
11:22:29<yitz>araujo: though I would like it to become unsurprising
11:22:44<araujo>unsurprising?
11:23:00<yitz>araujo: that you really can write a nice gui app easily in haskell
11:23:29<Peaker>Haskell is a fine imperative language too :)
11:23:36<araujo>yitz, yeah, you can!
11:23:48<araujo>Himerge's main purpose is to show that actually
11:24:05<yitz>Peaker: ok, ok, it will be even better once the reactive stuff becomes more mature
11:24:46<yitz>I hope that will be soon
11:25:16<Peaker>yitz: Baughn is helping with unamb now, and I think there aren't many bugs left in there
11:25:23<yitz>great!
11:25:25<Peaker>yitz: someone needs to debug why joinE doesn't work
11:25:27<mebbel>heh
11:25:29<Peaker>I wish I had some time
11:25:51<mebbel>"I think there aren't many bugs left in there" <- famous last words
11:26:23<yitz>mebbel: Fermat once said something along those lines.
11:26:47<yitz>they did get it debugged eventually though.
11:26:56<mebbel>haha
11:27:26<mebbel>imagine writing a program that takes 400 years to debug
11:31:39<Axman6>anyone know who Arnaud Payement is?
11:37:01<myst>ACTION is listening Lacrimosa - I lost my star in Krasnodar [Sehnsucht, 2009]
11:38:08<Axman6>wow, never seen now playing spam in #haskell before
11:38:10<cob_jonas>myst++ after that line the name Arnaud Payement doesn't look so strange
11:38:50<myst>sorry guys it was a test
11:40:17<Berengal>I like it when code just works. I like haskell
11:42:21<araujo>:)
11:43:06<Berengal>I was writing some java at work today, when suddenly a bug attacked. I was actually shocked, because the code compiled just fine
11:43:19<HugoDaniel>hi
11:43:36<Berengal>Hello
11:43:46<kynky>run time error vs compile time error ?
11:43:49<Baughn>yitz: NEar as I can tell,there are no bugs in my last version of unamb
11:44:02<Baughn>yitz: I'm now working on performance, via RTS hacks
11:44:07<Berengal>kynky: Not an "error" as such, just garbage execution
11:44:11<cob_jonas>it's not like that's impossible in haskell either, only much rarer
11:44:20<Baughn>p_l: while true; do mkdir a; cd a; done
11:44:22<yitz>Well, here is Arnaud Payement's thesis (master's?) at Oxford: http://progtools.comlab.ox.ac.uk/projects/jungl/resources/arnaud_msc_thesis.pdf
11:45:03<cob_jonas>Baughn: that's evil
11:45:11<yitz>He acknowledges his advisor Oege de Moor, and Mathieu Verbaere.
11:45:22<cob_jonas>Baughn: if you do it a tricky way you can even get an undeletable directory that way
11:45:32<Baughn>cob_jonas: How's that?
11:45:45<cob_jonas>Baughn: depends on what system you're on
11:45:50<cob_jonas>on DOS it's definitely possible
11:45:52<Baughn>Linux, so no directory hardlinks.
11:46:08<Peaker>Berengal: :)
11:46:21<cob_jonas>Baughn: you can have bind mounts or just plain remount an fs to a longer mount path
11:46:27<Peaker>Berengal: I find that FP Haskell code "Just works" and that imperative Haskell code still has some bugs fly through
11:46:32<yitz>Baughn: glad to hear about the progress.
11:46:46<cob_jonas>I'm not sure if you can do this in linux though
11:47:03<Baughn>yitz: Beyond that, the reactive Monad instance is badly broken, and unfortunately it's used all over the place.
11:47:04<cob_jonas>maybe if you're tricky you could get one you can't delete because you don't have enough memory or something
11:47:06<hackagebot>storable-record 0.0.1
11:47:09<cob_jonas>but I doubt
11:47:20<Baughn>yitz: That said, fixing unamb fixes quite a lot of its issues. :)
11:47:24<yitz>Baughn: that's pretty fundamental
11:47:26<Baughn>yitz: (Most notably the deadlocks)
11:47:30<HugoDaniel>is there anything similar to assembly in haskell ?
11:47:34<Berengal>Peaker: Yeah, that's my experience as well.
11:47:38<cob_jonas>HugoDaniel: in what way?
11:47:42<Baughn>HugoDaniel: C?
11:47:54<yitz>the Monad instance is in some ways the most important contribution
11:48:02<EvilTerran>HugoDaniel, there's core, being the intermediate language a compiler uses
11:48:10<EvilTerran>HugoDaniel, (but that varies from compiler to compiler)
11:48:19<Peaker>yitz: the Monad instance of what?
11:48:30<yitz>reactive
11:48:42<Berengal>Peaker: But that's still much better than languages where everything is imperative
11:48:43<cob_jonas>also in dos you can have a directory in which you can only put files of short names
11:48:47<cob_jonas>which is a bit funny
11:48:54<Peaker>Berengal: and the imperative part is far more powerful
11:49:20<Berengal>Peaker: The imperative part is like perl on crack
11:50:04<HugoDaniel>hmm
11:50:05<yitz>cob_jonas: ever mount an old dos partition on linux? it's also really weird.
11:50:10<FunctorSalad>hmm... are you not supposed to use stream-fusion/Data.Stream manually?
11:50:14<HugoDaniel>anyone up to coding an "Assembly Monad" in haskell ?
11:50:27<Berengal>HugoDaniel: It's been done
11:50:28<yitz>FunctorSalad: why not?
11:50:32<mebbel>HugoDaniel: what, like harpy?
11:50:33<HugoDaniel>Berengal: where ?
11:50:46<cob_jonas>yitz: I have. I had to to set up the virtual machine with dos.
11:50:53<FunctorSalad>yitz: I tried rewriting the meteor benchmark to use streams directly, and got ~30x slowdown :-(
11:50:58<Berengal>HugoDaniel: http://www.haskell.org/sitewiki/images/1/14/TMR-Issue6.pdf
11:51:00<cob_jonas>but it's not so bad as mounting them from dos
11:51:04<FunctorSalad>yitz: with most of the time lost in concatMap
11:51:25<yitz>FunctorSalad: does sound like you're losing your fusion.
11:51:35<cob_jonas>where depending on what codepage you loaded with mode, you can use different characters in filenames (and the case mapping is different too) so you can have files you can't delete
11:51:38<yitz>FunctorSalad: look over dons' blog about it
11:52:39<yitz>cob_jonas: unmount; format should do the trick
11:53:00<cob_jonas>yitz: sure, but it's easier to just rename them with norton utilities disk editor
11:53:10<yitz>hehe
11:53:14<HugoDaniel>allright, harpy seems like the right tool to use and abuse :D
11:53:19<cob_jonas>or to mount in linux and rename from there
11:53:55<FunctorSalad>yitz: there is a lot of commented out stuff about concatMap, I guess there's still some problem with it?
11:54:11<cob_jonas>or there's some of those fsck utilities (there are like three for dos, each having a slightly different idea about what's valid on fat and what isn't)
11:54:37<FunctorSalad>of course, maybe it's my fault and I blocked the fusion somehow
11:55:16<yitz>cob_jonas: in short: what a mess
11:56:13<yitz>FunctorSalad: don't know. but if you look at the core and experiment, you should be able to figure it out.
11:56:50<FunctorSalad>is there some ghc flag you need to set apart from -O2?
11:57:54<Berengal>@djinn (a -> (b -> c)) -> (a -> b) -> a -> c
11:57:54<lambdabot>f a b c = a c (b c)
11:58:02<Berengal>Hmmm, S
11:58:20<Berengal>I should've gotten that from the type...
11:59:12<joeally>Is anyone familiar to project euler
11:59:29<mib_e7tcavos>hey
11:59:40<mib_e7tcavos>wondering if anyone can help me
11:59:58<joeally>I'll try but i am a noob myself
12:00:01<mib_e7tcavos>gt a slight problem with some code
12:00:28<joeally>okay..
12:00:47<EvilTerran>mib_e7tcavos, don't ask to ask, just ask; we don't know if we can help you 'til you tell us what the problem is.
12:00:56<mib_e7tcavos>kl
12:01:18<mib_e7tcavos>gt an algebraic type i blieve
12:01:29<mib_e7tcavos>data Film = Film Title Director Year [Fans]
12:02:13<mib_e7tcavos>exampleFilms :: [Film]
12:02:30<mib_e7tcavos>exampleFilms = [(Film "Blade Runner" "Ridley Scott" 1982 ["Garry", "Dave", "Zoe"])]
12:02:43<mib_e7tcavos>so i have a list of films
12:03:02<mib_e7tcavos>now im trying to add a film
12:03:13<mib_e7tcavos>addFilm :: Title -> Director -> Year -> [Film] -> [Film]
12:03:24<mib_e7tcavos>addFilm ti di ye film = film ++ [(Film ti di ye [])]
12:03:33<mib_e7tcavos>ive compiled
12:03:49<mib_e7tcavos>and it tells me it doesnt have a show function
12:03:52<mib_e7tcavos>any ideas?
12:04:06<cob_jonas>what it says
12:04:09<mebbel>yeah, data Film = Film Title Director Year [Fans] deriving (Show)
12:04:41<mebbel>looks like your code is fine, it just doesn't know how to print the results
12:04:53<mib_e7tcavos>oh so i just put deriving show when im declaring
12:04:57<Neut>using a list comprehension, how would I define a function which does this,
12:05:02<mebbel>yes
12:05:12<Neut>matches 1 [1,2,4,2,1,2] ~~ [1,1]
12:05:14<mib_e7tcavos>awesome
12:05:20<mib_e7tcavos>thanks for the help
12:05:44<mebbel>matches k xs = [x | x <- xs, x == k]
12:05:46<Axman6>\y xs -> [ x | x <- xs, x == y]
12:05:54<Berengal>Neut: matches n l = [e | e <- l, n == e]
12:06:28<mebbel>spot the non-idiomatic haskeller :-)
12:06:59<yitz>> let matches k xs = [x | x <- xs, x == k] in matches 1 [1,2,4,2,1,2]
12:07:00<lambdabot> [1,1]
12:07:02<Neut>thanks
12:08:01<cob_jonas>is that just matches m = filter (m ==)
12:08:08<Axman6>yah
12:08:13<Berengal>@type filter <$> (==)
12:08:14<lambdabot>forall a. (Eq a) => a -> [a] -> [a]
12:08:34<Berengal>> let matches = filter <$> (==) in matches 1 [1,2,4,2,1,2]
12:08:34<yitz>@type filter . (==)
12:08:35<lambdabot> [1,1]
12:08:36<lambdabot>forall a. (Eq a) => a -> [a] -> [a]
12:09:13<yitz>@pl matches k xs = [x | x <- xs, x == k]
12:09:14<lambdabot>matches = flip ((:) . ((x | x) <-)) . return . (x ==)
12:09:19<yitz>hehe
12:09:39<Axman6>ha
12:09:59<yitz>where do you file a bug against @pl ?
12:10:01<cob_jonas>let's write it with guard
12:10:09<Axman6>@undo matches k xs = [x | x <- xs, x == k]
12:10:10<lambdabot>matches k xs = concatMap (\ x -> if x == k then [x] else []) xs
12:10:22<Axman6>@. pl undo matches k xs = [x | x <- xs, x == k]
12:10:22<zachk>joeally: yea im on euler, im up to problem 14, none of your haskell programs should reall go over like 60 lines
12:10:23<lambdabot>matches = (=<<) . flip flip [] . (`ap` return) . (if' .) . (==)
12:10:38<yitz>ah, much better
12:10:56<zachk>joeally: though ive been at haskell for a year, ive seen people take 30 lines of my code and drop it down to one line of code, a year latter its one function in Data.List
12:12:24<wli>ACTION is having really bad luck with project euler.
12:12:50<Neut>using comprehensions again,
12:12:55<Neut>how would I define a function wihch
12:13:10<yitz>ACTION had fun for the first 100 or so, then it started getting tedious
12:13:22<Neut>addPairwise [1,7] [8,4,2] ~~ [9,11]
12:13:34<wli>ACTION is just too dumb to solve many of them.
12:13:36<yitz>Neut: try it yourself first
12:13:58<Berengal>ACTION would just zipWith (+)
12:14:04<Neut>yeah I have, but I can't work it out which is why I have jumped on IRC
12:14:10<mebbel>Neut: not possible in H98
12:14:15<mebbel>that needs an extension
12:14:16<Berengal>mebbel: Sure it is
12:14:20<wli>The few I can solve often have unacceptably slow solutions.
12:14:27<mebbel>Berengal: zip doesn't count
12:14:31<Axman6>> zipWith (+) [1,7] [8,4,2]
12:14:32<lambdabot> [9,11]
12:14:35<Berengal>mebbel: Sure it does
12:14:37<yitz>Neut: what have you tried?
12:14:53<burp>uh, how does zipWith work with unequal sized lists?
12:15:03<yitz>burp: it just quits
12:15:10<yitz>after one runs out
12:15:11<Neut>[m + n | (m,n) <- zip list1 list2]
12:15:12<wli>e.g. the fastest multiplication thing
12:15:12<Axman6>@src zipWith
12:15:12<lambdabot>zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
12:15:13<lambdabot>zipWith _ _ _ = []
12:15:20<burp>ah I see
12:15:25<Berengal>> let addPairwise xs ys = [r | r <- zipWith (+) xs ys] in addPairwise [1,7] [8,4,2] -- :P
12:15:26<lambdabot> [9,11]
12:15:45<yitz>Neut: that looks good. try it here with lambdabot
12:16:01<Axman6>> [x + y | x <- [1,7] | y <- [8,4,2]]
12:16:03<lambdabot> [9,11]
12:16:06<Axman6>whoot
12:16:12<Neut>>let addPairwise' = [m + n | (m,n) <- zip list1 list2]
12:16:20<yitz>Axman6: that's not H98 though.
12:16:24<mebbel>Berengal: then so does [x | x <- zipWith (+) xs ys]
12:16:24<Axman6>ah
12:16:35<yitz>Neut: you need a space after the >
12:16:41<Neut>kk thanks
12:16:45<Neut>> let addPairwise' = [m + n | (m,n) <- zip list1 list2]
12:16:46<Berengal>mebbel: Huh?
12:16:47<lambdabot> not an expression: `let addPairwise' = [m + n | (m,n) <- zip list1 list2]'
12:17:45<yitz>Neut: put list1 and list2 as parameters after the function name. then put "in ..." at the end to try out your function with an example.
12:17:47<cob_jonas>> let { addPairwise' = [m + n | (m,n) <- zip list1 list2] } in addPairwise' [1,7] [8,4,2]
12:17:47<lambdabot> Not in scope: `list1'Not in scope: `list2'
12:17:56<Axman6>> let addPairwise' list1 list2 = [m + n | (m,n) <- zip list1 list2] in addPairwise' [1,7] [8,4,2]
12:17:57<lambdabot> [9,11]
12:18:06<Neut>ooo works
12:18:08<Neut>thanks
12:18:52<Ferdirand>> let addPairwise = zipWith (+) in addPairwise [1,7] [8,4,2]
12:18:54<lambdabot> [9,11]
12:19:20<Neut>yeah I know there are higher order functions for it,
12:19:26<Berengal>> getZipList $ (+) <$> ZipList [1,7] <*> ZipList [8,4,2]
12:19:27<lambdabot> [9,11]
12:19:28<Neut>just practising list comprehensions
12:21:00<mebbel>Neut: for bonus points, rewrite your list comprehensions using do syntax
12:24:24<urquell>Berengal: What's the <$> and <*> thingies?
12:24:42<Axman6>:t (<$>)
12:24:43<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
12:24:44<Axman6>:t (<*>)
12:24:45<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
12:25:44<Axman6>> (,) <$> [1..5] <*> ['a'..'c']
12:25:45<lambdabot> [(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c'),(4...
12:25:50<Axman6>> (,) <$> [1..3] <*> ['a'..'c']
12:25:51<lambdabot> [(1,'a'),(1,'b'),(1,'c'),(2,'a'),(2,'b'),(2,'c'),(3,'a'),(3,'b'),(3,'c')]
12:26:14<Axman6>:t (,) <$> [1..3]
12:26:15<lambdabot>forall a b. (Num a, Enum a) => [b -> (a, b)]
12:26:49<Philonous1>@type \x -> fmap ($ x)
12:26:51<lambdabot>forall a b (f :: * -> *). (Functor f) => a -> f (a -> b) -> f b
12:27:28<Neut>with the matches function, matches k xs = [x | x <- xs, x==k]
12:27:40<Neut>how would I chnage it so that it only returns unique items from a list
12:27:57<Philonous1>@type fmap.fmap
12:27:58<Neut>ie [1,2,3,2,1,4,5] ~~ [3,4,5]
12:27:59<lambdabot>forall (f :: * -> *) a b (f1 :: * -> *). (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b)
12:29:42<cob_jonas>> M.fromList [(1,5)]
12:29:44<lambdabot> fromList [(1,5)]
12:31:38<DrSyzygy>?quickcheck (M.toList . M.fromList) xs == xs where _ = xs :: [(Int,Int)]
12:31:39<lambdabot>Unknown command, try @list
12:31:42<DrSyzygy>?list
12:31:42<lambdabot>http://code.haskell.org/lambdabot/COMMANDS
12:31:55<DrSyzygy>Wasn't there some in-channel quickcheck interface?
12:32:10<Axman6>@check True
12:32:11<lambdabot> "OK, passed 500 tests."
12:32:20<DrSyzygy>?check (M.toList . M.fromList) xs == xs where _ = xs :: [(Int,Int)]
12:32:20<lambdabot> Parse error at "where" (column 34)
12:32:42<DrSyzygy>?check \(xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs
12:32:42<lambdabot> Unbalanced parentheses
12:32:49<cob_jonas>> let { ie s = map fst (filter ((1 ==) . snd) (M.toList (M.fromListWith (+) (map (flip (,) 1) s)))); } in ie [1,2,3,2,1,4,5] {- M is Data.Map -}
12:32:50<lambdabot> [3,4,5]
12:32:50<DrSyzygy>?check \(xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs)
12:32:50<lambdabot> Parse error at "M.toL..." (column 25)
12:32:57<cob_jonas>=> Neut
12:32:57<DrSyzygy>Meh
12:33:12<Neut>yes?
12:33:29<RayNbow>@check \xs :: [(Int,Int)] -> (M.toList . M.fromList) xs == xs
12:33:29<lambdabot> Parse error at "::" (column 5)
12:33:31<doserj>?check \xs -> (M.toList . M.fromList) xs == (xs::[(Int,Int)])
12:33:33<lambdabot> "Falsifiable, after 3 tests:\n[(2,-3),(-1,0)]\n"
12:33:40<cob_jonas>Neut: that's the function you wanted, didn't you?
12:33:49<cob_jonas>it gave [3,4,5] from [1,2,3,2,1,4,5]
12:33:50<DrSyzygy>doserj: Thanks.
12:33:56<cob_jonas>or do you also want to keep the order?
12:34:00<cob_jonas>because this one doesn't
12:34:16<cob_jonas>> let { ie s = map fst (filter ((1 ==) . snd) (M.toList (M.fromListWith (+) (map (flip (,) 1) s)))); } in ie [1,5,2,3,2,1,4]
12:34:18<lambdabot> [3,4,5]
12:34:20<Neut>is it possible to do with a simpler list comprehension?
12:34:22<DrSyzygy>?check \xs -> (sort . M.toList . M.fromList) xs == sort (xs::[(Int,Int)])
12:34:23<lambdabot> "Falsifiable, after 11 tests:\n[(0,3),(-3,0),(-6,-4),(3,0),(3,6)]\n"
12:34:47<cob_jonas>Neut: it probably is
12:34:50<cob_jonas>dunno
12:35:20<doserj>DrSyzygy: toList.fromList removes duplicate keys
12:35:23<cob_jonas>well this one has a map and filter which you can rewrite to a single list comprehension
12:35:47<cob_jonas>try it if you want to
12:35:48<DrSyzygy>doserj: I expected that but wanted to see QuickCheck confirm it. :-P
12:36:05<Neut>thanks cob_jonas
12:37:13<zachk>sweet, i wrote drop using foldr and zip
12:37:59<cob_jonas>zip? you mean zip with iota?
12:38:19<zachk>> mydrop2 5 [1..10] where mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list
12:38:21<lambdabot> <no location info>: parse error on input `where'
12:39:04<zachk>> let mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list in mydrop2 5 [1..10]
12:39:06<lambdabot> Overlapping instances for GHC.Show.Show ((a, b) -> b)
12:39:06<lambdabot> arising from a use...
12:39:12<cob_jonas>> let { mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list } in mydrop2 5 "policeman"
12:39:13<lambdabot> Overlapping instances for GHC.Show.Show ((a, b) -> b)
12:39:13<lambdabot> arising from a use...
12:39:24<zachk> mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list
12:39:38<zachk>> mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list
12:39:40<lambdabot> <no location info>: parse error on input `='
12:39:45<zachk>i quit it works in ghci
12:39:52<cob_jonas>@type let { mydrop2 n list = foldr (\x y-> if fst x<=n then y else (snd):y) [] $ zip [1..] list } in mydrop2 5 "policeman"
12:39:53<lambdabot>forall a b. [(a, b) -> b]
12:40:17<cob_jonas>maybe you copied it wrong?
12:41:44<zachk>yea i typed it wrong
12:41:52<zachk>did where stop working in lambdabot?
12:42:25<cob_jonas>huh?
12:43:36<byorgey>@where where
12:43:37<lambdabot>?where where
12:43:47<byorgey>@where hcar
12:43:47<lambdabot>http://www.haskell.org/communities/
12:43:54<byorgey>looks ok to me
12:44:51<zachk>> let mydrop n list = foldr (\x y-> if fst x<=n then y else (snd x):y) [] $ zip [1..] list in mydrop 5 [1..10]
12:44:54<lambdabot> [6,7,8,9,10]
12:44:58<zachk>there we go :-D
12:51:44<Phyx->Afternoon, I was wondering how do you check if a value is undefined?
12:51:53<cob_jonas>> SimpleReflect.var$concatMap(["\"","\\",",","> SimpleReflect.var$concatMap([","]!!)[3,0,1,0,0,2,0,1,1,0,2,0,2,0,2,0,3,0,2,0,4,0,4]"]!!)[3,0,1,0,0,2,0,1,1,0,2,0,2,0,2,0,3,0,2,0,4,0,4]
12:51:55<lambdabot> > SimpleReflect.var$concatMap(["\"","\\",",","> SimpleReflect.var$concatMap...
12:51:58<cob_jonas>Phyx-: you don't
12:52:26<Phyx->there must be someway
12:52:42<Botje>Phyx-: nope.
12:52:54<Botje>why do you need to know if something is undefined?
12:53:17<yitz>Phyx-: you design your code so that it will never be undefined, guaranteed.
12:53:35<cob_jonas>the whole point of bottom is that you don't check for it, right?
12:53:47<Botje>you /can't/ check for it
12:53:51<Botje>not without becoming bottom yourself
12:54:23<doserj>@hoogle isBottom
12:54:24<lambdabot>Test.QuickCheck.Batch isBottom :: a -> Bool
12:55:07<Phyx->doserj: thanks :)
12:56:08<Botje>O_O
12:56:17<doserj>Phyx-: you should know what you are doing, though, before you use this function
12:56:20<Botje>did the quickcheck guys solve the halting problem?
12:56:38<cob_jonas>Botje: no, it's just an unsafePerformIO without unsafe in it's name
12:56:53<Phyx->Botje: no, you just evaluate it and catch the exception
12:57:04<Phyx->i was thinking that aswell, but asked first
12:57:53<Phyx->doserj: yes, i know what i'm doing :) The only other way i could solve what i'm doing is by using syb and make a generic producer, but using undefined to initialize is much easier
12:58:53<yitz>> isBottom $ fix ("a" ++)
12:58:55<lambdabot> Not in scope: `isBottom'
12:59:22<yitz>> Test.QuickCheck.Batch.isBottom $ fix ("a" ++)
12:59:24<lambdabot> Not in scope: `Test.QuickCheck.Batch.isBottom'
12:59:31<yitz>darn
13:00:00<doserj>yitz: you didn't expect unsafePerformIO to be in scope in lambdabot, did you?
13:00:26<Phyx->hehehe
13:00:30<yitz>doserj: I didn't expect isBottom to exist at all, if you want to know the truth
13:01:36<doserj>yitz: it is cheating of course. it won't catch last [0..], for example.
13:01:58<Phyx->which i don't need anyway, i'm also cheating in a sense :)
13:02:10<cob_jonas>will it catch out of memory? or sigint?
13:02:40<cob_jonas>or killThread?
13:02:55<Phyx->it'll catch anything that throw an exception i beleive
13:02:56<yitz>so it runs the function in a separate thread and looks for an exception?
13:03:15<cob_jonas>yitz: why separate thread?
13:04:54<doserj>yitz: it is basically unsafePerformIO . try . evaluate
13:05:27<cob_jonas>isn't evaluate evil and does something completely different from its name?
13:05:36<cob_jonas>or that doesn't matter at this point?
13:05:43<yitz>ok got it.
13:07:28<cob_jonas>@src Test.QuickCheck.Batch.isBottom
13:07:28<lambdabot>Source not found. Sorry.
13:08:41<doserj>cob_jonas: evaluate is a (almost) just return $! x in the IO Monad
13:10:35<doserj>cob_jonas: 'evaluate x' is an IO action that, when executed, evaluates x
13:10:49<amgarching>hi, why doesnt this work: 1 % 2 % 3 ??
13:11:14<Peaker>@type (%)
13:11:15<lambdabot>forall a. (Integral a) => a -> a -> Ratio a
13:11:35<Peaker>@type (1%2)%3
13:11:37<lambdabot>forall t. (Integral t, Integral (Ratio t)) => Ratio (Ratio t)
13:12:08<kpreid>> 1 / 2 / 3 :: Ratio Integer
13:12:09<lambdabot> 1 % 6
13:12:22<Peaker>hmm -- (Ratio t) is not a type variable, why does @type allow it to be in a class constraint?
13:12:40<amgarching>how do I type, say i * j / k * l / m / n if I want it to be a Ratio?
13:12:41<Peaker>> 1%2%3
13:12:41<Berengal>Peaker: -XFlexibleContexts?
13:12:42<lambdabot> No instance for (GHC.Real.Integral (GHC.Real.Ratio t))
13:12:42<lambdabot> arising from a us...
13:12:43<kpreid>amgarching: because % is the "ratio of integers" operation and 1 % 2 is not an integer
13:12:49<Peaker>Berengal: what does that do?
13:13:04<kpreid>amgarching: use / instead
13:13:07<Berengal>Peaker: Allow more than just variables in contexts
13:13:24<DrSyzygy>> i * j / k * l / m / n :: Ratio Exp
13:13:25<lambdabot> Not in scope: type constructor or class `Exp'
13:13:36<DrSyzygy>> 2 * 3 / 4 * 5 / 6 / 7 :: Ratio Int
13:13:38<lambdabot> 5 % 28
13:13:50<kpreid>> 1 :: Expr
13:13:51<lambdabot> 1
13:14:00<DrSyzygy>> i * j / k * l / m / n :: Ratio Expr
13:14:02<lambdabot> Couldn't match expected type `GHC.Real.Ratio SimpleReflect.Expr'
13:14:05<cob_jonas>amgarching: if they're all integers, then (i * j * l) % (k * m * n) or just put fromInteger before each and then use * and /
13:14:13<kpreid>> i * j / k * l / m / n :: Expr
13:14:14<lambdabot> i * j / k * l / m / n
13:14:26<cob_jonas>as in (fromIntegral i) * (fromIntegral j) / (fromIntegral k) * ...
13:15:29<amgarching>ok, I got the idea, let me try. Thanks.
13:16:47<yitz>> 2 * 3 % 4 * 5 / 6 / 7
13:16:49<lambdabot> 5 % 28
13:17:43<yitz>amgarching: use % for the first division, / for the rest
13:17:57<cob_jonas>yitz: nope
13:18:08<yitz>cob_jonas: counterexample?
13:18:13<cob_jonas>yitz: that only works because number literals are both integers and rationals
13:18:20<yitz>cob_jonas: right
13:18:51<cob_jonas>well I'm not sure what type i and j etc really has in amgarching's question
13:19:11<yitz>the first one makes the type of the expression a Ratio, the rest are division for that type with the literals typed as Ratios
13:19:13<cob_jonas>but if they're all integers than that's not enough, if they're all ratios (including literals) then you don't need that one % neither
13:19:34<amgarching>cob_jonas: i <- [0..n], j <- [0..i], etc
13:19:35<yitz>cob_jonas: that's true, and then you *can't* use %.
13:20:03<cob_jonas>amgarching: same thing, the [0..n] can be lists of ratios
13:20:11<cob_jonas>amgarching: so then you can just use * and /
13:20:49<cob_jonas>amgarching: do { i <- [1..3]; j <- [1..3]; return (i / j) }
13:20:52<cob_jonas>> do { i <- [1..3]; j <- [1..3]; return (i / j) }
13:20:53<lambdabot> [1.0,0.5,0.3333333333333333,2.0,1.0,0.6666666666666666,3.0,1.5,1.0]
13:20:59<doserj>% is just supposed to be used as a (smart) constructor
13:21:02<cob_jonas>> do { i <- [1..3]; j <- [1..3]; return (i / j :: Ratio Integer) }
13:21:04<lambdabot> [1 % 1,1 % 2,1 % 3,2 % 1,1 % 1,2 % 3,3 % 1,3 % 2,1 % 1]
13:21:54<yitz>> [r | r <- [0..3]] :: [Rational]
13:21:56<lambdabot> [0 % 1,1 % 1,2 % 1,3 % 1]
13:22:15<FunctorSalad_>I don't think I get SCCs. I have: foo x = {-# SCC "foo_" #-} go ... where go = ...
13:22:37<yitz>> [r | r <- [0%1..3]]
13:22:40<lambdabot> [0 % 1,1 % 1,2 % 1,3 % 1]
13:22:47<FunctorSalad_>why is the automatic cost center for foo much more costly than my "foo_" ?
13:23:34<amgarching>of what type is r here: [ fromIntegral r | r <- [0..3]] ??
13:23:42<amgarching>> [ fromIntegral r | r <- [0..3]] ??
13:23:44<lambdabot> <no location info>: parse error (possibly incorrect indentation)
13:23:54<FunctorSalad_>@type [ fromIntegral r | r <- [0..3]]
13:23:56<lambdabot>forall b. (Num b) => [b]
13:25:55<zachk>haskell is starting to feel like legos :-D
13:26:11<xenoblitz>hi people can I ask a question regarding the following code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5276#a5276
13:26:18<DrSyzygy>zachk: That's good! Then the character of functional programming is reaching you.
13:26:28<xenoblitz>any one can shed some light why simulate latchC works but simulate latchC2 doesn't?
13:27:53<zachk>i would need to draw a schematic :-/
13:28:06<FunctorSalad_>meh. I covered all the branches of my function with SCCs but the auto top-level SCC of the function still has lots of own time
13:28:09<Phyx->lol, DrSyzygy untill someone tells you you're supposed to fit that round lego block in that square hole, then they show you how and you're left scratching your head :)
13:28:52<zachk>just take a Round->Square and go from Thuare
13:29:08<Phyx->lol
13:29:28<DrSyzygy>EXACTLY!
13:29:46<amgarching>so if I have data Monom = Monom Integer Integer Integer, I cannot use (Monom i j k) if any of (i,j,k) is "inferred/promoted" to Rationals? I get some obscure errmsg.
13:30:07<DrSyzygy>amgarching: Because you don't have integers any longer.
13:30:08<doserj>xenoblitz: I would guess latchC2 has a loop?
13:30:21<DrSyzygy>And there is no inherent way to convert a Rational to an Integer, with good reason.
13:30:21<xenoblitz>doserj: both of them actually have a loop
13:30:34<fasta>xenoblitz: post complete code next time
13:30:44<xenoblitz>doserj: just that one has two High inputs while the other has a Low and High
13:30:50<xenoblitz>fasta: it is complete code as far as i know
13:31:03<doserj>xenoblitz: it is missing type Var = String
13:31:06<fasta>xenoblitz: ire.hs:7:12: Not in scope: type constructor or class `Var'
13:31:17<xenoblitz>fasta: ouch yeah sorry let me amend that
13:31:29<cob_jonas>because of && one might have a loop but still terminate
13:32:02<xenoblitz>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5276#a5277
13:33:24<yitz>lookUpWire = flip lookup
13:34:12<doserj>("c", And (Label "a") (Label "f") doesn't loop if a is Low
13:34:48<xenoblitz>doserj: cause and false x is always false?
13:35:01<doserj>yes
13:35:33<xenoblitz>doserj: but how does it reach that conclusion? is this defined somewhere?
13:35:42<doserj>@src &&
13:35:43<lambdabot>True && x = x
13:35:43<lambdabot>False && _ = False
13:37:10<xenoblitz>I don't know if I understand correctly... can I view that unknown part as a thunk so False && thunk
13:37:21<xenoblitz>so False?
13:37:43<cob_jonas>> False && undefined
13:37:46<lambdabot> False
13:37:48<cob_jonas>> undefined && False
13:37:49<lambdabot> * Exception: Prelude.undefined
13:37:55<Phyx->http://en.wikipedia.org/wiki/Short-circuit_evaluation
13:38:29<Gracenotes>similar to short-circuit evaluation, but the mechanisms are entirely different
13:39:19<Gracenotes>not to mention, short-circuit evaluation is more like IO Bool -> IO Bool -> IO Bool. In Haskell, && is pure, Bool -> Bool -> Bool.
13:39:28<Gracenotes>but that's petty
13:40:02<Phyx->the only difference is that in haskell becauze of lazy evaluation short defining && doesn't need any special operators
13:40:08<Phyx->but the article mentions that aswell
13:41:54<xenoblitz>thanks guys I keep wondering how I come up against this problems :S
13:43:24<jeff_s_>I think of OR like "elem True list" and AND like "not (elem False list)"
13:44:46<xenoblitz>quickquestion related to what we were discussing:... when we write our own operators are they short-circuited or "normal"?
13:45:48<cob_jonas>xenoblitz: depends on how you write them
13:46:02<doserj>Haskell is lazy, so short-circuited is normal :) unless you explicitely pattern match, nothing is evaluated.
13:46:09<Phyx->exactly
13:46:30<kpreid>xenoblitz: but the order of cases can determine which argument is examined first, which makes a difference in termination
13:46:42<kpreid>in which argument has to be defined
13:46:48<jeff_s_>I imagine it's easy to rewrite && and || to not short-circuit.
13:46:48<kpreid>> False && undefined
13:46:49<lambdabot> False
13:46:52<kpreid>> undefined && False
13:46:53<lambdabot> * Exception: Prelude.undefined
13:46:56<cnwdup>How would I load (using System.Plugins) a data structure of type Foo s? Is this even possible? I thought I did this but now I have my code rewritten and I get errors about ambiguity of type s.
13:47:12<Phyx->jeff_s_: yes, just force evaluation before you compare
13:47:41<xenoblitz>oh i c so its a question of pattern matching... if a case exists with a _ you can create short-circuited operators
13:48:02<kpreid>xenoblitz: exactly. well, _ or ~
13:48:02<zachk>dont use the _ wildcard
13:48:02<zachk>otherwise you wont be able to evaluate it
13:48:11<zachk>whats ~ match to
13:48:13<kpreid>but also a plain variable
13:48:44<yottis>is _ really special or just an idiom?
13:48:47<xenoblitz>in the end its how you pattern match then that defines if an operator or function is short-circuited or not
13:48:53<doserj>> let False && False = False; False && True = False ; True && False = False; True && True = True in False && undefined
13:48:54<jeff_s_>I was just gonna ask the same thing. I don't remember seeing ~ in pattern matches yet.
13:48:54<lambdabot> * Exception: Prelude.undefined
13:48:57<kpreid>if I write "foo False bar = ..." then it doesn't evaluate bar, but does evaluate the first arg and check it
13:49:02<kpreid>yottis: it's special
13:49:08<kpreid>> let foo _ _ = 1 in foo 1 2
13:49:09<lambdabot> 1
13:49:14<kpreid>> let foo x x = 1 in foo 1 2
13:49:15<lambdabot> Conflicting definitions for `x'
13:49:15<lambdabot> In the definition of `foo'
13:49:21<kpreid>> let foo _x _y = 1 in foo 1 2
13:49:23<lambdabot> 1
13:49:24<yottis>so foo x y = x is different from foo x _ = x?
13:49:30<kpreid>yottis: no
13:49:48<kpreid>the specialness is just that it doesn't actually bind any variable and can be used many times
13:50:08<doserj>_ is just an identifier that cannot be used on the right hand side
13:50:12<kpreid>it makes no difference if you were to replace every _ in a program with distinct variable names
13:50:14<yottis>is the difference that _ can't be referenced on the right-hand side?
13:50:18<yottis>echo that
13:50:31<kpreid>the other difference is that you can use it multiple times on the left
13:50:46<xenoblitz>amazing stuff I hope i remember hehe
13:50:57<jeff_s_>4.4 Lazy patterns @ http://www.haskell.org/tutorial/patterns.html
13:51:44<xenoblitz>thanks guys
14:09:33<mib_e7tcavos>hey ive gt a problem
14:09:46<mib_e7tcavos>say i have a list of users
14:09:55<mib_e7tcavos>[user]
14:10:17<mib_e7tcavos>and im trying to find if my user is in a list of users
14:10:30<mib_e7tcavos>so technically
14:10:47<mib_e7tcavos>user == [user] or is part of
14:10:57<mib_e7tcavos>any ideas how to do that
14:11:04<cnwdup>> lookup 2 [1..10]
14:11:05<lambdabot> No instance for (GHC.Enum.Enum (t, b))
14:11:05<lambdabot> arising from the arithmetic seque...
14:11:11<mauke>> elem 2 [1..10]
14:11:12<cnwdup>> lookup (2::Int) [1..10]
14:11:12<lambdabot> True
14:11:13<lambdabot> No instance for (GHC.Enum.Enum (GHC.Types.Int, b))
14:11:13<lambdabot> arising from the arit...
14:11:21<mauke>cnwdup: what
14:11:30<doserj>cnwdup: lookup is for association lists
14:11:30<cnwdup>Woups. That was just stupid. (:
14:11:44<mib_e7tcavos>kl
14:13:00<Botje>mib_e7tcavos: there is an "elem" function
14:13:07<Botje>as mauke pointd out
14:13:21<mib_e7tcavos>yeah "looking" it up now
14:13:33<Phyx->@hoogle elem
14:13:33<lambdabot>Prelude elem :: Eq a => a -> [a] -> Bool
14:13:33<lambdabot>Data.ByteString elem :: Word8 -> ByteString -> Bool
14:13:33<lambdabot>Data.Foldable elem :: (Foldable t, Eq a) => a -> t a -> Bool
14:13:44<Phyx->@hoogle elem --info
14:13:45<lambdabot>Prelude elem :: Eq a => a -> [a] -> Bool
14:13:45<lambdabot>
14:13:45<lambdabot>elem is the list membership predicate, usually written in infix form, e.g., x `elem` xs.
14:16:40<Peaker>@hoogle unsafePerformIO --info
14:16:40<lambdabot>Foreign unsafePerformIO :: IO a -> a
14:16:41<lambdabot>
14:16:41<lambdabot>This is the "back door" into the IO monad, allowing IO computation to be performed at any time. For this to be safe, the IO computation should be free of side effects and independent of its environmen
14:16:41<lambdabot>t.
14:18:45<Peaker>was --info always there? :P
14:19:02<jeff_s_>@hoogle --help
14:19:03<lambdabot>Go to the website for full help, http://haskell.org/hoogle/
14:19:04<lambdabot>
14:19:04<lambdabot>Flag reference:
14:19:17<ray>@hoggle safePerformIO
14:19:17<lambdabot>Foreign unsafePerformIO :: IO a -> a
14:19:18<lambdabot>System.IO.Unsafe unsafePerformIO :: IO a -> a
14:19:46<Phyx->heh, is that an alias?
14:20:08<ray>no, lambdabot has spelling error tolerance
14:20:25<Phyx->to what extend?
14:20:33<Phyx->@haggle test
14:20:33<lambdabot>Test.HUnit.Base test :: Testable t => t -> Test
14:20:33<lambdabot>Test.HUnit.Base data Test
14:20:33<lambdabot>Test.QuickCheck class Testable a
14:20:36<Phyx->hmm
14:20:36<jeff_s_>someone had fun making hoogle
14:20:41<Gracenotes>I think it's Levenshtein distance
14:20:47<Gracenotes>er... lemme see.
14:21:17<ray>but what specific levenshtein distance is the tolerance
14:21:27<mauke>2
14:21:34<Phyx->aha
14:21:41<Gracenotes>:o so I see
14:21:59<ray>so transposing 2 letters uses it up
14:22:14<ray>except in the degenerate case where you transpose 2 letters that are the same
14:22:28<Phyx->doesn't Hayoo use this?
14:22:45<Peaker>I don't understand the difference between Hoogle and Hayoo
14:22:49<ray>lost my hayoo mail
14:22:54<Peaker>Hayhoo is more comprehensive?
14:23:25<ray>hayoo's newer and possibly fancier
14:23:28<boegel>Hayoo included packages, Hoogle doesn't
14:23:36<boegel>s/included/includes
14:23:46<Phyx->i find hoogle returns better results
14:23:51<cob_jonas>but you can compile hoogle database for any package, can't you?
14:23:57<cob_jonas>locally
14:24:02<boegel>maybe, yeah
14:24:28<Phyx->and doesn't hayoo use Textual Type searching and Hoogle 4 Structural Edit distance to do searching?
14:25:17<Gracenotes>mauke: hm. where is the matching in the lambdabot source?
14:25:23<Phyx->so hayoo alpha normalizes and strength reduced alpha normalizes, then does substring searching
14:25:33<mauke>Gracenotes: dunno
14:25:44<Peaker>Phyx-: What's "structural edit distance"?
14:26:18<Phyx->Peaker: difference in only structure between the search value and result value
14:26:42<Peaker>as in - ignoring names?
14:27:05<Gracenotes>aha.
14:27:47<Phyx->Peaker: for instance, if you search for "Maybe Int" the structure it tries to match against is "? ?"
14:27:50<Gracenotes>the edit distance cut-off is < 3
14:27:57<Phyx->it's only usefull for the typeseaches i beleive
14:27:58<Gracenotes>so <= 2, as mauke said...
14:28:04<cob_jonas>@hoogle :: Maybe Int
14:28:04<lambdabot>Prelude Nothing :: Maybe a
14:28:05<lambdabot>Data.Maybe Nothing :: Maybe a
14:28:05<lambdabot>Language.Haskell.TH maxPrecedence :: Int
14:28:27<Peaker>Phyx-: I think it would make sense to lose only names of type variables, and not of everything else?
14:28:43<Peaker>Though it could try and substitute everything for a super-class/subclass, etc
14:28:59<cob_jonas>it does that too
14:29:16<Phyx->Peaker: you have to take into account things like aliases, missing instances, boxing etc
14:29:32<cob_jonas>@hoogle (Monad f) => f (a -> b) -> f a -> f b
14:29:32<lambdabot>Control.Monad ap :: Monad m => m (a -> b) -> m a -> m b
14:29:32<lambdabot>Control.Monad liftM :: Monad m => (a1 -> r) -> m a1 -> m r
14:29:32<lambdabot>Control.Applicative (<*>) :: Applicative f => f (a -> b) -> f a -> f b
14:29:40<cob_jonas>@hoogle (Functor f) => f (a -> b) -> f a -> f b
14:29:40<lambdabot>Prelude fmap :: Functor f => (a -> b) -> f a -> f b
14:29:40<lambdabot>Control.Applicative (<$>) :: Functor f => (a -> b) -> f a -> f b
14:29:40<lambdabot>Control.Monad fmap :: Functor f => (a -> b) -> f a -> f b
14:29:46<Phyx->so it uses the structure to quickly reduce the set of possibles i beleive and then tries to sort through the best matched ones
14:29:51<cob_jonas>@hoogle (Applicative f) => f (a -> b) -> f a -> f b
14:29:51<lambdabot>Control.Applicative (<*>) :: Applicative f => f (a -> b) -> f a -> f b
14:29:51<lambdabot>Control.Applicative (<**>) :: Applicative f => f a -> f (a -> b) -> f b
14:29:51<lambdabot>Control.Applicative liftA :: Applicative f => (a -> b) -> f a -> f b
14:31:25<cnwdup>@src map
14:31:26<lambdabot>map _ [] = []
14:31:26<lambdabot>map f (x:xs) = f x : map f xs
14:31:29<Gracenotes>this is rather strange. The "closests" function is used, but I can't find it anywhere
14:31:32<Phyx->Peaker: that way, for instance searching for Monad m => m a would also find Maybe a, which *might* be what you want,
14:31:32<cnwdup>@type map
14:31:33<lambdabot>forall a b. (a -> b) -> [a] -> [b]
14:31:35<Gracenotes>@hoogle closests
14:31:35<lambdabot>No results found
14:31:38<Gracenotes>:.
14:32:01<mux>:t foldr ((:) . f) []
14:32:03<lambdabot>forall b a. (Show a, SimpleReflect.FromExpr b) => [a] -> [b]
14:32:05<Peaker>(<**>) = flip (<*>)? or (<**>) = liftA2 (flip ($)) ?
14:32:09<mux>: \f -> t foldr ((:) . f) []
14:32:14<mux>:t \f -> t foldr ((:) . f) []
14:32:16<lambdabot> Couldn't match expected type `((a -> b -> b) -> b -> [a] -> b)
14:32:16<lambdabot> -> (a1 -> [b1] -> [b1])
14:32:16<lambdabot> -> [a2]
14:33:00<Phyx->Peaker: if you want to know more look at http://community.haskell.org/~ndm/hoogle/
14:34:13<Peaker>> let (<**>) = liftA2 (flip id) in [10,20] <**> [(+1),(+2)]
14:34:15<lambdabot> [11,12,21,22]
14:34:19<Peaker>> [10,20] <**> [(+1),(+2)]
14:34:21<lambdabot> [11,12,21,22]
14:34:31<Peaker>> let (<**>) = flip (<*>) in [10,20] <**> [(+1),(+2)]
14:34:32<lambdabot> [11,21,12,22]
14:34:39<Peaker>aha
14:34:55<Gracenotes>okay!
14:35:29<cob_jonas>@type <**>
14:35:30<lambdabot>parse error on input `<**>'
14:35:32<cob_jonas>@type (<**>)
14:35:33<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f a -> f (a -> b) -> f b
14:35:58<Peaker>@type flip (<*>)
14:35:59<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f a -> f (a -> b) -> f b
14:36:07<Peaker>the difference is in the way effects are sequenced
14:36:37<cob_jonas>I see
14:36:39<Peaker>flip (<*>) sequences right-to-left, and liftA2 (flip id) sequences left-to-right
14:47:04<mgee>hi, did somebody already worked with QIO? The quantum computer IO monad.
14:47:18<mib_e7tcavos>hey
14:47:45<mib_e7tcavos>anyone know if there is a function for a avergae of a list
14:48:01<dmwit>mib_e7tcavos: No.
14:48:08<mib_e7tcavos>list of int
14:48:13<dmwit>It's easy to write, though. =)
14:48:14<cob_jonas>but there's many ways to write it
14:48:15<mib_e7tcavos>nope ok
14:48:22<mib_e7tcavos>yeah ill give it ago
14:50:01<jmcarthur_work>there is a fast way and a slow way. keep that in mind as you write it :)
14:50:35<jmcarthur_work>(this particular case has been complained about before because the most naive solution isn't the fastest)
14:50:43<dmwit>No, there's a space-efficient way and a space-inefficient way. They're about equally fast. =)
14:50:49<Pellwurst>is there a special symbol to match a whitespace as a regexp?
14:51:02<dmwit>Pellwurst: In PCRE, \s
14:51:14<mauke>[[:space:]] in posix
14:51:15<jmcarthur_work>well, the naive solution can also easily overflow the stack if it's built without optimizations
14:51:22<dmwit>ACTION nods
14:51:28<mib_e7tcavos>average :: [Int] -> Int
14:51:34<Pellwurst>mauke: thx, that should do the job
14:51:41<mib_e7tcavos>average I = sum I / length I
14:51:43<mib_e7tcavos>?
14:52:06<dmwit>mib_e7tcavos: Seems close. There's a few problems left.
14:52:31<dmwit>mib_e7tcavos: First, variable names have to start with a lower-case letter, to distinguish them from constructor names.
14:52:41<mib_e7tcavos>yeah
14:52:49<mib_e7tcavos>small i lol
14:52:57<dmwit>mib_e7tcavos: Also, length returns an Int, which you can't divide by, so you'll need to convert it:
14:53:00<dmwit>:t fromIntegral
14:53:01<lambdabot>forall a b. (Integral a, Num b) => a -> b
14:53:24<mib_e7tcavos>ah ok
14:53:46<doserj>mib_e7tcavos: what should the average of [1,2] be?
14:53:48<dmwit>As a stylistic note, it's a common idiom in Haskell to call a list of things by a name ending in 's', so xs, ys, zs, is, as, numbers, etc.
14:53:59<sammartin>mib_e7tscos: have you thought about returning a tuple of sum and length as an option?
14:54:05<jeff_s_>average [1,2] = 1
14:54:22<dmwit>jeff_s_: ewww
14:54:26<jeff_s_>hehe
14:54:27<Phyx->lol
14:54:32<dmwit>average [1,2] = 3 % 2
14:55:15<cob_jonas>I thought yyou should fold with a tuple
14:55:30<jeff_s_>I like integer math, 3/2 = 1 has its uses
14:55:34<dmwit>cob_jonas: Yep, but for a beginner, the naive solution is probably fine.
14:55:46<dmwit>Until we have long lists, readable is better than efficient. =)
14:55:47<jeff_s_>actually, how do you do integer divsion in haskell anyway?
14:55:53<dmwit>:t div
14:55:54<lambdabot>forall a. (Integral a) => a -> a -> a
14:56:01<jeff_s_>do you have to truncate the rational number?
14:56:14<dmwit>...no...
14:56:17<mib_e7tcavos>thanks guys gt it now cheers
14:56:24<Absolute0>Is 'type t = (Int k, Char v) => Data.Map.Map k v' valid?
14:56:28<Absolute0>I am getting an error
14:56:29<Ferdirand>btw, is it possible to automatically fuse two foldls over the same list with a single tuple foldl ?
14:56:32<MyCatVerbs>> [5 `div` 2, 14 `div` 3]
14:56:33<lambdabot> [2,4]
14:56:41<Botje>Absolute0: what is that supposed to do?
14:56:43<dmwit>Absolute0: Int and Char aren't classes.
14:56:52<Absolute0>type t = Data.Map.Map Int Char won't work either
14:56:53<jeff_s_>Ferdirand - ya, start with ([],[]) instead of []
14:57:01<dmwit>Absolute0: And type names must start with an uppercase letter.
14:57:08<Botje>Absolute0: that's because type names start with an uppercase letter
14:57:10<dmwit>type T = Map Int Char
14:57:12<Absolute0>ah
14:58:30<Absolute0>also importing libraries using the qualified keyword fails in ghci
14:58:38<dmwit>yes
14:58:41<Absolute0>is there any way to override that?
14:59:12<dmwit>Do it in a file?
14:59:27<Absolute0>nevermind.
14:59:47<Absolute0>ghci should behave like a file!
15:00:38<dmwit>I'm going to go ahead and claim that mutual recursion makes your claim false.
15:04:08<byorgey>ghci could behave like a file if you embed it in a (TimeTravelT IO) monad
15:04:50<byorgey>not just mutual recursion, the fact that declarations don't have to be an any particular order in a file is good enough.
15:04:50<dmwit>To be honest, though, I don't see how come it can't behave like a file, now that we have :{ :}
15:05:04<byorgey>be *in any
15:05:22<byorgey>dmwit: are you at school?
15:05:33<dmwit>I'll be in in about an hour or so.
15:05:39<Phyx->what's :{ :} ?
15:05:47<byorgey>ok, me too
15:05:54<dmwit>Phyx-: :{ starts a multiline ghci command
15:06:00<byorgey>sad devil, happy devil!
15:06:08<dmwit>heh
15:06:11<Phyx->hmm ok
15:06:28<dmwit>byorgey: I've got a long list of links talking about inter- and intra-city transportation for Hac \phi.
15:06:36<byorgey>sweet!
15:07:05<cob_jonas>let me try to write this average thing the way I wanted now because when mibbit asked I tried to but got an error and then I got called away
15:07:22<dmwit>cob_jonas: Good idea!
15:07:30<cob_jonas>I know I wrote it a few times of course
15:09:25<Peaker>byorgey, dmwit: ghci could suspend disbelief and allow to use yet-inexistent names
15:09:30<jeff_s_>ACTION scrolls up
15:09:36<jeff_s_>thanks MyCatVerbs for the reminder about `div`
15:09:40<dmwit>Peaker: I can't even imagine how many problems that would cause.
15:09:42<Peaker>byorgey, dmwit: It could also re-evaluate dependent stuff when existing names are re-defined
15:09:58<dmwit>Peaker: I make so many typos in ghci it's not even funny.
15:09:59<Peaker>dmwit: or, it could have a special notation to enable that for some name
15:10:01<byorgey>Peaker: maybe. sounds horribly complicated and full of nasty surprises for the user.
15:10:10<dmwit>exactlyl
15:10:13<dmwit>ah
15:10:20<dmwit>Perfect examplel. ;-)
15:10:21<Peaker>dmwit: blah = @bleh bluh
15:10:31<byorgey>dmwit: hehl
15:10:34<Peaker>bluh -- undefined
15:10:39<Peaker>bleh -- OK that it is undefined
15:10:40<dino->oo, I didn't know about that :{
15:11:00<jeff_s_>@hoogle blah = bleh bluh
15:11:01<lambdabot>Parse error:
15:11:01<lambdabot> --count=20 "blah = bleh bluh"
15:11:01<lambdabot> ^
15:11:05<Peaker>when blah is used - only then it will try to type/use it
15:11:27<Phyx->jeff_s_: ?
15:11:33<jeff_s_>Just being silly.
15:11:39<Phyx->lol
15:11:49<Peaker>byorgey, dmwit: What problems do you envision with it?
15:12:00<Peaker>I see it *complicating* ghci, but worse isn't better is it? :)
15:13:02<dmwit>Peaker: I propose that you implement it and prove us wrong. ;-)
15:13:11<Peaker>dmwit: I don't know ghc :(
15:13:40<cob_jonas>> let { ave :: [Float] -> Float; ave = snd . foldl' (\(k, a) x -> (k + 1, a + (x - a)/(k + 1))) (0, 0); } in ave [3,2,2] {- throw in a map fromIntegral if it has to work on a list of Ints -}
15:13:41<lambdabot> 2.3333333
15:13:44<byorgey>Peaker: I don't know of any specific things off the top of my head. it was just a feeling. you may be right.
15:13:46<cob_jonas>there, that way
15:14:06<Peaker>byorgey: CL does essentially that, doesn' tit?
15:14:19<byorgey>Peaker: I've no idea, does it?
15:14:31<cob_jonas>Peaker: so how would that undefined names thingy work?
15:14:33<byorgey>cob_jonas: nice, only one traversal
15:14:38<cob_jonas>what would an undefined name do?
15:15:17<Peaker>cob_jonas: well, I think there could be a customizable configuration whether @ are necessary, and if they are, and you have @ on a name, then it only checks the syntax, and waits for that name to exist before evaluating the expression
15:15:25<dmwit>cob_jonas: That looks like a lot of extra division to me.
15:15:31<Phyx->that seems overly complicated to me...
15:15:55<Peaker>cob_jonas: unmarked @ names will behave as they do today
15:16:03<dmwit>> let ave = uncurry (/) . foldl' (\(k, a) x -> (k + 1, a + x)) (0, 0) } in ave [3, 2, 2]
15:16:04<lambdabot> <no location info>: parse error on input `}'
15:16:10<dmwit>> let ave = uncurry (/) . foldl' (\(k, a) x -> (k + 1, a + x)) (0, 0) in ave [3, 2, 2]
15:16:11<lambdabot> 0.42857142857142855
15:16:19<dmwit>Oh, right.
15:16:20<cob_jonas>dmwit: but at least it's more precise in some cases (for arbitary float arguments) than just doing one division
15:16:32<byorgey>dmwit: that's the reciprocal, I think
15:16:33<cob_jonas>for [3,2,2] it doesn't matter of course
15:16:34<dmwit>> let ave = uncurry (/) . foldl' (\(a, k) x -> (a+x, k+1)) (0, 0) in ave [3, 2, 2]
15:16:35<lambdabot> 2.3333333333333335
15:16:44<dmwit>cob_jonas: Right, that's possibly true.
15:17:17<byorgey>ACTION runs screaming from the dark art of accurate numerics
15:17:19<cob_jonas>Peaker: but would those names be allowed in IO <- binding statements?
15:17:38<cob_jonas>Peaker: I mean, if it's just plain assignments then right, you just print them late
15:18:12<Peaker>cob_jonas: ghci does effect execution and ordinary let bindings.. The former can require entire expression to be well-defined, and the latter can wait
15:19:12<Peaker>Type definitions could work the same - except perhaps if the type is re-defined then all the former uses of it in the shell should either be invalidated, re-evaluated, or remain using the old type, where the new type only shares a name with the old one
15:20:01<dmwit>Peaker: You know, these days you don't have to know GHC to write your own Haskell interpreter.
15:20:13<dmwit>Check out the hint package on Hackage, and wow us with your innovation. =)
15:20:36<Peaker>at the very least I'll have to parse my own syntax?
15:20:43<Peaker>(for the annotations)
15:20:46<cob_jonas>Peaker: so would it work if you entered something like "let { x = @y }" and then "y <- f x" ?
15:21:00<Peaker>cob_jonas: I think that should be fine
15:21:10<dmwit>Yep, you might have to scan for annotations.
15:21:36<dmwit>You could separate annotations from Haskell code in some clever way, though.
15:21:56<cob_jonas>which one does it run first?
15:22:17<dmwit>:t fixIO
15:22:18<lambdabot>Not in scope: `fixIO'
15:22:28<dmwit>?instances MonadFix
15:22:28<lambdabot>((->) r), Either e, ErrorT e m, IO, Maybe, RWS r w s, RWST r w s m, Reader r, ReaderT r m, ST s, State s, StateT s m, Writer w, WriterT w m, []
15:22:28<cob_jonas>yeah, I could never wrap my head around that fixIO thing
15:22:32<cob_jonas>oh well
15:22:44<cob_jonas>anyway, defining types in ghc is sort of easy
15:22:53<cob_jonas>my plugin sort of works for that
15:22:53<byorgey>cob_jonas: hm? what do you mean, which would it run first?
15:23:04<mauke>@hoogle fixIO
15:23:04<lambdabot>System.IO fixIO :: (a -> IO a) -> IO a
15:23:13<mauke>ah, mfix[IO]
15:25:16<cob_jonas>http://erxz.com/pb/17809 allows you to define types inline in ghci
15:25:30<Peaker>> mfix return
15:25:31<lambdabot> No instance for (GHC.Show.Show (m a))
15:25:31<lambdabot> arising from a use of `M7875774271...
15:25:46<Peaker>> fix id
15:25:51<lambdabot> mueval-core: Prelude.read: no parse
15:25:51<lambdabot> mueval: ExitFailure 1
15:26:06<MyCatVerbs>Ouch! That loses all current bindings. Not good. :/
15:26:26<Peaker>@type both
15:26:27<lambdabot>forall (a :: * -> * -> *) b c. (Arrow a) => a b c -> a (b, b) (c, c)
15:26:34<Peaker>MyCatVerbs: that's a binding from earlier?
15:27:50<ray>fix id should be thread killed
15:27:57<ray>why wouldn't it parse?
15:28:32<mauke>I think the parse error refers to the result
15:28:53<MyCatVerbs>Peaker: the inline type definition hack cob_jonas pointed out.
15:29:07<ray>i guess that could be
15:29:15<Peaker>oh
15:29:16<MyCatVerbs>Win: it lets you define data, newtypes and types inline in GHCi.
15:29:35<cob_jonas>MyCatVerbs: yes, but if you have plain let bindings (not IO bindings) you can do them with :decl and then they're reintroduced every time you add a new binding and not lost
15:29:38<Peaker>one after the other, or only the last one survives?
15:29:43<MyCatVerbs>Lose: the only way of implementing that was to build and load a module, which means you suddenly lose all your bindings.
15:30:26<cob_jonas>Peaker: one after the other, if you try to add two of the same name you get an error so use the :undecl command to remove the previous one
15:30:57<MyCatVerbs>cob_jonas: a large portion of the time in GHCi, I am working with IO bindings. Generally I like to put my data sets in files rather than type them into the REPL.
15:31:18<Peaker>MyCatVerbs: put them in an .hs file
15:31:36<alexsuraci>Is there such a thing as a tuple containing one value?
15:31:43<dmwit>No.
15:31:43<mauke>alexsuraci: no
15:31:50<cob_jonas>MyCatVerbs: well, you could bind the IO commands to functions and run those functions as an IO binding, or just use readline to go back and rerun old statements
15:31:53<alexsuraci>alright, thought so
15:31:55<alexsuraci>thanks
15:31:58<dmwit>alexsuraci: There's Identity.
15:32:02<dmwit>> Identity 3
15:32:03<lambdabot> No instance for (GHC.Show.Show (Control.Monad.Identity.Identity t))
15:32:03<lambdabot> aris...
15:32:12<cob_jonas>dmwit: yes, but that's not Showable I think
15:32:16<cob_jonas>> Identity 5
15:32:16<lambdabot> No instance for (GHC.Show.Show (Control.Monad.Identity.Identity t))
15:32:17<lambdabot> aris...
15:32:40<wjt>there's OneTuple on hackage :D
15:32:41<alexsuraci>well, more from a language implementation standpoint than utility
15:32:44<alexsuraci>haha
15:32:50<dmwit>> runIdentity (Identity 3)
15:32:52<lambdabot> 3
15:33:36<Phyx->@cabal info OneTuple
15:33:37<lambdabot> bzzt.
15:33:39<Phyx->lol
15:33:48<dmwit>eh?
15:33:50<dmwit>?help cabal
15:33:50<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
15:34:01<dmwit>Okay, so it's auto-correcting to something...
15:34:01<ray>> let show Identity a = "Identity " ++ show a in Identity 3 -- or something
15:34:03<lambdabot> Constructor `Control.Monad.Identity.Identity' should have 1 argument, but h...
15:34:04<Phyx->@hackage info OneTuple
15:34:05<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/info OneTuple
15:34:11<Phyx->...
15:34:19<dmwit>ray: show (Identity a), and it needs to be in an instance block.
15:34:48<ray>yes, (Identity a)
15:35:05<bavardage>o/
15:35:20<dmwit>ACTION calls on bavardage
15:35:23<dmwit>Yes, dear?
15:37:39<cob_jonas>by the way, let me note that my ghci extension also lets you import modules qualified as
15:37:53<cob_jonas>so you can finally write :import qualified Data.Map as M
15:38:00<cob_jonas>some may find this the most important use
15:39:21<cob_jonas>eg. http://erxz.com/pb/17810
15:41:59<cnwdup>> let xs = [1::Int, 'c'::Char] :: forall a. Show a => [a] in map show xs
15:42:00<lambdabot> Couldn't match expected type `GHC.Types.Int'
15:42:40<cnwdup>How can I create such a list containing arbitrary values and restricting the usable functions to a few working on any types?
15:44:15<mauke>you can't directly
15:44:21<cnwdup>Ok.
15:44:27<integral>> let xs = [1 :: Int, 'c' :: Char] :: [forall a. Show a => a] in map show xs
15:44:29<lambdabot> Cannot match a monotype with `forall a. (GHC.Show.Show a) => a'
15:44:40<mauke>you can make an existential wrapper and wrap each element individually
15:45:43<Gracenotes>data Showable = forall a. Show a => Showable a
15:46:03<Gracenotes>.. possibly deriving Show. All you can do with it is show, after all...
15:46:14<integral>heh :-)
15:46:58<Ferdirand>jeff_s_: well, I know how to do it by hand. I was wondering if the compiler could do it for me, with a rule or so
15:47:17<Ferdirand>or if there was some subtle hidden catch that would make it incorrect
15:47:53<cob_jonas>or just use a normal algebraic type
15:49:16<cob_jonas>> let { xs = [Left 1, Right 'c']; } in map (either show show) xs
15:49:17<lambdabot> ["1","'c'"]
15:51:10<mauke>> let xs = [show 1, show 'c'] in xs
15:51:12<lambdabot> ["1","'c'"]
15:52:07<arcatan>what would be my options if i wanted to generate png images with haskell?
15:54:46<byorgey>arcatan: what sort of png images?
15:55:03<mib_e7tcavos>hey another noob question here
15:55:16<byorgey>mib_e7tcavos: ask away!
15:55:32<Absolute0>Are list comprehensions lazy when passed as parameters to other functions?
15:55:37<mib_e7tcavos>i need to return top ten films by fans
15:55:59<mib_e7tcavos>all ive gt so far is
15:56:17<mib_e7tcavos>topTenFilms :: [Film] -> [Title]
15:56:28<Absolute0>I am wondering if it is better to insert each element into a map individually or create a list and call fromList function?
15:56:30<mib_e7tcavos>topTenFilms films = [title | Film title director year fans <- films, length fans >= m ]
15:56:38<mib_e7tcavos>im having brain freezer
15:56:54<dmwit>arcatan: Cairo, diagrams, Gtk2Hs, HsMagick, ...
15:57:35<tetha>mib_e7tcavos: couldn't you sort the films by fan-count and take the first 10?
15:57:39<dmwit>Absolute0: Use fromList.
15:57:42<mib_e7tcavos>anyone gt any ideas of what i shud look at
15:57:46<byorgey>mib_e7tcavos: try sorting the films first by number of fans
15:57:49<mib_e7tcavos>yes
15:57:54<mib_e7tcavos>ah yeah
15:57:55<Absolute0>dmwit: just as effecient?
15:57:58<mib_e7tcavos>cheers guys
15:58:01<byorgey>mib_e7tcavos: you can even use sortBy
15:58:14<Absolute0>dmwit: if the list is large creating the list and then sorting it within Data.Map seems silly.
15:58:16<dmwit>Absolute0: Just as, and may in the future be more efficient.
15:58:32<dmwit>Absolute0: I don't understand; why would that be silly?
15:58:38<Absolute0>dmwit: as apposed to individually inserting each one
15:58:50<arcatan>byorgey: dynamically generated png images serverd over HTTP
15:58:54<Absolute0>isn't inserting one quicker than sorting an entire list?
15:59:07<dmwit>Absolute0: Maybe, but inserting them all is not.
15:59:16<Absolute0>ah
15:59:23<dmwit>Absolute0: Also, what is up with your thing against sorting? Data.Map doesn't call sort anywhere.
15:59:42<byorgey>arcatan: yes, but I mean, what will the images be like? how simple/complex? will it involve putting together other images, or just generating simple shapes, or...?
15:59:46<Absolute0>dmwit: how does it achieve log n lookup?
15:59:52<Absolute0>its sorts the map
16:00:09<Absolute0>i think it says so in the docs
16:00:19<dmwit>Absolute0: ...sort of, yes.
16:00:32<byorgey>it uses a balanced tree.
16:00:33<arcatan>byorgey: oh. i will generate the pixel data myself and want to encode it in a png
16:00:34<dmwit>Absolute0: Insertion puts the element "in the right place," so to speak.
16:00:35<tetha>isn't data.map a tree?
16:01:18<byorgey>arcatan: ah. In that case you probably want to use HsMagick, or perhaps Cairo
16:01:22<dmwit>arcatan: Then I suggest Gtk2Hs or HsMagick.
16:01:23<Beelsebob>depends on the implementation tetha
16:01:24<SamB>tetha: sure!
16:01:29<Beelsebob>but in most implementations... yes
16:01:33<dmwit>arcatan: Cairo can be nice, but definitely not if you want pixel-level control.
16:01:42<SamB>well, I mean, you could use some other kind of tree to implement it
16:01:45<byorgey>ok, thanks dmwit, I didn't know that =)
16:01:57<SamB>and if you were insane you could even use an alist
16:02:01<arcatan>dmwit: i do
16:02:03<cob_jonas>Absolute0: if the most efficent method is putting the elements in one by one, then that's what fromList will do, so I think fromList is always the most efficent if you can generate the list in a pure lazy way
16:02:15<Absolute0>dmwit: Inserting a newly generated element into the map is slower than first generating the entire list and calling Map.fromList?
16:02:22<SamB>but nobody would want to use the alist-based Data.Map, would they ?
16:02:27<cob_jonas>the insertion by one might be needed if you can't generate the list lazily, eg. if you're reading the elements from a file one by one
16:02:28<Absolute0>ah alright
16:02:55<Absolute0>i guess i was forgetting that haskell is lazy.
16:02:56<Absolute0>:)
16:03:02<dmwit>Absolute0: It's hard to compare those two operations, because they don't start and end at the same place.
16:03:09<tetha>Absolute0: well, you are venturing into the land of optimizing against a single standard library there
16:03:22<dmwit>Absolute0: Yes, inserting one element is faster than generating a whole new Map, but those are rarely the two options you're comparing.
16:04:06<cnwdup>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2491#a2491 Could anyone tell me why this outputs "pluginA: state of wrong type, pluginB: state of wrong type" in ghci? Is this approach right to realize dynamically loaded plugins which can access the other plugin's states?
16:05:36<dmwit>Alright, time to go in to work. yay! =)
16:06:25<Absolute0>:)
16:07:07<Absolute0>So are list comprehensions lazy when inputted to other functions?
16:07:47<Absolute0>ie: map (+) 0 [x | x < [0..99999999999]]
16:08:14<mapreduce>Absolute0: Yes.
16:08:16<Absolute0>ie: fold (+) 0 [x | x < [0..99999999999]]
16:08:28<burp>try it
16:08:31<Absolute0>mapreduce: from #java? :)
16:08:41<mapreduce>> foldl (+) 0 [1..]
16:08:47<lambdabot> mueval-core: Prelude.read: no parse
16:08:47<lambdabot> mueval: ExitFailure 1
16:08:54<mapreduce>> head [1..]
16:08:57<lambdabot> 1
16:09:24<EvilTerran>Absolute0, list comprehensions de-sugar to uses of map and filter, so are as lazy as those functions
16:09:52<EvilTerran>@undo [f x | f <- fs, x <- xs, p x]
16:09:52<lambdabot>concatMap (\ f -> concatMap (\ x -> if p x then [f x] else []) xs) fs
16:09:59<Absolute0>mapreduce: foldl (+) 0 [x | x <- [0..99999999999]]
16:10:00<byorgey>and those functions are pretty lazy. Just yesterday I asked map to take out the garbage and it said it 'might get around to it later'.
16:10:12<mapreduce>Absolute0: I am from many programming language channels, not just ##java.
16:10:17<EvilTerran>ok, concatMap and if/then/else. comes to the same thing.
16:10:28<Absolute0>rickyclarkson..
16:10:42<mapreduce>Yes?
16:13:08<Absolute0>how's scala going?
16:14:12<mapreduce>Not bad, but I'm not getting to use it as much as I was. I follow its development closely.
16:15:08<Absolute0>never got into it, haskell is way cooler :)
16:15:27<mapreduce>Agreed.
16:17:47<Absolute0>Is there any syntax to allow an infinite amount of arguments to a function without using lists?
16:18:18<Absolute0>ie: foo :: a1 -> a2 .. aN-1 -> aN
16:18:27<doserj>that's not infinite
16:18:30<pepepto>hola¡
16:18:35<Absolute0>i mean undefined
16:18:45<jeff_s_>unbounded?
16:18:49<Absolute0>or that :)
16:18:52<cnwdup>Absolute0, you can use the type system for that like printf does.
16:19:05<cnwdup>quicksilver, ping
16:19:10<Absolute0>ah ok
16:19:12<Absolute0>thanks
16:20:21<cob_jonas>what's wrong with lists?
16:20:39<cob_jonas>there's a reason why we've got an easy syntax for lists
16:20:55<jeff_s_>Text.Printf.printf "%c"
16:21:06<jeff_s_>> Text.Printf.printf "%c"
16:21:08<lambdabot> Add a type signature
16:21:22<Absolute0>cob_jonas: extra bandwidth
16:21:23<jeff_s_>er....
16:21:24<doserj>there is no easy pattern matching syntax for lists, though
16:21:28<cob_jonas>but printf sucks anyway, because it doesn't handle floating point formats properly
16:21:57<cob_jonas>bandwidth?
16:22:13<jeff_s_>@type Text.Printf.printf
16:22:16<lambdabot>forall r. (PrintfType r) => String -> r
16:22:31<Absolute0>'[' = 8 bytes!!!
16:22:33<Absolute0>:)
16:22:51<jeff_s_>> Text.Printf.printf "%c" "h"
16:22:53<lambdabot> Add a type signature
16:23:03<jeff_s_>oh
16:23:04<Peaker>Absolute0: I think just 4?
16:23:18<Absolute0>Peaker: does haskell use unicode?
16:23:26<Peaker>Absolute0: yeah, at least GHC does
16:23:29<cob_jonas>oh no
16:23:32<cob_jonas>I hate this question
16:23:44<Absolute0>isn't unicode 8 bytes?
16:23:59<Twey>ACTION twitches.
16:24:01<jeff_s_>unicode is like 5 different encoding standards or something like that
16:24:09<Absolute0>utf-8
16:24:19<Twey>Unicode is a mapping of code points to characters
16:24:24<Twey>Different encodings are different sizes
16:24:26<Peaker>Absolute0: Unicode is an abstract mapping of "code points" to linguistic symbols, and some rules about how to render/go over a sequence of code points
16:24:31<Twey>UTF-8 is variable-size
16:24:32<Peaker>Absolute0: a code point is a number within 32-bit range
16:24:46<Twey>For ASCII characters, it's eight *bits*, hence its name
16:24:56<Twey>For some other characters it can require more
16:24:59<Peaker>Absolute0: but it can be encoded in various ways, one of which is UTF8 which takes 8 *bits* per code-point, if it is simple ASCII. When it isn't, it uses more bytes
16:25:14<Twey>Peaker: :)
16:25:59<Absolute0>see cob_jonas precious bandwidth down the drain just like that, pftt@
16:26:07<Absolute0>=)
16:26:14<Twey>ACTION laughs.
16:26:17<Phyx->*twitches*
16:27:03<Absolute0>especially in this economy
16:27:35<Phyx->hmm... i need to extend my state :P
16:28:13<jeff_s_>I'm looking at the printf source, and I'm thinking that it's a library I don't ever want to use.
16:29:04<jeff_s_>http://oreilly.com/catalog/9780596101213/ btw
16:29:04<Phyx->lol
16:29:34<Phyx->now it's time for a game of... Will it typecheck
16:30:07<jeff_s_>lambdabot already convinced me that it won't
16:30:23<Phyx->lol, i'm talking about my own code :P
16:30:30<Phyx->i changed my type of my StateT
16:30:36<Phyx->so now i'm notifying everywhere
16:32:29<EvilTerran>Phyx-, are you familiar with the idea of newtype-wrapping monad transformer stacks?
16:33:18<Phyx->EvilTerran: i'm changing the get /put calls, which now return a different value
16:33:27<Phyx->not the type or my functions :P
16:33:37<cob_jonas>or you can try data with named elements and use bracket amend functions
16:33:50<EvilTerran>Phyx-, ah, i see
16:33:53<cob_jonas>then the type changes but your code text needn't
16:34:36<Phyx->cob_jonas: using records is one way to go, but i don't forsee another change needed
16:35:52<Phyx->though you never know, so it's not a bad idea...
16:36:00<EvilTerran>Phyx-, what i meant was something like "newtype MyMonad a = MyMonad { unMyMonad :: StateT (Foo, Bar) IO a }; getFoo :: MyMonad Foo; getFoo = MyMonad $ gets fst; putFoo :: Foo -> MyMonad (); putFoo foo = MyMonad . put" ...
16:37:06<EvilTerran>Phyx-, and then you could make it a StateT (Foo, Bar, Baz), and all you'd need to do to fix backwards compatibility would be to update the definitions of (get/put)(Foo/Bar)
16:37:39<Phyx->EvilTerran: i have something similiar, but i just use a Type synonym atm
16:38:15<Phyx->i ahve
16:38:17<Phyx->type ReadB a b c= State (Buchi (a,b),[c])
16:38:17<Phyx->type ENGINE a b c d= ReaderT (BuchiPair a b) (ReadB a b d) c
16:38:18<cob_jonas>EvilTerran: of course that only works if you derive Monad and define a run by hand
16:38:35<EvilTerran>cob_jonas, well, yeah, there's a little more boilerplate than i let on :P
16:41:14<cob_jonas>of course that's more useful when you're not just having a state but multiple trickier monad transformers inside
16:42:20<EvilTerran>cob_jonas, although even with just a State monad, the specialised get/set functions keep changes local if you change the state type
16:43:18<cob_jonas>but you can get that if you just define custom indexers and amenders for your tuple type, or let haskell syntax do that for you
16:43:55<Phyx->...
16:44:55<EvilTerran>???
16:57:18<Phyx->hrm.. sometimes i think i build too much infrastructure/framework before i actually start on the logic
17:06:57<xoclipse>in my cabal file i have build-depends: haxml, but when i try to configure it tells me "Setup.hs: At least the following dependencies are missing:
17:06:57<xoclipse>HaXml >=1.19.4", (HaXml is installed fine though)
17:07:40<koeien>cabal is case-sensitive
17:08:05<xoclipse>yeah i have it like this: Build-Depends: base, haskell98,
17:08:05<xoclipse> binary >= 0.5, bytestring >= 0.9.1.4,
17:08:05<xoclipse> HaXml >= 1.19.4
17:08:25<koeien>do you runghc Setup.hs configure ?
17:08:31<koeien>or cabal configure ?
17:08:37<koeien>in the first case, add --user if necessary
17:09:12<dcoutts>or just use cabal
17:09:25<dcoutts>there's really no need to mix use of 'cabal' with 'runghc Setup'
17:09:27<koeien>it's shorter anyway :)
17:09:36<xoclipse>runghc Setup.hs configure doesn't work
17:09:40<xoclipse>i was doing "runhaskell"
17:09:48<xoclipse>same thing w/ cabal configure
17:10:01<xoclipse>if i ghc --make *.hs my source files (that import haxml), it works fine
17:10:09<xoclipse>so i'm sure that HaXml is installed
17:10:14<dcoutts>xoclipse: what does ghc-pkg list HaXml say?
17:14:39<xoclipse>ghc-pkg dump | grep HaXml
17:14:49<xoclipse>import-dirs: /Users/chris/.cabal/lib/HaXml-1.13.3/ghc-6.10.1
17:14:49<xoclipse>library-dirs: /Users/chris/.cabal/lib/HaXml-1.13.3/ghc-6.10.1
17:14:49<xoclipse>hs-libraries: HSHaXml-1.13.3
17:14:49<xoclipse>haddock-interfaces: /Users/chris/.cabal/share/doc/HaXml-1.13.3/html/HaXml.haddock
17:14:49<xoclipse>haddock-html: /Users/chris/.cabal/share/doc/HaXml-1.13.3/html
17:15:01<xoclipse>i changed the cabal script to be HaXml, with no version
17:15:08<xoclipse>but it still fails
17:15:20<dcoutts>xoclipse: next time, it's simpler to use "ghc-pkg list HaXml"
17:15:25<xoclipse>oh okay :)
17:15:51<dcoutts>xoclipse: so you see why you got the error message now
17:16:05<xoclipse>1.13.3 < 1.19.4?
17:16:26<xoclipse>that ghc-pkg command is helpul, thanks!
17:18:16<amgarching>why is this illegal? instance (Num a) => Num (a, a) where, How would you do complex numbers with tuples?
17:18:41<mauke>I wouldn't use tuples
17:19:17<amgarching>isnt a tuple just another type constructor?
17:19:23<mauke>yes
17:19:46<Tigran>amgarching: But you're making an instance that is too specific
17:19:57<Tigran>amgarching: (a,a) as opposed to (a,b)
17:20:14<Tigran>By making your own data Complex a = Complex a a
17:20:21<Tigran>You're only working with a single type variable
17:20:39<Tigran>Which means you can do the perfectly valid `Num a => Num (Complex a)'
17:25:32<shag>how do i get RTS options compiled into my program? i.e. when using the -N option for controlling the number of threads, i always want my program to use 4 threads
17:25:49<shag>without needing to specify +RTS -N4 all the time
17:26:28<monochrom>I don't think it can.
17:32:04<cob_jonas>sure you can, with http://www.haskell.org/ghc/docs/latest/html/users_guide/ffi-ghc.html#ffi-library
17:32:29<cob_jonas>or just make a simple wrapper program that execs the other program with +RTS -N as arguments
17:33:59<cob_jonas>or you can set the GHCRTS environment variable but that would affect all haskell programs
17:34:18<koeien>including ghc itself...
17:38:41<deech_>Hi all, How do I use an operator like (+) or (-) if it is part of a module that I imported qualified?
17:38:49<koeien>(Prelude.+)
17:39:12<Beelsebob>surprising
17:39:20<Beelsebob>I would have expected it to be Prelude.(+)
17:39:32<mauke>I hate hpaste in a good way
17:39:33<monochrom>IIRC a M.+ b works.
17:39:50<deech_>That worked thanks!
17:40:11<Beelsebob>hmm, I guess in that context (M.+) makes more sense
17:40:19<Beelsebob>parenthesise anything infix and it becomes prefix
17:41:01<mib_e7tcavos>hey can i ask what is wrong with this code
17:41:10<mib_e7tcavos>topTenFilmsa :: [Film] -> [FilmB]
17:41:12<Absolute0>Is it possible to get a range in descending order without calling reverse?
17:41:23<mib_e7tcavos>topTenFilmsa films = [Film title director year sum length fans]
17:41:25<mauke>Absolute0: [a, a-1 .. b]
17:41:50<mib_e7tcavos>can i use sum and length with the statement
17:41:55<Absolute0>thanks
17:42:27<mauke>mib_e7tcavos: you're missing a few parentheses
17:42:31<cnwdup>@ty sum
17:42:33<lambdabot>forall a. (Num a) => [a] -> a
17:42:36<cnwdup>@ty length
17:42:37<lambdabot>forall a. [a] -> Int
17:42:54<mauke>and some other things
17:43:02<mib_e7tcavos>hmm
17:43:07<cnwdup>mib_e7tcavos, you can use length on every list. But you can use sum only on lists which elements are an instances of the Num class.
17:43:21<cnwdup>*instance
17:43:25<monochrom>Haskell is not English.
17:44:34<mib_e7tcavos>but surely length returns a [int]
17:44:44<Peaker>mib_e7tcavos: why?
17:44:44<monochrom>You can't just write "automatic banking machine user" and expect it to be parsible.
17:44:47<mib_e7tcavos>i just used sum to unlist it
17:44:53<cnwdup>mib_e7tcavos, it returns Int not [Int].
17:44:59<mib_e7tcavos>ahhh
17:45:06<monochrom>Haskell is not German either. You can't just write "automaticbankingmachineuser" and expect it to be parsible.
17:45:24<skorpan>is haskell swedish?
17:45:29<monochrom>I don't know.
17:45:48<skorpan>@faq can haskell parse "automatic banking machine user"?
17:45:48<jeff_s_>Haskell is Esperanto.
17:45:48<lambdabot>The answer is: Yes! Haskell can do that.
17:45:51<mib_e7tcavos>still saying fans paramerters arnt set
17:46:02<mauke>mib_e7tcavos: no, it's not saying that
17:46:09<cnwdup>mib_e7tcavos, then provide the actual code.
17:46:40<mib_e7tcavos>sorry its saying:
17:46:41<Philonous>monochrom: Try capitalising it. Then it might work.
17:46:50<mib_e7tcavos>Undefined variable "fans"
17:46:58<monochrom>Haha
17:47:20<cnwdup>mib_e7tcavos, then you're using the variable fans which is not defined. (; Post the source code in a pastebin, then one can tell you what's wrong.
17:47:21<monochrom>"Undefined variable" is pretty clear.
17:47:52<mib_e7tcavos>ok
17:48:17<monochrom>I don't understand why people don't understand error messages.
17:50:12<tetha>people are lazy and dont want to read
17:50:13<Philonous>No instance for (Read Error)
17:50:19<monochrom>If it says "expected type Char, inferred type Int", then it means exactly that, you have something should be an Int and a Char, you have a self-contradiction. What more do you expect?
17:50:24<cob_jonas>Philonous++ lol
17:50:38<monochrom>Do you expect the computer to tell you how to fix it?
17:50:47<koeien>monochrom: sometimes, yes, but some error messages are obscure
17:50:52<mib_e7tcavos>http://pastebin.ca/1435211
17:50:57<tetha>I would love to invent a system that tells you how to fix bugs
17:51:08<tetha>I guess then I can just stop studying :)
17:51:08<mib_e7tcavos>trying to return the list of fans as a amount
17:51:13<monochrom>If so, you may as well die now. If the computer can fix it, why do we need you to write programs? What's your point of existence?
17:51:14<cob_jonas>< buubot> cob_jonas: The paste 1435211 has been copied to http://erxz.com/pb/17824
17:51:15<cnwdup>mib_e7tcavos, where are title director year length and fans defined?
17:51:16<c_wraith>Hmm. I'm getting conflicting instances between convertible-1.0.1 and time-1.1.3 :(
17:52:09<cnwdup>mib_e7tcavos, there are several things wrong with your code as far as I can see.
17:52:24<cnwdup>mib_e7tcavos, you cant to convert a list of Film to a list of FilmB, right?
17:52:37<mauke>nice typo
17:52:50<mib_e7tcavos>ok
17:52:50<tetha>koeien: well, yes, and there are error messages which are misleading due to stacking bugs and arcane errors, but I'd say they are no daily error messages
17:53:51<cnwdup>mib_e7tcavos, if you want to convert a list of Film to a list of FilmB you have to convert every element of the first list to FilmB. map is the function to use for that.
17:54:08<mib_e7tcavos>ok
17:54:09<cnwdup>mib_e7tcavos, map takes a function and a list and applies the function to every element of the list yielding a new list.
17:54:18<mib_e7tcavos>kl
17:54:26<cnwdup>mib_e7tcavos, you can write your function topTenFilmsa using topTenFilmsa films = map toFilmB films.
17:55:03<cnwdup>mib_e7tcavos, toFilmB will look pretty miuch like topTenFilma but title, directory, etc. are used wrong. They are not defined.
17:55:41<c_wraith>Ok... problem solved... explicit dependency on an older version of time. >_>
17:55:45<cnwdup>mib_e7tcavos, However, you can define them as you want if you pattern match Film correctly: toFilmB :: Film -> FilmB, toFilmB (Film title directory year fans) = FilmB title directory year (length fans)
17:56:48<mib_e7tcavos>ok i see what u mean
17:56:58<cnwdup>mib_e7tcavos, another issue with your code: length fans has to be in parantheses since otherwise length and fans would be applied to the data constructor Film. But you want to result of (length fans) to be applied.
18:03:55<Baughn>http://www.pps.jussieu.fr/~jch/software/XinC.html <-- Have a read, fellows
18:08:56<ehird>:t (<*>)
18:08:57<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
18:08:58<ehird>:t (<$>)
18:08:59<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
18:09:16<ehird>hmm
18:09:37<ehird><$> is used to do things like (pureFunction <$> getLine), isn't it?
18:09:50<ehird>what about (unpureFunction <??> getLine)?
18:09:58<Twey>Is IO a functor?
18:10:11<ehird>(and (unpureFunction <??> getLine <??> aPureThing <??> anotherUnpurething) etc)
18:10:12<c_wraith>ehird: is <*> what you want?
18:10:13<Twey>ehird: >> or >>=
18:10:16<cnwdup>ehird, what's wrong with <*> or ap for that?
18:10:33<ehird>Twey: in (f <foo> x) style, I mean
18:10:40<deech_>Hi all,
18:10:41<Beelsebob>ehird: <*>
18:10:42<ehird>cnwdup: (unpureFunction <*> getLine) :: IO (IO x)
18:10:48<ehird>err, wait
18:10:51<ehird>no
18:11:01<ehird>Beelsebob: how, (a -> IO b) != IO (a -> b)
18:11:04<ehird>19:08 lambdabot: forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
18:11:23<Beelsebob>ehird: well, IO (a -> b) is one form of impure function
18:11:24<Twey>:t print <*> getLine
18:11:26<lambdabot> Couldn't match expected type `a -> b' against inferred type `IO ()'
18:11:26<lambdabot> Probable cause: `print' is applied to too many arguments
18:11:26<lambdabot> In the first argument of `(<*>)', namely `print'
18:11:34<Beelsebob>if you happen to have one of type a -> IO b then you want =<<
18:11:40<ehird>ok
18:11:43<deech_>I am trying to import a CSV file using Text.CSV.ByteString, but it fails if any of the fields have a comma, even if the string containing the comma is enclosed in quotes.
18:11:45<Twey>:t print <$> getLine
18:11:46<Beelsebob>:t print =<< getLine
18:11:46<lambdabot>IO (IO ())
18:11:47<ehird>what about multiple arguments?
18:11:47<lambdabot>IO ()
18:11:55<Twey>So that would be join
18:12:01<ehird>say, (a -> b -> c -> IO d) and a and b are impure, but b is pure
18:12:05<Absolute0>How do I extract the a from Just a?
18:12:22<tromp>easiest by peatternmatch
18:12:24<Twey>join (print <$> getLine) ≡ print =<< getLine
18:12:27<monochrom>Use the do-notation for more arguments.
18:12:34<ehird>monochrom: bleargh
18:12:52<Twey>Absolute0: Pattern match, or fromJust if you're sure it's a Just, or maybe/fromMaybe otherwise
18:12:55<tromp>:t fromJust
18:12:56<lambdabot>forall a. Maybe a -> a
18:13:00<tromp>or that way
18:13:00<Beelsebob>if you don't want to use do notation, use >>= and lambdas ehird
18:13:06<Beelsebob>or...
18:13:13<Beelsebob>stop programming with side effecting stuff ;)
18:13:25<Absolute0>ah, I was trying to use guards direct matching seems like the way to do it..
18:13:29<Twey>Note that fromJust is unsafe if it could possibly be a Nothing — it will throw an error.
18:13:55<FalconNL>Does anyone know if there's a tutorial on how to work with the AST generated by Language.Haskell.Exts, e.g. getting a list of all top-level functions?
18:13:58<Absolute0>|a == Nothing | a == Just a which is obviously wrong
18:14:06<Twey>Very
18:14:09<Absolute0>:)
18:14:28<ehird>Beelsebob: welp
18:14:31<ehird>main = do [input, output] <- getArgs; image <- loadPngFile input; processImage image; savePngFile output image
18:14:36<ehird>it's just that that's pretty ugly.
18:14:47<monochrom>If you have N arguments you are asking for 2^N combinators.
18:14:57<Beelsebob>ehird: is the image a resource that is read only once?
18:15:13<monochrom>do-notation is pretty pretty.
18:15:16<ehird>Beelsebob: Clarification?
18:15:28<Beelsebob>ehird: does your program ever load the same image file more than once?
18:15:41<ehird>Beelsebob: No.
18:16:05<Beelsebob>ehird: then you can treat loadPngFile as a pure function
18:16:10<Beelsebob>by wrapping it in unsafePerformIO
18:16:13<monochrom>...
18:16:14<ehird>Beelsebob: ...
18:16:15<ray>!!!
18:16:23<Twey>ACTION twitches.
18:16:26<ehird>(1) No. (2) NO GOD NO. (3) It's a GD function.
18:16:28<Zao>ACTION kicks Beelsebob in the monads.
18:16:38<ray>what's wrong about image <- loadPngFile
18:16:43<Beelsebob>can anyone give me an example where it behaves in a non pure way?
18:16:59<ray>here's what's wrong about it: nothing
18:17:02<Twey>Beelsebob: It does IO?
18:17:09<Beelsebob>Twey: so does unamb
18:17:14<Beelsebob>so do many pure functions
18:17:21<Beelsebob>+ for example
18:17:27<Twey>And what do they do if the IO fails?
18:17:33<ehird>... + does IO?
18:17:35<Beelsebob>return a Maybe
18:17:37<ehird>LOL WAT
18:17:41<Beelsebob>ehird: sure - it calls into the haskell runtime
18:17:45<Zao>Blowing up far from the call site is something you usually need dynamically typed languages for.
18:17:46<ehird>Oh please.
18:17:50<Beelsebob>a great big impreative lump of code
18:17:57<ehird>Implementation details are NOT the same as API details.
18:17:59<Twey>Um.
18:18:05<ehird>You're silly.
18:18:14<Beelsebob>can you give an example where it behaves in an impure way?
18:18:19<Twey>Every function is impure. Let's go back to Clojure!
18:18:26<Beelsebob>when will it return different values for different calls?
18:18:32<mauke>Beelsebob: when the file changes
18:18:35<Beelsebob>remembering that you guarenteed me that you only call it once
18:18:38<Beelsebob>mauke: he only calls it once
18:18:44<mauke>Beelsebob: irrelevant
18:18:46<ehird>This is ridiculous. Utterly ridiculous.
18:18:52<mauke>Beelsebob: we don't have strict evaluation
18:18:56<Beelsebob>mauke: so?
18:19:09<mauke>so the compiler can evaluate stuff as often as it wants
18:19:09<ray>even if you could use unsafePerformIO safely in theory, why would you do it if you can avoid it
18:19:15<mauke>particularly in the presence of inlining
18:19:30<Beelsebob>mauke: which is why you follow the unsafePerformIO rules and mark it no inline ;)
18:19:34<Baughn>Twey: If unamb fails, in particular, it retries the next time you invoke it
18:20:01<Baughn>Twey: For unsafePerformIO in general, it stores the current state of the IO when it catches an exception, and restarts from there
18:20:34<ray>ehird: i don't think that's ugly, incidentally
18:20:49<Beelsebob>if you only load the file once, you can treat it like a resource - just like your program's code... It is to all intents and purposes a pure value
18:21:00<ray>where's the ugly part?
18:21:27<ehird>does anyone know an alternative to the gd package that doesn't stick everything in IO?
18:22:43<deech_>Sorry, my last message was interrupted by a phone call, but I have a CSV file with some text quoted. There are commas within the quotes, but Text.CSV.ByteString parses them as a column break. Is there any way to tell Text.CSV to ignore commas within quotes?
18:23:06<Phyx->20:17:22 * Twey twitches. <-- been doing that alot today, maybe you should see a doctor :P
18:23:30<Twey>Haha :-P
18:23:47<Baughn>deech_: The CSV standard has no "quotes". Or variable-sized fields, for that matter. :P
18:23:55<Twey>Baughn: Reading a file is quite clearly IO, IMO.
18:23:56<Baughn>deech_: I imagine you could propose a patch to do that
18:23:58<Beelsebob>ehird: in the mean time, what I'd really do with that program is main = readWrite =<< getArgs where readWrite [in,out] = wrietFile out . processImage =<< readFile in
18:24:10<Baughn>Twey: The question isn't whether it's IO, it's whether it's semantically pure
18:24:11<Twey>CSV is a standard?
18:24:13<Beelsebob>with a pure processImage function
18:24:22<Twey>But it reads a file
18:24:27<Twey>Of course it isn't semantically pure
18:24:30<Baughn>Twey: Which it is, if only done once. Okay, I admit that's questionable, but there you go
18:24:30<deech_>Baughn : I didn't know csv was a standard either.
18:24:34<Baughn>Twey: "IO" is a misnomer
18:24:41<Twey>It's not just an implementation detail — the goal of the function is to perform IO
18:24:56<cob_jonas>wow, em dash
18:25:07<cob_jonas>with spaces
18:25:08<ehird>Beelsebob: I cannot have a pure processImage. All of the gd functions are in IO.
18:25:10<Baughn>Twey: The IO monad doesn't exist to do IO, it exists to handle impure functions that do IO
18:25:21<Twey>cob_jonas: Unspaced em dashes are the devil
18:25:30<Baughn>deech_: Sort of
18:25:33<eivuokko>Baughn, it's also short to type.
18:25:35<Beelsebob>ehird: fix the library then - image processing is entirely pure
18:25:54<Baughn>deech_: Anyway, there are too many possible ways to quote csv data. You could propose a patch adding support for one, but of course only if it's optional.
18:26:05<Twey>Baughn: I would say that was pretty much the definition of impure
18:26:09<cob_jonas>Twey: IMO em dashes are devil, one should use en dashes, but that's because I've grown up in Hungary where en dashes are standard (and in some fonts they look as wide as em dashes)
18:26:13<ehird>Beelsebob: I cannot.
18:26:18<Beelsebob>why not?
18:26:25<Twey>cob_jonas: En dashes have a separate meaning in English
18:26:33<Twey>Several separate meanings, actually
18:26:46<Baughn>Twey: And I would disagree. IO can be pure, if it's idempotent and gives the same thing every time.
18:27:19<Beelsebob>Twey: is a forgien function call to int jam (void) { return 5; } pure?
18:28:08<Twey>Beelsebob: Yes — that function is intrinsically pure
18:28:13<Beelsebob>but it's in IO
18:28:18<Beelsebob>so it can't be, can it?
18:28:29<Twey>Yes — *that's* a case of pure semantics
18:28:38<Twey>And what I would use unsafePerformIO for
18:28:45<Beelsebob>right then, so your argument that any IO function can't be pure is invalid
18:29:03<cob_jonas>do you mean (return 5 :: IO Int)
18:29:07<Philonous>Beelsebob: Bat readFile is neither side effect free nor even referentially transparent
18:29:10<Beelsebob>similarly callMeOnlyOnceLoadResource :: FilePath -> Something can also be pure
18:29:20<Beelsebob>as long as you meet the precondition
18:29:23<Beelsebob>that you call it only once
18:29:37<cob_jonas>lol
18:29:45<Beelsebob>otherwise, no haskell program is pure - after all, the haskell program is a resource that's loaded from disk
18:30:10<Beelsebob>we just have to guarentee that the OS only loads the program once
18:30:36<xoclipse>hey guys, I made a simple AIM/OSCAR client in haskell, it was a cool little project, if anyone wants to check it out: http://chrismoos.com/2009/05/26/haskell-aim-client-a-cool-proof-of-concept/
18:30:44<Philonous>Beelsebob: Of course the program is impure, that's why main is in IO
18:30:44<Baughn>Beelsebob: You could use a global variable
18:30:58<Baughn>Beelsebob: Start your onlyOnce function with "putMVar global ()"
18:31:04<Beelsebob>Baughn: that would certainly guarentee the only once bit, yes
18:31:08<Beelsebob>sounds like an execellent plan to me
18:32:37<Peaker>xoclipse: haim is a Hebrew name of a guy
18:32:58<Cale>xoclipse: cool
18:33:11<Peaker>xoclipse: why do you use () around IO args? IO (String) instead of IO String?
18:33:54<Peaker>xoclipse: did you write your own Show instances because you don't like the derived ones?
18:33:57<xoclipse>no particular reason
18:34:14<xoclipse>peaker: i just wanted a little more customization
18:34:31<xoclipse>(for the show instances)
18:34:37<Peaker>xoclipse: why did you wrap a Get that you wrote with a runGet -- instead of just exporting Get values?
18:35:04<xoclipse>which file peaker?
18:35:10<Peaker>xoclipse: tlv.hs
18:35:10<xoclipse>you've got a lot of questions :P
18:35:17<xoclipse>btw i've only been using haskell for ~ month
18:35:27<jeff_s_>ACTION senses someone overusing the Socratic method.
18:35:41<Peaker>xoclipse: oh, awesome work ;)
18:35:43<xoclipse>i used runget because i didn't want the function that cals tlv_get to have to run it
18:36:08<xoclipse>i use runPut and runGet a lot
18:36:13<xoclipse>great functions btw, bytestring is awesome
18:36:18<Peaker>xoclipse: the function that calls tlv_get would have to unpack the tuple and do with the continuation byte-string, which is what Get makes more convenient (and possibly more efficient too)
18:36:58<xoclipse>so tlv_get :: BS.ByteString -> Get (TLV, BS.ByteString) is better?
18:37:15<Peaker>xoclipse: for example, if you look at tlv_extract_lblock -- it calls tlv_get and then uses fst/snd on its result, instead of being able to just use: result <- tlv_get ; use rest of input stream here
18:37:24<Peaker>xoclipse: tlv_get :: Get TLV
18:37:42<Peaker>xoclipse: (Get a) already encapsulates the notion of having a bytestring input and extra bytestring output
18:37:51<xoclipse>ohhh okay
18:37:56<xoclipse>yeah that's my misunderstand of it
18:38:03<xoclipse>great that makes my life easier :)
18:38:06<Peaker>xoclipse: :-)
18:38:35<xoclipse>you try out the client?
18:38:37<Peaker>xoclipse: also, if you have: let result = tlv_get stuff and then you use (fst result) and (snd result) its nicer to use: let (result, somethingElse) = tlv_get stuff ...
18:38:44<Peaker>xoclipse: I don't have an AIM account..
18:38:47<cob_jonas>so type Get = State BS.ByteString
18:38:52<xoclipse>ah okay
18:38:59<xoclipse>peaker: good points
18:39:07<xoclipse>its a learning process :)
18:39:08<xoclipse>that's why i write thigns like this
18:39:13<xoclipse>each time it gets better
18:39:16<Peaker>xoclipse: sure, its the best way to learn, good job :)
18:39:40<Peaker>xoclipse: its already looking decent, and a lot more than decent if you consider that its just 1 month
18:39:54<xoclipse>:)
18:39:58<Twey>Beelsebob: I didn't have an argument that any IO function (one returning and IO a) was impure
18:40:03<Twey>an**
18:40:12<Peaker>cob_jonas: I guess it could be implemented that way, but its not a good semantic model, because you can only move forward/backward and not arbitrarily change the string
18:40:25<xoclipse>i love the recusriveness of the tlv_extract* functions
18:40:27<xoclipse>i had fun with that
18:40:37<xoclipse>incidentally i really like the OSCAR protocol (SNAC, TLV, etc,.)
18:41:31<Peaker>xoclipse: a nice rule of thumb to know is that prefix-calls are always higher-precedence than infix, so you never need () around them. e.g: if (BS.length stuff) == 0 then ([], BS.empty) else do -- can be: if BS.length stuff == 0 then ...
18:41:41<Peaker>@hoogle ByteString -> Bool
18:41:42<lambdabot>Data.ByteString null :: ByteString -> Bool
18:41:42<lambdabot>Data.ByteString.Char8 null :: ByteString -> Bool
18:41:42<lambdabot>Data.ByteString.Lazy null :: ByteString -> Bool
18:41:57<Peaker>xoclipse: BS.null is basically a comparison of length to 0, except it can be more lazy
18:42:23<xoclipse>okay cool
18:43:12<xoclipse>right the parentheses can go
18:43:19<xoclipse>that's my C/C++/Java background :p
18:43:22<xoclipse>stupid parentheses
18:43:46<Peaker>xoclipse: oh cool, I needed an HaXml example, and now I have one :)
18:43:55<cnwdup>@pl (\f -> f `fmap` get)
18:43:56<lambdabot>(`fmap` get)
18:43:58<xoclipse>yeah, i had fun with that
18:44:03<xoclipse>took me a while to grasp HaXml
18:44:17<xoclipse>i probably stared at the screen for like 15 minutes and just thought
18:44:18<xoclipse>haha
18:44:24<Peaker>xoclipse: I think if you use deriving (Show, Read, ..) you get a show that's just as good, and no need for the boilerplate
18:44:34<xoclipse>great, good to know
18:44:47<cob_jonas>I just decided the "xml" library looks better
18:45:08<cnwdup>@pl (\f -> get >>= put . f)
18:45:08<lambdabot>(get >>=) . (put .)
18:45:22<Peaker>xoclipse: a pattern-match of (host:(port:(cookie:xs))) needs no () because : is already right-associative host:port:cookie:xs
18:45:32<cnwdup>@pl (\f -> put . f =<< get)
18:45:32<lambdabot>(get >>=) . (put .)
18:45:37<xoclipse>:)
18:46:35<Peaker>xoclipse: its nicer to have f . g . h . i $ x than: f $ g $ h $ i $ x, too
18:47:09<Peaker>let sig = encode $ BS.unpack $ bytestringDigest $ hmacSha256 (BS.pack $ sessionKey info) (BS.pack hashData) --> let sig = encode . BS.unpack . bytestringDigest . hmacSha256 (BS.pack $ sessionKey info) . BS.pack $ hashData
18:47:34<cob_jonas>I still think usually just parenthesis are better than $
18:47:56<Peaker>does ByteString.Char8 do utf8 or just (`mod`256)?
18:48:13<Peaker>cob_jonas: its really nice to be able to cut & paste any subset of the "pipe-line" out to its own function
18:48:15<jeff_s_>not utf8
18:48:31<Peaker>how do you convert String -> ByteString with some unicode encoding?
18:48:50<Zao>Peaker: Data.Text?
18:48:53<cob_jonas>Peaker: the encoding module
18:49:06<xoclipse>okay i'll use the f .g etc,.
18:49:41<Peaker>xoclipse: also, underscore convention isn't very common - the entire library/etc are all in camelCase
18:50:09<cob_jonas>yeah, but undescores are actually more readable
18:50:16<cob_jonas>ACTION ducks
18:50:52<xoclipse>okay
18:51:48<xoclipse>okay, i'm out for now
18:51:52<xoclipse>thanks for the tips, Peaker
18:52:20<Peaker>xoclipse: sure thing
18:52:44<Peaker>cob_jonas: a mishmash is less readable than either convention uniform though, and names less guessable
18:53:17<Baughn>So dromedarCase it is
18:53:21<Baughn>And CamelCase for types
18:53:47<cob_jonas>yeah
18:53:56<cob_jonas>but that's only if you give verbose names like the libraries
18:54:34<cob_jonas>if you use abbrevs like mk_wrd then camelCasing doesn't make it any more mish-mash or predictability
18:54:41<cob_jonas>it's two conventions either way
18:56:13<burp>@pl f x y z = x^2+y^3+z^4
18:56:13<lambdabot>f = flip flip (^ 4) . (((.) . (+)) .) . (. (^ 3)) . (+) . (^ 2)
18:58:08<cob_jonas>> let { f x y z = x^2+y^3+z^4 } in f x y z
18:58:10<lambdabot> x * x + y * y * y + z * z * (z * z)
19:03:10<ehird>19:54 cob_jonas: if you use abbrevs like mk_wrd then camelCasing doesn't make it any more mish-mash or predictability
19:03:11<ehird>19:54 cob_jonas: it's two conventions either way
19:03:13<ehird>so don't do that
19:05:18<zong_sharo>does pattern matching strict or lazy by default? (eg, w/o ! or ~)
19:05:54<pumpkin>> let f (x, y) = 5 in f undefined
19:05:56<lambdabot> * Exception: Prelude.undefined
19:05:59<pumpkin>:)
19:06:09<pumpkin>> let f ~(x, y) = 5 in f undefined
19:06:10<lambdabot> 5
19:07:02<mmorrow>, let x = undefined in 20
19:07:05<lunabot> 20
19:07:11<mmorrow>, let (x,y) = undefined in 20
19:07:13<lunabot> 20
19:08:01<mmorrow>let matches are lazy and case matches are strict (patterns in the params of a function == case) (unless you use ~ like pumpkin)
19:08:29<Peaker>mmorrow: is there a difference between let ~(x,y) = and let (x,y) = ?
19:08:42<mmorrow>hmm
19:08:42<Cale>zong_sharo: In function bindings, pattern matching forces evaluation when the function is applied. In pattern bindings, it's like there's an implicit ~ at the front of the pattern. The pattern is only matched if you use one of the variables it binds.
19:09:11<Beelsebob>Peaker: yes
19:09:18<Cale>Peaker: no
19:09:31<pumpkin>Peaker: maybe (given the previous two answers)
19:09:35<Peaker>heh
19:09:37<Beelsebob>the first one will start evaluating the right hand side before the (_|_, _|_) is produced
19:10:10<cob_jonas>but note that
19:10:13<Beelsebob>> let f ~(x,y) = 5 in f undefined
19:10:15<lambdabot> 5
19:10:18<Beelsebob>> let f (x,y) = 5 in f undefined
19:10:19<lambdabot> * Exception: Prelude.undefined
19:10:22<cob_jonas>> let { f (x, y) = (); } in seq (f undefined) ()
19:10:23<lambdabot> * Exception: Prelude.undefined
19:10:24<Beelsebob>see... there's a difference
19:10:26<cob_jonas>> let { f (x, y) _ = (); } in seq (f undefined) ()
19:10:28<lambdabot> ()
19:10:33<Peaker>> let (x,y) = undefined in 5
19:10:35<lambdabot> 5
19:10:38<Peaker>> let ~(x,y) = undefined in 5
19:10:39<Cale>'A pattern binding binds variables to values. A simple pattern binding has form p = e. The pattern p is matched "lazily" as an irrefutable pattern, as if there were an implicit ~ in front of it.'
19:10:39<lambdabot> 5
19:10:42<Peaker>this behavior is weird
19:10:44<zong_sharo>Cale: thx
19:10:52<Cale>(From the Report)
19:10:58<cob_jonas>Peaker: it is, but it's right
19:10:59<Beelsebob>oh hang on, I read your pattern wrong
19:11:05<mmorrow>Peaker: the let match is never attempted if it isn't needed
19:11:32<Cale>However, ! has the power to turn let into case :)
19:11:40<Cale>> let !(x,y) = undefined in 5
19:11:43<lambdabot> * Exception: Prelude.undefined
19:11:43<Peaker>I see -- so argument pattern matches of functions defined by let are not irrefutable
19:11:47<mmorrow>bang!
19:12:04<Peaker>hmm.. I think let ~(x,y) ... should be a syntax error if its no different to let (x,y) = ...
19:12:17<cob_jonas>Peaker: why? that wouldn't be really consistent
19:12:31<Cale>Of course you should be able to nest ~'s
19:12:39<Peaker>cob_jonas: its already inconsistent -- let has different semantics, why should it have the same syntax?
19:12:44<Cale>They're idempotent, but it doesn't hurt to allow it.
19:13:36<Cale>Peaker: It's unnatural to have only one place in a pattern where ~ isn't allowed and only in the case of let
19:14:05<Cale>Note that things like let (~(x:xs),ys) = ... can still be useful
19:14:09<cob_jonas>Cale: well, let woulnd't be the only case
19:14:31<cob_jonas>top-level bindings and postfix where and do-let statements has that too
19:14:38<Cale>Well, sure.
19:14:51<cob_jonas>but I think there's no point banning ~ there
19:14:56<Cale>I suppose I mean "only pattern bindings"
19:16:06<Cale>> let x + 1 = 0 in 5 + 1
19:16:08<lambdabot> 0
19:16:12<Cale>> let (x + 1) = 0 in 5 + 1
19:16:14<lambdabot> 6
19:16:19<Peaker>Cale: it can also be disallowed to use ! in case !foo ..
19:16:29<Cale>> let (x + 1) = 0 in x
19:16:31<lambdabot> * Exception: <interactive>:1:145-155: Irrefutable pattern failed for patter...
19:16:38<Cale>> let (x + 1) = 5 in x
19:16:40<lambdabot> 4
19:16:56<Lemmih>ACTION grins.
19:16:57<Cale>> let x + 1 = 5 in x
19:16:59<lambdabot> x
19:17:04<Cale>:)
19:17:14<Cale>lol, simplereflect
19:17:17<cob_jonas>Peaker: oh no, ! is completely different I think
19:17:29<Peaker>Cale: I see, I think my problem is that let is irrefutable by default on the outside, and not irrefutable anywhere else, that's weird
19:17:45<Peaker>why isn't let strict like case? add ~ for irrefutable ones?
19:18:13<Cale>Well, usually you don't want all your let-bound things evaluating before they're needed.
19:18:32<arcatan>i want to use hGetBuf, but how can I create a buffer where it would write?
19:18:36<Cale>(and I'm including the top-level and where clauses, etc. in that)
19:18:50<hatds>lazy lets are useful, if you made it strict I'd demand a lazy replacement :)
19:18:52<Cale>let is all about putting things on the heap, not evaluation.
19:18:55<cob_jonas>Cale: that's not _all_ your let bound things, only the rarer case when you let bind to a constructor pattern (or numeric etc)
19:19:06<cob_jonas>still I think the current haskell semantics is great
19:19:13<Peaker>Cale: yeah, I see, I think the "right" thing is to just not allow lets to pattern-match, but that would be a little inconvenient given current syntax
19:19:21<cob_jonas>it's easy to remember and is chosen right
19:19:24<Cale>cob_jonas: Well, sure, function bindings are already in WHNF :)
19:19:39<cob_jonas>Cale: also plain bindings to a variable
19:19:42<Cale>Peaker: It's handy, and it does what you want. :)
19:20:02<Peaker>it behaves weird, though
19:20:18<Cale>Peaker: It just takes a little thinking to realise that this strange-seeming behaviour really is what you want most of the time :)
19:21:34<Baughn>What was the difference between HNF and WHNF again, exactly?
19:21:42<Cale>> let fibs@(x:fibs') = 0 : 1 : zipWith (+) fibs fibs' in fibs
19:21:44<lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946...
19:21:58<Cale>Baughn: I seem to recall something about evaluation under lambdas?
19:22:49<Cale>right.
19:23:02<Cale>\x -> ((\y -> y+x) 2)
19:23:08<Cale>is in WHNF, but not HNF.
19:23:12<Peaker>Baughn: http://encyclopedia2.thefreedictionary.com/Weak+Head+Normal+Form
19:23:18<pumpkin>how does Clean's uniqueness typing deal with forking and concurrency?
19:23:39<Cale>So the difference is that WHNF doesn't evaluate underneath a lambda
19:25:35<Peaker>It could probably do the reduction inside inner lambda's, I don't see why it would have a rename problem - it doesn't actually need to use string names..
19:25:39<Baughn>, tipe `fmap` getClosureData 42
19:25:41<lunabot> luna: Not in scope: `tipe'
19:26:05<Phyx->:type getClosureData
19:26:10<Phyx->@type getClosureData
19:26:11<lambdabot>Not in scope: `getClosureData'
19:26:16<Cale>Peaker: hm?
19:26:25<Baughn>Peaker: Okay, so HNF is a subset of WHNF
19:26:26<Baughn>That makes sense
19:26:27<Cale>Peaker: HNF reduces inside lambdas, WHNF doesn't
19:27:44<Baughn>ACTION continues mutilating haskell's semantics
19:27:51<pumpkin>Baughn: did you figure out if you could link to that table?
19:28:09<Baughn>pumpkin: Not yet, had an exam today. I'm just starting on that now.
19:28:59<pumpkin>Baughn: do you see what I mean by the U symbol though?
19:29:12<Baughn>pumpkin: Yes, but it's mistaken
19:29:28<Baughn>Each RTS .a defines /multiple/ closure_flags symbols
19:29:36<Baughn>One D, the others U
19:29:50<pumpkin>hmm
19:29:55<pumpkin>I didn't see that in mine
19:29:57<hackagebot>hack-middleware-gzip 0.0.0
19:30:27<Baughn>pumpkin: for i in *a; do echo $i; nm $i |grep closure_flags; done
19:30:32<Cale>Odd, despite the language spec being called "The Concurrent Clean Language Report", I'm having trouble finding any actual mention of concurrency in it at all.
19:30:34<Baughn>In /usr/local/lib/ghc*/
19:30:59<Cale>Is it just the report itself which is concurrent?
19:32:40<pumpkin>Baughn: oh I see
19:33:41<Baughn>pumpkin: So I'll get this working now, but the overhead from actually /linking/ that is so enormous, it'll have to wait for 6.12
19:33:45<Baughn>And dynamic linking
19:33:55<pumpkin>why?
19:33:58<Cale>Oh, version 1.3.1 had process annotations which look like they're related to parallelism or concurrency, but they were apparently removed in 2.0
19:34:02<Baughn>22MB hello,world
19:34:24<Cale>That's somewhat embarrassing if the most recent standard for Concurrent Clean doesn't support concurrency though.
19:34:46<pumpkin>lol
19:34:49<pumpkin>yeah
19:34:56<pumpkin>how would uniqueness typing deal with that though?
19:34:59<pumpkin>was it just too complicated?
19:35:12<Peaker>Cale: was talking about what http://encyclopedia2.thefreedictionary.com/Weak+Head+Normal+Form said
19:35:56<deech_>Hi all, is there a Haskell library that will convert an HTML text with diacritics into a Haskell String?
19:36:30<Cale>pumpkin: hmm, it doesn't say anything about the interation of parallelism with I/O
19:37:31<Cale>pumpkin: Oh, hmm, it appears that I'm looking in the wrong place for stuff about concurrency. There's supposed to be a library...
19:39:42<andouille>I saw that yesterday: http://en.wikibooks.org/wiki/Haskell/Solutions/List_processing and I didn't manage to understand little things like 'x == y' in the encode function
19:39:52<andouille>Can you help me please, it's for coding a RLE
19:40:11<Cale>okay
19:40:23<Cale>deech_: I'm not sure. There are various HTML parsing libraries though
19:41:02<Cale>andouille: The x == y is a guard
19:41:18<Cale>andouille: Only if x == y gives True does that equation apply.
19:41:32<Cale>andouille: Otherwise, the 'otherwise' case is used.
19:41:59<Cale>That is, if x == y then the result of encode (x:y:xs) is succHead (encode (y:xs))
19:42:02<Baughn>andouille: "otherwise" is just a global binding to True, by the way. It's not syntax.
19:42:24<andouille>SO if 'x == y', what does it means concretly for the list ?
19:42:36<cob_jonas>@type (==)
19:42:37<lambdabot>forall a. (Eq a) => a -> a -> Bool
19:42:40<Cale>andouille: That the first two elements are equal
19:42:45<cob_jonas>> 3 == 5
19:42:46<lambdabot> False
19:42:48<cob_jonas>> 3 == 3
19:42:49<lambdabot> True
19:42:50<cob_jonas>> 3 == 2
19:42:51<andouille>does it means that @type(==)
19:42:52<lambdabot> False
19:42:54<Baughn>andouille: (x:y:xs), see
19:42:58<andouille>omg sorry
19:43:09<andouille>Ok thanks
19:43:11<Phyx->> otherwise && otherwise
19:43:12<lambdabot> True
19:43:14<Phyx->lol
19:43:16<Cale>andouille: (x:y:xs) is the list whose first two elements are x and y respectively, and the rest is called xs
19:43:18<Phyx->now that's funny
19:43:53<Peaker>> otherwise
19:43:54<lambdabot> True
19:44:02<Cale>andouille: I think I should point out that this way uses way too much explicit recursion, and isn't really making the most of library functions :)
19:44:09<andouille>Ok, I used to think that it was the first element that's x, the rest that's y and the last one that's xs.
19:44:12<Baughn>andouille: Or, in a pattern-match context, it's a pattern-match that decomposes such a list into the originating x, y and xs :)
19:44:12<andouille>Thanks
19:44:22<Baughn>> 2:3:[4..7]
19:44:22<Cale>> map (\xs -> (length xs, head xs)) . group $ "mississippi"
19:44:23<lambdabot> [2,3,4,5,6,7]
19:44:24<lambdabot> [(1,'m'),(1,'i'),(2,'s'),(1,'i'),(2,'s'),(1,'i'),(2,'p'),(1,'i')]
19:44:40<Baughn>> 2:3:0:[4..7] -- andouille: See? Simple.
19:44:41<lambdabot> [2,3,0,4,5,6,7]
19:44:50<Cale>> map (\xs -> (length xs, head xs)) . group $ "ruuuuunnnnnn lllleeeennnnnngggttthh"
19:44:52<lambdabot> [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2...
19:44:55<andouille>:D
19:45:18<pumpkin>aw, no &&& ?
19:45:31<pumpkin>Control.Arrow needs lovin too
19:45:34<Baughn>> map (length &&& head) . group $ "ruuuun length"
19:45:35<lambdabot> [(1,'r'),(4,'u'),(1,'n'),(1,' '),(1,'l'),(1,'e'),(1,'n'),(1,'g'),(1,'t'),(1...
19:46:01<hackagebot>hack-handler-kibro 2009.5.27
19:46:01<hackagebot>bamboo 2009.5.27
19:46:22<pumpkin>> concatMap (uncurry replicate) . map (length &&& head) . group $ "ruuuun length"
19:46:23<lambdabot> "ruuuun length"
19:46:26<Cale>> concatMap (\(n,x) -> replicate n x) $ [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2,h)]
19:46:28<lambdabot> No instance for (SimpleReflect.FromExpr GHC.Types.Char)
19:46:28<lambdabot> arising from a u...
19:46:32<andouille>How could I find a really good tutorial or a documentation for all the "operators" like '.' or '$' please
19:46:32<Cale>oops
19:46:37<Cale>> concatMap (\(n,x) -> replicate n x) $ [(1,'r'),(5,'u'),(6,'n'),(3,' '),(4,'l'),(4,'e'),(6,'n'),(3,'g'),(3,'t'),(2,'h')]
19:46:38<lambdabot> "ruuuuunnnnnn lllleeeennnnnngggttthh"
19:47:03<cob_jonas>($) is just identity restricted to functions, (.) is function composition
19:47:05<Cale>So basically, whoever wrote that code didn't know about... map, concatMap, group, replicate... :)
19:47:08<Baughn>andouille: Well, . and $ are just function composition and application respectively
19:47:23<pumpkin>> uncurry replicate =<< (map (length &&& head) . group $ "ruuuun length")
19:47:24<lambdabot> "ruuuun length"
19:47:25<Cale>@src (.)
19:47:26<lambdabot>(f . g) x = f (g x)
19:47:34<hatds>I think what you are asking for is to be directed towards a list of prelude functions and their definitions
19:47:46<andouille>ok, but where can I learn to use map, replicate or other things lique that (pre-built functions ?) ?
19:47:48<Cale>andouille: (.) takes two functions f and g and makes a function which when applied to x gives f (g x)
19:48:04<andouille>hatds, exactly ;)
19:48:12<cob_jonas>dunno, some book?
19:48:12<Cale>andouille: $ takes a function and a value to apply it to, and applies the function
19:48:16<Cale>@src ($)
19:48:17<hatds>http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
19:48:18<lambdabot>f $ x = f x
19:48:22<Baughn>andouille: I don't recall ever reading such a tutorial; you learn by using them
19:48:34<Baughn>andouille: Start by walking through all the prelude functions. :)
19:48:38<Cale>This seems pointless, but the main purpose of it is that $ has really low precedence
19:48:54<Baughn>> map ($ 3) [(+1),(*2)] -- Also this
19:48:56<lambdabot> [4,6]
19:49:03<Cale>So it's as if you've wrapped both sides in parens
19:49:20<andouille>ok
19:49:28<andouille>thank you very much
19:49:37<cob_jonas>(and then all functions of Data.List and Control.Monad and Data.Maybe, most importantly foldr and foldl')
19:51:59<cob_jonas>but another method to learn all the funny function is to hang around here and listen and ask questions and sooner or later you'll meet the more useful functions
19:52:05<cob_jonas>at least I found that works
19:52:09<Cale>He quit for some reason
19:52:36<cob_jonas>yeah, I see
19:52:39<cob_jonas>still
19:53:49<cob_jonas>I found that works
19:54:04<cob_jonas>I mean how'd I guess which of the lots of functions to look at?
19:54:16<cob_jonas>if I see them here in use I can pick the useful modules and functions
19:54:43<cob_jonas>@type liftM2
19:54:45<lambdabot>forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
19:54:45<cob_jonas>@type liftA2
19:54:47<lambdabot>forall a b c (f :: * -> *). (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
19:57:51<kniu>Do full record types make positionally-accessed types obsolete?
19:59:00<cob_jonas>kniu: what positionally accessed types?
19:59:03<Twey>kniu: They should do, for flexibility
19:59:29<Twey>A record type is usually a big type whose members are likely to change during the course of development
19:59:54<Twey>Accessing it solely via record syntax and the provided getters allows that to be done without it becoming a problem
20:00:04<Twey>Accessing it positionally would break that
20:00:14<kniu>k
20:03:48<Baughn>"isHNF :: a -> IO Bool" <-- Oh yeah, there we go.
20:04:27<pumpkin>does it actually work right? Cale tried that code we found on the mailing list last night and it didn't look too correct
20:04:45<Cale>What?
20:04:48<Baughn>..well, I'm about to find out.
20:05:04<Cale>I found an isWHNF on the mailing list, but it was totally broken.
20:05:11<pumpkin>yeah :)
20:05:43<Cale>Also, it still had the problem that error "foo" has the same ClosureType as 5
20:06:29<Baughn>Even after rwhnf'ing 5?
20:07:02<pumpkin>does that do anything?
20:07:08<Cale>yeah.
20:07:24<pumpkin>what type does it give 5?
20:07:24<Cale>Or making it monomorphic.
20:07:26<Cale>AP
20:08:09<Cale>oh...
20:08:32<Cale>*Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` getClosureType x
20:08:32<Cale>Indirection 28
20:08:45<Cale>But the code which they had for handling indirections is broken.
20:09:53<Baughn>So I'll have to fix that, I guess
20:11:07<hackagebot>hack-middleware-jsonp 0.0.0
20:12:37<Cale>Baughn: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5284#a5284
20:14:23<Baughn>Cale: An AP's a thunk type, though
20:14:42<Baughn>Cale: It may have been rwhnf'd, but it.. isn't in HNF
20:15:07<Cale>It's because x is polymorphic
20:15:26<Cale>But somehow it doesn't show up as Fun like I'd expect.
20:18:04<Cale>(It ought to be a function of the typeclass dictionary, shouldn't it?
20:18:05<Cale>)
20:18:17<Cale>Oh, I see.
20:18:31<Cale>Those are two separate x's.
20:19:41<Cale>So it's like rwhnf (x instanceNumInteger) `seq` getClosureType (x instanceNumInteger)
20:19:46<Cale>It doesn't help :)
20:19:55<Cale>*Main Control.Parallel.Strategies> let x = 5; y = x :: Integer in rwhnf y `seq` getClosureType y
20:19:56<Cale>Indirection 28
20:20:01<Cale>That works though.
20:20:31<Cale>*Main Control.Parallel.Strategies> let x = 5; y = x :: Integer in y `seq` getClosureType y
20:20:31<Cale>Constr
20:20:32<Cale>and that
20:21:14<hackagebot>hack-middleware-cleanpath 0.0.0
20:21:21<Cale>Now, if only we could see past the indirections...
20:22:05<Cale>Baughn: oh, another strange and unexpected one:
20:22:08<Cale>*Main Control.Parallel.Strategies> getClosureType "a"
20:22:08<Cale>Constr
20:22:08<Cale>*Main Control.Parallel.Strategies> getClosureType "ab"
20:22:08<Cale>AP
20:22:23<Cale>*Main Control.Parallel.Strategies> getClosureType ('a':'b':[])
20:22:23<Cale>Constr
20:22:33<pumpkin>why are those different?
20:23:04<Cale>I have no idea. I thought it might have something to do with the polymorphic strings extension.
20:23:13<Cale>But "a" is still in string syntax.
20:23:36<Cale>So if it really was that extension, it should be AP too.
20:23:39<pumpkin>yeah
20:23:49<Cale>(because it'd be fromString "a" or whatever)
20:23:58<pumpkin>you could try running it all under XOverloadedStrings ?
20:24:19<Cale>same results
20:29:42<Jedai>There is all this optimisation stuff with unpackCString and so on
20:30:13<Jedai>It could be what's causing the difference between those case
20:30:25<pumpkin>I thought that was only when you actually compile things
20:30:57<Jedai>pumpkin: I must admit that I'm not too sure of wether that's the case or not
20:31:30<Jedai>It was just an hypothesis to try and explain this weird result
20:34:18<Baughn>..oh dear, got to use an unsafeCoerce here
20:34:51<Baughn>@index unsafeCoerce
20:34:52<lambdabot>bzzt
20:35:01<Botje>System.Unsafe, i guess?
20:35:07<Baughn>Unsafe.Coerce, actually
20:35:13<Botje>oh. boo :)
20:37:07<pumpkin>nothing more fun than unsafeCoerce
20:37:10<pumpkin>except unsafeCoerce#
20:37:39<pumpkin>actually, probably a lot of things more fun than that :P
20:38:22<pumpkin>bbl :)
20:38:56<Peaker>@type System.Unsafe.Coerce.unsafeCoerce
20:38:58<lambdabot>Couldn't find qualified module.
20:39:01<Peaker>@type Unsafe.Coerce.unsafeCoerce
20:39:03<lambdabot>forall a b. a -> b
20:39:13<Peaker>System.Unsafe vs Unsafe? Hmm
20:44:27<Cale>Baughn: I tried using unsafeCoerce for following the indirections, but wasn't able to get anything but a segfault. However, I have no idea what I'm doing :)
20:46:07<Baughn>Cale: Hm. Well, basically HValue is a wrapper for.. any lifted type
20:46:15<Baughn>I got it working. :D
20:46:23<Cale>Oh, interesting.
20:46:43<Baughn>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5285#a5285
20:47:08<duaneb>man
20:47:15<duaneb>ocaml is so unfunctional
20:47:16<duaneb>:P
20:47:22<duaneb>it's kind of painful to read ocaml code
20:47:30<Cale>Oh, heh, I see what I did wrong. :)
20:47:30<duaneb>it's like a really ugly c
20:47:48<Baughn>Cale: That would be?
20:48:19<Cale>Getting the parameters in the wrong order and not being warned by the typechecker because one was unsafeCoerced and the other polymorphic :)
20:48:19<arcatan>no, ocaml is like better C
20:48:27<Baughn>Cale: Eheh. ^^;
20:48:33<duaneb>arcatan: how so?
20:48:33<lament>better, uglier C?
20:48:51<duaneb>it seems like a less-f'd up C++
20:48:59<duaneb>but with boxed types
20:49:22<duaneb>and an option for tail recursion :P
20:50:09<Cale>Baughn: Should there be any difference between unsafeCoerce and unsafeCoerce# here?
20:50:40<Baughn>Cale: No, they're equal
20:51:15<Cale>*Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` getClosureType x
20:51:15<Cale>Indirection 28
20:51:15<Cale>*Main Control.Parallel.Strategies> let x = 5 :: Integer in rwhnf x `seq` removingIndirections getClosureType x
20:51:15<Cale>AP
20:51:21<Cale>hmm
20:53:00<Cale>ACTION suddenly wishes that GHC preserved expressions somehow. :)
20:54:20<Cale>Baughn: Shouldn't it still be isWHNF? You're actually not looking underneath functions...
20:54:46<Baughn>Cale: Near as I can tell, HNF is a subset of WHNF, and this function is only complete for HNF
20:54:50<Baughn>..well, not even that, really
20:55:01<Baughn>But I'm not very sure of the terminology. :/
20:55:12<Cale>I get PAP for (\x -> x+1) which is in HNF
20:55:34<Cale>and your function will produce False for that...
20:55:50<Cale>(it's also in WHNF)
20:56:09<Baughn>True. I'm not sure whether producing True for PAP is /safe/ or not, since I'm not sure what PAP really is.
20:56:23<Baughn>In this case, bogus False is safe; bogus True isn't
20:56:26<Cale>yeah, it would be good to figure that out... :)
20:56:47<Cale>I wonder where all these types are really documented...
20:58:40<Cale>"Entry Code for an AP (a PAP with arity zero)."
20:58:57<Baughn>I see
20:59:10<Baughn>So.. (\x -> error "foo") would be PAP too
20:59:18<Baughn>Well, certainly can't return True for that. :)
20:59:23<Baughn>Hm. Actually, I could
20:59:27<Baughn>..
20:59:27<Cale>That should be in WHNF
20:59:40<Baughn>Right, evaluating a function succeeds, even if /calling/ the function would fail
20:59:44<Baughn>So PAP => True is safe
20:59:57<Baughn>AP, not so much
21:00:05<Cale>right
21:00:29<mib_xxfkjqs6>hey
21:00:37<mib_xxfkjqs6>wondering if anone can help me
21:00:39<Baughn>I didn't bother with defining a case for Blackhole, but have you seen anything that produces it?
21:00:56<mib_xxfkjqs6>im trying to sort some data in haskell
21:00:59<mib_xxfkjqs6>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5286
21:01:18<mib_xxfkjqs6>by fans has anyone got any ideas
21:01:25<Cale>Baughn: It probably ought to be treated as not in WHNF
21:01:39<Baughn>Cale: Yes, but if it's at all useful I might add a third return value
21:01:49<Baughn>WHNF, Undecided and Bottom
21:02:05<Cale>mib_xxfkjqs6: By number of fans?
21:02:12<mib_xxfkjqs6>yea
21:02:38<Cale>fanCount (Film t d y fs) = length fs
21:02:43<mib_xxfkjqs6>was going to length the fan list
21:02:52<Cale>and then, sortBy (comparing fanCount) films
21:03:03<mib_xxfkjqs6>ah awesome
21:03:04<Cale>But that's not terribly efficient.
21:03:06<mib_xxfkjqs6>thanks
21:03:28<mib_xxfkjqs6>ok
21:03:41<Cale>another way is to map (\x -> (fanCount x, x)) over the list and then sortBy (comparing fst)
21:03:44<mib_xxfkjqs6>is there a better way that i could look into
21:03:54<Baughn>@tell conal http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5289#a5290 <-- Here's the latest version of Unamb, with WHNF-detection. It appears to work, but YMMV.
21:03:54<lambdabot>Consider it noted.
21:04:08<Cale>map snd . sortBy (comparing fst) $ [(fancount x, x) | x <- films]
21:04:33<Cale>That way, you only compute the number of fans once per film.
21:04:44<Cale>Rather than every time two are compared.
21:05:59<Baughn>Cale: Thanks for your help. This will either blow up spectacularily, or improve performance dramatically. :
21:06:02<Baughn>:)
21:06:04<Cale>hehe
21:06:31<Cale>Baughn: I wonder if this is at all related to any of the bugs that I added to the reactive trac
21:06:46<mib_xxfkjqs6>thanks cale
21:08:05<Baughn>Cale: It probably is. The currently-on-hackage Unamb is fundamentally broken.
21:08:11<Baughn>Cale: You should try mine, though perhaps without isHNF.
21:08:20<Baughn>@tell conal Oh, and I updated the comments.
21:08:21<lambdabot>Consider it noted.
21:11:17<skorpan>how do you pronounce <*>? "sequence?"
21:11:40<Baughn>"ap"
21:11:44<Peaker>@hoogle --info discriminate
21:11:45<lambdabot>Parse error:
21:11:45<lambdabot> --count=20 "--info discriminate"
21:11:45<lambdabot> ^
21:11:51<Peaker>@hoogle discriminate --info
21:11:52<lambdabot>No results found
21:12:02<Peaker>oh, silly me
21:12:03<Baughn>@hoogle discriminate
21:12:03<lambdabot>No results found
21:12:12<Baughn>Peaker: ..but what are you checking that for?
21:12:16<Peaker>@hoogle tipe --info
21:12:17<lambdabot>No results found
21:12:20<Peaker>Baughn: trying to read your paste
21:12:32<Peaker>discriminate is right there, I missed it
21:13:30<Peaker>Baughn: what about blocking in the do block of unsafePerformIO? What if you get an early exception?
21:14:01<Baughn>Peaker: THen it'll simply get restarted automatically.
21:14:35<Baughn>Peaker: You only need to worry about exceptions in unsafePerformIO if you do any exception handling. Otherwise it's totally transparent.
21:14:43<Peaker>unsafePerformIO just loops around execution of the IO until it stops throwing exceptions?
21:15:04<Baughn>Actually, it /pauses/ the execution if the thread throws an exception (or receives one)
21:15:09<Baughn>Then it restarts it from where it stopped
21:15:27<Baughn>I'm not sure I want to think too much about how that is implemented, but it's semantically correct.
21:15:44<Baughn>I only need to worry about it because I use an exception handler to kill some threads if that happens, and I need to restart them.
21:15:58<Peaker>Baughn: in what sense it is paused if it is then resumed immediately?
21:16:06<Baughn>Peaker: It isn't resumed immediately
21:16:14<Baughn>Peaker: let a = unsafePerformIO something
21:16:28<Baughn>Peaker: If you evaluate a and, while that happens, throw/receive an exception, the evaluation is paused
21:16:39<Peaker>until what?
21:16:39<Baughn>But /your thread is killed/, or at least thrown back out to some higher level
21:16:53<Baughn>It restarts once some thread - any thread - starts evaluating a again
21:17:03<Peaker>the whole *thread* that happened to use the thunk with the unsafePerformIO is killed?
21:17:03<Baughn>Well. Unpauses.
21:17:28<Peaker>does unsafePerformIO start a new thread for the action?
21:17:35<Baughn>Peaker: Whatever would normally happen for an exception happens. If there are no exception handlers, then sure.
21:17:38<Baughn>And no.
21:17:40<Cale>skorpan: yeah, <*> is equivalent to Control.Monad.ap, so that's how I'd normally pronounce it too
21:17:51<skorpan>okay
21:17:52<Cale>(apart from having a more general type)
21:18:09<Baughn>Peaker: If you don't touch exceptions inside your unsafePerformIO code (except perhaps to throw one)..
21:18:12<skorpan>can you use constructors infix? e.g. 1 `Hello` 3, where Hello :: Int -> Int -> Hello
21:18:16<Cale>yes
21:18:16<Baughn>Peaker: ..then it works the same way as a throw from pure code.
21:18:25<skorpan>thanks
21:18:34<Baughn>Peaker: You *can't immediately resume the evaluation*, since an exception *handler* has to be in IO
21:18:36<Peaker>Baughn: oh, so thread A uses unsafePerformIO on an action -- it raises, thread A gets a bottom, but Haskell remembers that internal action's state. Another guy tries to use the thunk, it continues execution of that remembered action in the context of a new thread?
21:18:41<Cale>Apart from pattern matching, constructors are normal functions and work exactly the same as them in every way.
21:18:46<Baughn>Peaker: Yes
21:19:14<Cale>Well, I suppose there's record syntax too...
21:19:14<Baughn>Peaker: One gotcha here is that if the exception is /from/ the unsafePerformIO (eg. throwIO (or throw)), then that continuation will just re-throw the exception. :P
21:19:24<Peaker>Baughn: so this is a pretty special thing, as IO actions can migrate between threads (the only place it ever happens?)
21:19:27<Cale>(but that's unsurprising :)
21:19:33<hackagebot>buster 2.2
21:19:43<Baughn>Peaker: Yes
21:19:44<Cale>hackagebot! You should give a link!
21:19:51<Peaker>Baughn: what a weird implementation
21:20:03<Baughn>Peaker: So in my code I need to throw an exception, but only /once/, to the thread that it's currently executing in
21:20:09<Baughn>Peaker: Thus the throwTo myId
21:20:22<Peaker>Baughn: why doesn't it just restart the whole action in that case?
21:20:35<Baughn>Peaker: To avoid lost work
21:20:56<Baughn>Peaker: Exceptions are defined to never destroy in-progress evaluation, only pause them
21:21:02<Peaker>oh, there's the issue that unsafePerformIO tries to guarantee the action will run just once
21:21:36<Baughn>Peaker: Anyway. Once another thread resumes the unamb, the throwTo will be re-executed; *however*, the thread ID it gets is now dead, so nothing happens and the code continues from where it left off
21:21:40<Peaker>I see the logic of this choice.. the action is run for someone who needs the value.. doesn't need it anymore? pause until someone does
21:21:48<Baughn>Right
21:22:23<Cale>I wonder if you can rig it so that two consecutive calls to myThreadId return different things :)
21:22:27<Baughn>It got a bit hacky for me, but only because I want to throw an exception /only once/
21:22:46<Peaker>Baughn: I think this could probably be abstracted away more nicely by an unsafePerformIO wrapper?
21:23:00<Baughn>Peaker: That's basically what retry is
21:23:25<Baughn>It allows actions to be restarted instead of resumed
21:23:29<Peaker>Baughn: make it its own function - it may be very useful on its own then
21:23:45<Baughn>Peaker: Considering how much trouble figuring it out was, yeah, I bet.
21:23:52<Baughn>Peaker: But I won't until I'm sure I know it works right.
21:24:08<Cale>I wonder if unamb might have an easier time were it to be implemented as a GHC primop.
21:24:19<Peaker>Baughn: btw, if you re-call (retry act) you might want to memoize the result of (retry act), e.g: retry act = result where result = ... code
21:24:28<Baughn>Cale: Given isHNF..? Oh yeah.
21:24:59<Baughn>Peaker: No point. If I got the result, there would be no exception.
21:25:04<duaneb>I need new coding music.
21:25:33<Peaker>Baughn: is it ok that race assumes that f b does not throwIO?
21:26:06<Peaker>Baughn: "result" would not be the result you got, it would just be the memoized action instead of rebinding it each time
21:26:12<Peaker>Baughn: similarly to:
21:26:14<Peaker>@src forever
21:26:15<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
21:26:17<Baughn>Peaker: I don't see how race assumes that
21:26:29<nimred>hello #haskell
21:26:30<Peaker>forever act = loop where loop = act >> loop
21:26:47<Peaker>Baughn: instead of: forever act = act >> forever act
21:27:20<Baughn>Peaker: Please keep in mind that the restart is inside an exception handler. No exception, no restart.
21:27:34<Baughn>If exception, no return value
21:27:53<Cale>nimred: hello!
21:27:55<nimred>i am trying to build X11 binding using cabal. so i read i need to run autoreconf first, but can you please tell me wich way ?
21:28:15<Cale>nimred: What? autoreconf?
21:28:19<Baughn>nimred: "cabal install X11" always worked for me
21:28:23<Peaker>Baughn: you'll recall "catch" multiple times if you handle multiple exceptions to build the catching action, instead of just re-using the previous "catch" result
21:28:48<Cale>Yeah, cabal install ought to work fine...
21:28:59<Baughn>Peaker: I still don't see what result you're talking about
21:29:19<nimred>Cale http://darcs.haskell.org/X11/README
21:29:20<Baughn>By the time there /is/ a result anywhere, my job is already done and it's returning to whatever called unamb
21:29:39<Cale>nimred: Oh, you're installing the darcs version rather than the one on Hackage?
21:30:00<Peaker>Baughn: just give a name to "retry act" so the *IO action* is memoized, not any runtime result
21:30:16<Cale>nimred: It appears to have the same version number as the one on hackage anyway...
21:30:38<Baughn>Peaker: ..what would this buy me?
21:30:42<nimred>Cale i am trying to install xmonad from hand on OpenBSD
21:31:18<Cale>nimred: I would start by making sure that cabal-install is installed, as it will make solving dependency problems much simpler.
21:31:19<nimred>OpenBSD package system doesn't include xmonad-contrib
21:31:35<nimred>cabal-install ?
21:31:40<Peaker>Baughn: "throwTo myid e >> retry act" here will re-compute (retry act) - i.e recall "catch"/etc. If you just give it a name it will save a bit of runtime and perhaps memory (in case of repeated exceptions, maybe its even significant), just a convention that I find useful in general to memoize my function with the args if I recurse to it with the same args
21:31:52<Cale>yes, it's a tool for downloading and installing Haskell programs and libraries
21:31:59<Cale>http://hackage.haskell.org/packages/archive/pkg-list.html is the list of packages available
21:32:16<Baughn>Peaker: I find it hard to believe that will make any difference whatsoever. Keep in mind, GHC doesn't do partial evaluation.
21:32:16<Cale>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad
21:32:32<Cale>If you have cabal-install, you should be able to type cabal install xmonad and be done.
21:32:33<nimred>isn't it included in http://www.haskell.org/cabal/release/cabal-1.6.0.2/Cabal-1.6.0.2.tar.gz that i installed ?
21:32:44<Cale>No, that's the Cabal library.
21:32:45<Baughn>Peaker: (Even if it did, the cost of code generation here would enormously dwarf the cost of not generating code; the number of retry calls will usually be very small)
21:32:55<nimred>Cale ah
21:32:59<Peaker>Baughn: why is forever act = act >> forever act worse than forever act = result where result = act >> result ?
21:33:14<Cale>nimred: Also, you shouldn't need to get that manually.
21:33:16<tibbe>How can we emulate something like this http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5292#a5292 in Haskell?
21:33:19<Cale>nimred: It comes with GHC anyway.
21:33:32<tibbe>the use case is a web app that gets fed data incrementally
21:33:36<Baughn>Peaker: It isn't. It's the same exact thing.
21:34:02<nimred>Cale let me see
21:34:08<Cale>http://hackage.haskell.org/packages/archive/cabal-install/0.6.2/cabal-install-0.6.2.tar.gz -- you can get the source for cabal-install here. Inside you'll find a bootstrap.sh which, supposing you're not missing libraries that come with GHC, should get you started.
21:34:08<Peaker>Baughn: Why is fix f = f (fix f) worse than fix f = result where result = f result ?
21:34:38<Peaker>Baughn: its different - because ghc memoizes stuff that has a name, but not function applications
21:34:57<Baughn>Peaker: In /that/ case it's different
21:35:21<mwc_>What's the story on why Parsec 3.0 isn't widely used yet? Some sort of horrible bug?
21:35:24<Cale>nimred: I think by default it installs to ~/.cabal/bin. Normally, I make that into a link to ~/bin pre-emptively, but you could also just add it to your path.
21:35:57<mwc_>or is it just that parsec 2.1 is the version shipped with ghc?
21:36:03<Peaker>Baughn: Are you sure the forever case doesn't make a difference? I'm pretty sure Control.Monad.forever uses the seemingly pointless "where" clause
21:36:04<Cale>(it's where binaries for cabal packages end up getting installed when you install as user)
21:36:16<Cale>mwc_: I bet the latter.
21:36:37<Baughn>Peaker: I'm sure it makes no difference for IO. Other monads, again, are different; it makes no difference in this case because IO is strict.
21:37:58<nimred>Cale : i have ghc installed on my system but no cabal-install binary
21:38:02<Peaker>Baughn: Ok, I don't know enough about the implementation details of IO bind, maybe you're right
21:38:11<Cale>nimred: Right.
21:38:22<Cale>nimred: So, get that tarball I linked to
21:38:27<Cale>http://hackage.haskell.org/packages/archive/cabal-install/0.6.2/cabal-install-0.6.2.tar.gz
21:38:43<Cale>and inside you'll find bootstrap.sh which you should try running
21:38:56<Baughn>Peaker: For another monad, forever can build up an arbitrarily long chain of applications (even infinite.. doh, I guess), which if would've blown the stack when evaluated
21:39:28<ray>stacks only get "blown" in haskell, i've noticed
21:39:37<Baughn>Peaker: For IO, evaluation is strict; I /sort/ of build a retry thunk, but it doesn't get nested; thunk A is being evaluated (running retry) before B (the recursive call) even gets started, and by the time B is constructed A can be GC'd
21:39:57<Baughn>ray: As opposed to?
21:39:57<nimred>Cale --> http://pastebin.com/m6fe3006a :/
21:40:14<ray>overflown or whatever
21:40:34<Peaker>Baughn: the nested thunks is not the only reason you want not to build them - its also unnecessary extra work
21:40:44<Baughn>Peaker: Which is unnoticable
21:40:50<Cale>nimred: Okay, your ghc is missing packages...
21:40:59<ray>i like blown, it comes with the mental image of a stack bursting through an invisible sheet of plastic wrap, causing disaster
21:41:06<Cale>nimred: Which normally come with ghc.
21:41:10<byorgey>nimred: are you using ghc 6.6.1 ?
21:41:11<Baughn>Peaker: Trust me, you won't notice something like five instructions between the two forkIO calls, the MVar stuff and the RTS closure inspections.
21:41:12<Peaker>Baughn: anyhow, great work on unamb there, I think your discoveries should probably be put into a library meant to make unsafePerformIO more usable
21:41:29<Peaker>Baughn: Maybe abstracted a bit more for generality, though
21:41:32<nimred>Cale :
21:41:33<nimred>$ pkg_info | grep ghc
21:41:34<nimred>ghc-6.6.1p2 compiler for the functional language Haskell
21:41:36<Baughn>Peaker: Once I'm sure it works. :)
21:41:47<Cale>nimred: Oh, haha, that's like a few years old.
21:42:03<Cale>nimred: I'll be surprised if you can get xmonad to compile with it :)
21:42:11<ray>ghc 6.6.1 is 2 minor major versions old
21:42:16<Peaker>Baughn: why is loop trying twice?
21:42:21<byorgey>yeah, I'm not sure if we still support 6.6
21:42:23<nimred>Cale --> http://openports.se/lang/ghc
21:42:25<byorgey>xmonad, that is
21:42:30<Baughn>Peaker: Two threads.
21:42:37<Baughn>Peaker: It counts the number of running threads, basically
21:42:54<Cale>Version 6.6.1 (released 26 April 2007)
21:43:33<Peaker>Baughn: oh, I see, because you changed it to put in the MVar even if it fails
21:43:49<nimred>Cale : what version would i need ?
21:43:54<arjanb>what is a practical way to debug a loop in a big knot tying piece of code?
21:44:16<byorgey>nimred: 6.8 should be fine, but as long as you're upgrading might as well get the latest release, 6.10.3
21:44:17<Baughn>arjanb: Hum. I think i could invent one.
21:44:18<ray>does openbsd still hate haskell?
21:44:18<Twey>Unravel it into nice simple code :-P
21:44:22<Baughn>arjanb: It would be useful
21:44:27<byorgey>nimred: you can get it here: http://haskell.org/ghc/
21:44:33<byorgey>should be a binary package that will work
21:44:42<Cale>byorgey: But he's on OpenBSD, will it really?
21:44:46<nimred>Cale : ok but wich way to install ?
21:45:14<byorgey>hmm, the ghc page says the OpenBSD package is maintained by dons.
21:45:26<Baughn>arjanb: Anyway, vacuum. I don't know if it already does this, but it'd be possible to have it survive meeting bottom and show those as well
21:45:27<Cale>dons!!
21:45:29<Cale>hehe
21:45:40<byorgey>nimred: check this page: http://haskell.org/ghc/distribution_packages.html#netbsd
21:45:55<byorgey>it says 'GHC is in the OpenBSG ports tree as lang/ghc'
21:46:02<byorgey>is that the same thing you had before?
21:46:22<byorgey>ACTION knows nothing about OpenBSD
21:46:40<Baughn>, vacuum [2,3,undefined]
21:46:43<ray>they appear to hate haskell
21:46:44<lunabot> luna: Prelude.undefined
21:46:54<Baughn>arjanb: ..yep, will take a little work
21:46:58<nimred>Cale : i know that see http://pkgsrc.se/search.php?so=ghc
21:47:04<arjanb>Baughn: nice idea but will it survive the stackoverflow?
21:47:08<Baughn>mmorrow: How do you feel about fixing up vacuum to show (some) bottoms?
21:47:08<copumpkin>Baughn: is your isWHNF for vacuum?
21:47:11<Botje>ray: they should, it makes their "secure C code" look pathetic :o)
21:47:19<byorgey>nimred: ah, that looks better
21:47:20<Baughn>copumpkin: No, unamb
21:47:20<Cale>nimred: Did you really mean to address that to me?
21:47:22<copumpkin>ah
21:47:42<copumpkin>vacuum should never evaluate anything unless it's already been evaluated!
21:47:44<Baughn>copumpkin: Vacuum doesn't need it. :)
21:47:56<Baughn>copumpkin: ..ooh, good idea
21:48:08<byorgey>nimred: the lang/ghc one (6.8.3) should be fine
21:48:21<Baughn>mmorrow: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5289#a5290 <-- Oh, and here's some code you may find useful to make vacuum /not/ follow thunks. :D
21:48:23<nimred>ok see you in a moment i switch to NetBSD
21:48:32<Cale>nimred: ...
21:48:35<copumpkin>who'da thunk it?
21:48:49<Baughn>copumpkin: ..you die. Slowly, painfully, and with flowers.
21:49:21<copumpkin>lol
21:49:25<Cale>ah, it is netbsd
21:49:26<Cale>hehe
21:49:36<ray>i'm a lazy thunk, and nobody ever evaluates me
21:49:37<copumpkin>ACTION feels the love
21:50:32<Cale>nimred: if we can get dons here, he'd probably know, though I think he's using ArchLinux these days.
21:51:08<mmorrow>Baughn: i just removed the ghc pkg dep from vacuum, and improved a few other things. no 30MB binaries!! :)
21:51:22<copumpkin>nice
21:51:36<copumpkin>mmorrow: is what I said above possible?
21:51:37<mmorrow>Baughn: (and its getClosureType is s.t. you can use it for your isWHNF now)
21:51:46<mmorrow>um, /me looks
21:51:48<Cale>http://www.cse.unsw.edu.au/~dons/haskell_openbsd.html -- this hasn't been updated since 2005... へ_へ;
21:51:49<copumpkin>to not evaluate anything unless it's already been evaluated
21:51:59<copumpkin>zomg kana smiley
21:52:04<Baughn>mmorrow: Well, if you can duplicate the indirection, that's nice. :)
21:52:05<mmorrow>copumpkin: yes, i found out why things were segfaulting
21:52:12<copumpkin>nice!
21:52:35<mmorrow>i'm gonna add a vacuumNoForce (can you think of a better name?)
21:52:45<Baughn>vacuumNoEvaluate?
21:52:46<copumpkin>featherPaw
21:52:50<mmorrow>the only thing with that though is that you'll always have to run it like:
21:52:53<copumpkin>stealthyLikeACar
21:52:55<copumpkin>*Cat
21:52:58<mmorrow>a `seq` vacuumNoForce
21:52:59<Baughn>gentleSucktion
21:53:04<guenni>does anybody know where I can find the docs for parsec 3.0?
21:53:07<mmorrow>or you'll always just get a single node AP
21:53:08<arjanb>lazyVacuum
21:53:17<Baughn>mmorrow: Well, can't you move that seq inside the vacuum?
21:53:25<copumpkin>mmorrow: gentleVacuum?
21:53:27<guenni>mmorrow: hi
21:53:30<mmorrow>Baughn: hmm, good point
21:53:36<mmorrow>guenni: hi
21:54:20<copumpkin>alright bbiab :)
21:54:39<byorgey>guenni: on hackage?
21:54:45<byorgey>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsec
21:54:57<guenni>byorgey: whereever
21:55:36<guenni>sry I should have said "user manual"
21:55:43<Cale>Huh, there are a lot of people on various mailing lists reporting struggle in terms of getting recent releases of GHC on OpenBSD.
21:55:57<mmorrow>Baughn: hmm, i'll have to think about doing what's in that paste by default. that's an interesting idea though
21:56:05<byorgey>guenni: I don't think there is such a thing. The Haddock documentation looks detailed, though.
21:56:32<guenni>byorgey: thx
21:56:33<Baughn>mmorrow: Well, by 6.12 the size shouldn't be a problem anymore
21:56:42<mmorrow>Baughn: (i think indirs will only ever show up if things aren't being forced)
21:57:05<Baughn>mmorrow: ..yes, but that's the general idea, so...
21:57:11<mmorrow>cool :)
21:57:56<mmorrow>Baughn: (in fact, that's basically exactly how vacuum works, it just keeps doing that to get all reachables)
21:58:18<Baughn>Indirections show up a /lot/, due to the GC
21:59:52<cads>hey, I've got a representation of a vector space, and I want to test it for consistency
22:00:33<Cale>QuickCheck properties for the vector space axioms? :)
22:00:42<nimred>Cale ah. to tell the truth i didn't search for on google :/
22:01:07<cads>cale, that's essentially what I did
22:01:28<cads>I run random vectors through the axiom properties :)
22:01:30<Cale>nimred: I haven't found a solution, except that it might be possible to work your way up from 6.6.1 by building it from source...
22:01:45<cads>it checks out perfectly for integers and rationals
22:01:47<mmorrow>Baughn: yes, vacuum catches the exception thrown by `undefined', then vacuums that! :)
22:02:03<Cale>nimred: Would probably be a good idea to contribute a binary package if you got it working.
22:02:24<Baughn>, vacuum undefined
22:02:25<mmorrow>Baughn: http://moonpatio.com/vacuum/gallery/undefined.png
22:02:26<lunabot> luna: Prelude.undefined
22:02:29<mmorrow>not lunabot's
22:02:33<Cale>cads: Right, for floating point, you'll probably find lots of problems :)
22:02:34<Baughn>Ah
22:02:49<nimred>let's me try first on NetBSD with 6.8.3...
22:02:52<mmorrow>(lunabot's is from before the vacuum pkg actually, version -1)
22:03:08<Cale>nimred: Ah, if that's a realistic option, then it might work out for you :)
22:03:31<Cale>nimred: If you're switching operating systems altogether though, linux is much more convenient :P
22:03:31<mmorrow>(that list of chars you see in the image is "Prelude: unde..."
22:03:51<cads>Cale: you have an idea how I could write tests that would show that the floats are doing as well as they can in representing the vectors?
22:04:12<guenni>btw: is parsec still *the* recommended parsing library?
22:04:49<cads>I could use equality within a thresh-hold to show that the floats aren't off like crazy
22:05:11<cads>in fact, I think I'll find out what the error really is, I bet it's tiny
22:05:24<nimred>Cale well i will try on linux if i can't get it working on NetBSD neither...
22:05:26<Botje>is the Data instance for Data.Set broken?
22:06:56<mmorrow>Botje: it's crippled "to preserve abstraction" :(
22:07:38<Botje>mmorrow: uh oh. is this documented somewhere?
22:07:51<Cale>cads: I wonder... you could certainly write tests which said that the relative error was less than some bound or something.
22:08:01<cads>cale, I think I need to look up a little numerical analysis, I bet it's still possible to write theorems about floats, just with a little extra detail
22:08:06<mmorrow>Botje: in the comment above the instance decl in the Data.{[Int]Map,[Int]Set} src
22:08:14<cads>maybe a lot of extra detail, heh
22:08:39<Cale>cads: Yeah, I don't really know a lot about numerical analysis of that sort apart from the basic "Floating point arithmetic satisfies little other than commutativity"
22:08:49<mmorrow>-- This instance preserves data abstraction at the cost of inefficiency.
22:08:49<mmorrow>-- We omit reflection services for the sake of data abstraction
22:09:01<cads>heh, it's commutative?
22:09:16<Botje>well, it kind of breaks uniplate for Sets :)
22:09:33<Cale>Yeah, not that it means much in the face of the fact that it's not associative.
22:09:54<mmorrow>Botje: looks like you need to create a personal Data.Set fork :)
22:10:05<Botje>i'll .. consider it :p
22:10:10<Botje>thanks for the info!
22:10:13<mmorrow>np
22:10:44<cads>floating points are a little disturbing like that
22:11:36<Cale>Also, equality testing for NaN is stupid :)
22:11:48<Cale>> let x = 0/0 in x == x
22:11:50<lambdabot> False
22:12:29<cads>my tests would have to be truncated to some digit threshold if I was using computable reals :/
22:12:30<mmorrow>what should it do?
22:12:37<mmorrow>NaB(ool)?
22:12:57<Cale>Well, you'd normally want == to at least be an equivalence relation
22:13:01<cads>> let x = 1/0 in x == x
22:13:03<lambdabot> True
22:13:10<Cale>x == x should be unconditionally true
22:13:12<mmorrow>ohhhh
22:13:18<cads>that's funky
22:13:21<mmorrow>i just realized that's what you did
22:13:36<mmorrow>yeah, that is annoying
22:14:09<Cale>It's arguable that since NaN represents a failure anyway then all its comparisons should fail, but then we have:
22:14:12<Cale>> let x = 0/0 in x /= x
22:14:14<lambdabot> True
22:14:43<davidL>is there an algorithm to convert a turing machine to a pushdown automata?
22:14:49<Cale>davidL: No.
22:14:53<mmorrow>, let a .==. b = if (isNaN a && isNaN b) || a == b then True else False in let x = 0/0 in x .==. x
22:14:54<lunabot> True
22:15:03<Cale>davidL: Because PDAs can only recognise context free languages.
22:15:10<xian>Hi, I'm having a stupid question: I have a function f x y and I partially apply it by supplying a value for x. There's a let-binding z inside f depending only on x. I want z evaluated when g = f x is called so that it isn't evaluated every time I call g y.
22:15:21<mmorrow>yeah, the NaN equality thing could be argued both ways i guess
22:15:24<davidL>Cale: errr, rather, a TM that is known to be context-free
22:16:05<cads>mmorrow: is nan also supposed to be a kind of "bottom" value as well?
22:16:10<Cale>davidL: That's a more interesting question. I have no idea. I suspect you might be able to use the *proof* that it's context free to generate a PDA.
22:16:43<Cale>xian: It probably ought to already
22:16:48<mmorrow>you mean in the sense that it takes everything else with it?
22:16:55<Cale>xian: But if not, then you can force the matter with something like...
22:16:57<mmorrow>, (0/0) * 1
22:16:58<lunabot> NaN
22:17:01<mmorrow>etc
22:17:02<mmorrow>?
22:17:03<Cale>f x = let .... in \y -> ...
22:17:07<davidL>Cale: how would you go about proving that the problem of deciding whether a turing machine is context-free is undecidable? (without appealing to rice's theorem)
22:17:26<xian>Cale: Yes, that's what I did (and it works), but I find it somewhat inelegant.
22:17:48<mmorrow>cads: i guess in a sense, but i'd hesitate to say in the same sense as `undefined'
22:17:51<Cale>xian: I think probably compiling with optimisations will do something similar.
22:18:06<cads>no, in the sense that it denotes a computation that's failed (which it does)
22:18:30<cads>but it doesn't cover computations that just wouldn't terminate
22:18:55<mmorrow>cads: if you can ever get NaN by over/underflow then i agree
22:19:06<mmorrow>(i'm not sure off the top of my head)
22:19:25<mmorrow>ie is (0/0) the only way to get NaN?
22:19:35<mmorrow>(excluding using NaN in a computation of course)
22:19:42<RayNbow>ACTION finally found some use for his gmail account: receiving and sorting mailing list messages... ^_^
22:19:43<cads>sqrt(-1) usually gives nan
22:19:52<mmorrow>ah, true
22:19:55<RayNbow>(but damn, Haskell-Cafe is way too active :p)
22:20:28<mmorrow>cads: i guess i'd say s/error/you tried to map to a number not in R/
22:20:36<mmorrow>(other than infinity)
22:20:50<Cale>RayNbow: I'm starting to consider auto-archiving all of those...
22:21:05<Cale>RayNbow: I've missed normal mail because my inbox fills too quickly.
22:21:15<RayNbow>Cale: yeah
22:21:18<Traveler8>WHATS UP
22:21:36<RayNbow>I recently found a page that showed how to setup filters/labels for mailing lists
22:21:47<Traveler8> AWSOME
22:21:55<Traveler8>WHERE
22:21:59<nimred>Cale must bootstrp.sh be run as root ?
22:22:15<Cale>nimred: I don't think so.
22:22:15<Traveler8>FUCK U MAN U SHIT
22:22:26<mwc_>if you mean bootstrap.sh to set up cabal install, then no
22:22:35<mwc_>and I would further advise you NOT to run it as root
22:22:43<RayNbow>Cale: and there's a greasemonkey script so you can have a tree view of your labels in gmail
22:23:23<RayNbow>(called Folders4Gmail)
22:23:36<nimred>mwc i get permission pb
22:24:31<Cale>nimred: hmm, it should be trying to install everything as user, but which GHC do you have?
22:24:58<nimred>Cale you ask me if i have GHC ?
22:25:22<nimred>yes i have :
22:25:22<nimred>vohfi% pkg_info | grep ghc
22:25:23<nimred>ghc-6.8.3 Compiler for the functional language Haskell
22:26:03<Cale>nimred: The bootstrap.sh script does explicitly request to install the packages as user. What permission issue are you getting?
22:26:41<mmorrow>Baughn: removing indirections is going to be needed for vacuumLazy
22:26:43<Cale>davidL: Hmm, I'm not sure.
22:27:00<Baughn>mmorrow: Right. I think I've got the right code for that, so use mine
22:27:04<mwc>Does 6.8.x's ghc-pkg honor --user? I can't remember
22:27:22<mmorrow>Baughn: making sure you not to duplicate nodes is going to be more .. interesting too
22:27:26<nimred>Cale while compiling zlib :
22:27:27<Cale>davidL: It seems to me that there might be a way to use the halting problem...
22:27:43<Baughn>mmorrow: Well.. block GCs, use reallyUnsafePointerEquality?
22:27:45<Cale>mwc: I think so. It just wasn't the default then.
22:27:50<nimred>Error during cabal-install bootstrap:
22:27:54<nimred>Building the zlib package failed
22:28:02<nimred>oups
22:28:18<Cale>nimred: Do you have the headers etc. for the C zlib library installed?
22:28:22<nimred>sorry
22:28:24<RayNbow>Cale, http://xs539.xs.to/xs539/09222/gmail-mailinglists838.png :)
22:28:25<mmorrow>Baughn: vacuum already does essentially that, so it'd just be a matter of not adding indirection nodes to the graph, and then following their children
22:28:35<Cale>RayNbow: cool
22:28:41<nimred>it in fact is : "ld: cannot find -lgmp"
22:28:47<Cale>nimred: aha
22:28:48<mmorrow>(and inserting the children as if they were the indirection node)
22:28:59<Baughn>mmorrow: Hang on, it does that /now/?
22:29:11<nimred>Cale :P
22:29:13<Cale>nimred: That's a bit surprising, as it's a dependency for GHC too.
22:29:14<Baughn>mmorrow: What happens if evaluating some structure takes lots of memoery?
22:29:15<mmorrow>Baughn: no, now it adds nodes regardless of closure type
22:29:31<Cale>nimred: But anyway, you should install libgmp and its development files.
22:29:31<xian>Cale: I can't seem to figure out what optimization flag might be responsible for the kind of optimization you mentioned above. Do you know which one I may have to turn on?
22:29:45<mmorrow>Baughn: it sucks up the entirety of the structure now
22:29:46<Cale>xian: Does -O2 work?
22:29:53<nimred>libgmp ?
22:29:57<Cale>xian: If not, then I suppose there's no cure but to write it that way.
22:30:07<Baughn>mmorrow: I mean, if you block GCs.. some evaluations end up with a small structure, but use lots of memory to construct it
22:30:10<Cale>nimred: It's used for the Integer type.
22:30:21<Cale>nimred: It's an arbitrary precision arithmetic library.
22:30:30<Baughn>mmorrow: I'd think it'd be safer to first walk the tree with GC /on/, and then redo it to construct your graph, only then turning it off
22:30:31<mmorrow>Baughn: (there was a mysterious segfault that'd occur if everything wasn't forced which i just found the reason behind last week or so)
22:30:50<nimred>Cale ok thanks for your help
22:30:57<nimred>i am compiling gmp
22:31:28<nimred>looks like it will take some time...
22:31:47<xian>Cale: Okay, I see. Then I'll have to resort to writing that function in an awkward way. Thanks for your assistance.
22:32:04<mmorrow>Baughn: i think it's going to be interesting figuring out how to best walk the graph without forcing :)
22:32:20<Baughn>Have fun. :P
22:33:55<nimred>Cale : ach doesn't work neither
22:34:00<nimred>still getting the same message
22:34:37<mmorrow>Baughn: (the reason for the segfault was that the bytecode assembler creates info tables that are specialized, and the reference to those infotabs only exist until that constructor is forced for the first time (globally). so the "fix" is check whether the # of ptrs/lits the infotable (gotten from a Storable instance) says there are is a sane number (bytecode assembler-constructed itables happen to claim to have somehting like 11172634 p
22:34:38<mmorrow>trs and lits when viewed through the regular infotab storable instance))
22:35:34<mmorrow>(by "specialized" i mean have a different layout completely)
22:35:35<Baughn>mmorrow: ..I salute the utter horror of that solution. It is truly worthy of RTS hackery.
22:35:39<mmorrow>err, not completely
22:35:45<mmorrow>Baughn: heh
22:37:25<Peaker>What are "bags"? Data structures that are mentioned in "Taste of Haskell"?
22:37:51<Baughn>Multi-sets?
22:38:12<Peaker>ah, like maps to element counts or histograms?
22:38:40<Baughn>More like maps to lists of elements
22:38:57<Baughn>I've seen a few different definitions of "bag", though.
22:39:08<Cale>xian: You might also choose to use 'where' which should work just as well
22:39:13<Cale>xian: like...
22:39:36<Cale>xian: f x = g where <other constants>; g y = ...
22:39:41<Baughn>Peaker: Sort of Map k [k], assuming that Eq is sometimes "mistaken"
22:39:47<Baughn>Peaker: Or, rather, Ord
22:40:01<Cale>xian: maybe a little prettier :)
22:40:30<Cale>nimred: That message means that libgmp isn't found in your library path.
22:40:32<Peaker>Baughn: ah
22:40:40<Cale>nimred: So I don't know what to tell you.
22:40:46<Baughn>Peaker: Otherwise you could use Map k Int, sure
22:41:05<Baughn>Map k Natural?
22:41:05<wli>I use Map k Integer
22:41:10<Cale>I usually think of Map k Natural or Map k Integer
22:41:15<Baughn>ACTION tends to assume 64-bit for some reason
22:41:25<Baughn>I'd probably use Map k Word64
22:41:31<Cale>I hate the Int type and wish it would go away.
22:41:32<Cale>hehe
22:41:44<Cale>Stupid premature optimisation :)
22:42:40<Baughn>Cale: "Don't prematurely optimize" is one thing
22:42:45<Cale>Well, mostly the problem is all the Prelude functions which produce or require Int
22:43:02<Baughn>Cale: I also like to follow "Don't bother *not* optimizing if the optimized version is no more code, no more complex, and is staggeringly obvious"
22:43:08<Cale>Which means I have to explicitly stick fromIntegral in there or use the generic* things from Data.List
22:43:11<RayNbow>hmm, Data.MultiSet uses type Occur = Int...
22:43:17<Peaker>my friend is learning Haskell and just complained that he has to sprinkle fromIntegral everywhere because of Ints in the Prelude
22:43:25<Cale>Baughn: I usually need/want Integer
22:43:32<Baughn>RayNbow: Well, that's just wrong. You can very easily overflow it on a 32-bit system
22:43:51<RayNbow>Baughn: don't tell me, tell twanvl :p
22:44:15<Baughn>twanvl: You can very easily overflow a 32-bit Int. Don't use it for multiset occurences. Geez.
22:44:26<Cale>and all the occurrences of Int mean that I can't rely on the fact that Integer is the default numeric type
22:44:42<RayNbow>(but 32 bits ought to be enough for everyone :p)
22:44:46<RayNbow>ACTION hides
22:45:00<FalconNL>I don't suppose there's an easier implementation for the function getModuleSource :: String -> IO String than downloading it off Hackage?
22:45:17<Baughn>FalconNL: Nope
22:45:29<Cale>FalconNL: That's about all you can do apart from checking if it's in the cabal cache.
22:45:33<Baughn>There's no reason to think your system even has a copy of the source
22:45:45<Baughn>*Faster* implementations, sure. Easier, no. ;)
22:46:11<Cale>Even if it is in the cabal cache, you'll still have to unpack it.
22:46:16<FalconNL>Figured as much. Out of curiosity, what would the faster implementation be?
22:46:34<Baughn>FalconNL: Checking the cache.
22:46:38<Cale>FalconNL: Checking if it's already in ~/.cabal/packages/hackage.haskell.org
22:47:12<Cale>But even if it does happen to be there, it'll still be in a .tar.gz
22:47:35<Cale>Maybe Cabal has a way to manage the cache...
22:48:00<FalconNL>I'll stick with downloading for now. Now to figure out how to download a file with Haskell...
22:48:00<Baughn>A .tar.gz is what you'd get from Hackage too
22:48:14<Peaker>can one implement co-routines on top of callCC (ala stackless Python tasklets/etc)? I want to demonstrate the power of monad transformers
22:48:30<Baughn>FalconNL: I'd go with "cabal fetch"; then you /know/ it'll be in the cache.
22:49:16<FalconNL>heh. Gotta love hackage. Searching for "download" reveals the package named download. That should do nicely :)
22:49:43<Baughn>..cabal fetch...
22:50:03<Cale>Yeah, I agree, cabal fetch followed by looking in the cabal cache is a better idea.
22:50:27<Philonous>FalconNL: download depends on linux' c-lib if I remember correctly
22:50:49<Cale>HTTP would be the normal package to use for that...
22:50:59<FalconNL>Philonous: yeah, I noticed. I'll try cabal fetch instead.
22:54:51<nimred>Cale well i have to go to bed. see you tomorrow. thanks for your help :)
22:55:22<altmattr>I have hit what I think is essentially the expression problem
22:55:23<altmattr>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2501#a2501
22:55:34<FalconNL>Hm. "cabal fetch base" results in "cabal: internal error: impossible".
22:55:36<altmattr>I have written up a little example specific to my problem
22:55:47<altmattr>can I get any suggestions for the best way thru?
22:56:41<altmattr>I am sure just about everyone here has had the same problem
22:56:42<altmattr>:)
22:59:37<FalconNL>Does anyone know why base would not be cabal-fetchable?
23:00:04<altmattr>FalconNL: fraid not, it sounds like cabal doesn't know either
23:00:04<pumpkin>is it on hackage?
23:00:23<FalconNL>pumpkin: yeah, it's the package that contains the Prelude
23:00:34<pumpkin>well, I know the package contains that
23:00:37<pumpkin>but I didn't know it was on hackage
23:00:44<pumpkin>I mean, rts is a package too
23:00:46<pumpkin>as is ghc
23:00:54<pumpkin>but they're not "real"
23:01:12<sjanssen>FalconNL: 'cabal install base' is intentionally disabled
23:02:13<sjanssen>FalconNL: perhaps fetch was also disabled by mistake or conservative programming
23:02:18<MyCatVerbs>sjanssen: ahahaha, that would break in so many fun ways. :3
23:02:29<FalconNL>sjanssen: Wonderful. Guess it's back to downloading off Hackage, since the Prelude is one of the more important modules I need the source from.
23:02:47<pumpkin>@hackage base
23:02:47<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/base
23:02:56<pumpkin>ah, cool
23:03:04<pumpkin>@hackage rts
23:03:04<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rts
23:05:41<altmattr>All-right, how about a rephrased version?
23:05:42<altmattr>What is best practice for adding a new field to an existing constructor without rewriting every function over that constructor (or at least minimising the pain)?
23:06:06<pumpkin>use {}
23:06:39<pumpkin>if you had case x of Constructor _ _ _ -> ... use case x of Constructor{} -> ...
23:06:43<Peaker>gtk2hs is not cabalized?
23:06:52<pumpkin>naming the constructor fields helps if you actually need the values
23:07:05<pumpkin>Peaker: I heard it was too complicated to build for cabal
23:07:09<pumpkin>at least in its current state
23:07:38<Phyx->ahh, taking a step back and reading the code does help :)
23:07:57<altmattr>pumpkin: you just made my jaw drop - I didn't even know you could do that!
23:08:05<altmattr>how did I miss that?
23:08:57<pumpkin>I only came across it recently, can't remember where
23:09:22<altmattr>now I am off to rewrite every pattern matching function I ever wrote
23:09:25<Peaker>pumpkin: cabal lets it have its own build executables?
23:10:45<Phyx->@type (*** id)
23:10:46<lambdabot>forall b c b'. (b -> c) -> (b, b') -> (c, b')
23:11:13<Phyx->@type (*** id) (++"-")
23:11:14<lambdabot>forall b'. ([Char], b') -> ([Char], b')
23:11:18<goalieca2>is there no ubuntu 9.04 package for cabal? it is not in haskell-utils and it doesnt come up in a repo search
23:11:25<pumpkin>Peaker: yeah, but I guess they decided it wasn't worth cabalizing if all the work was going to be done by configure and make? not sure
23:11:40<Phyx->@type (*** (++"-")) id
23:11:41<lambdabot>forall c. (c, [Char]) -> (c, [Char])
23:11:45<Phyx->ah
23:11:47<Phyx->that's the one
23:11:56<Peaker>pumpkin: at least get deps?
23:12:10<pumpkin>Peaker: beats me :) that's just what I heard
23:12:17<Phyx->arrow is really handy
23:12:27<Twey>Sometimes
23:12:33<Twey>Not very often, though, alas
23:12:36<Phyx->hehe
23:12:46<pumpkin>I find it useful pretty often!
23:12:50<pumpkin>it got my par down to 3
23:12:57<Phyx->hmm this doesn't look so nice... a function with 8 class constraints
23:13:13<pumpkin>Phyx-: http://blog.omega-prime.co.uk/
23:13:20<Phyx->ACTION looks
23:13:41<Phyx->oh that's nice
23:13:45<Phyx->thanks :)
23:13:55<Phyx->i can clean up qute a bit with that
23:14:32<Peaker>pumpkin: what's "context" ?
23:15:24<Phyx->hmm seems to be just a proposal at this point pumpkin ?
23:15:27<Phyx->too bad :(
23:16:19<ray>peaker: context is what's behind that link
23:17:10<Phyx->I like the proposal though
23:17:40<ray>i've decided instance (Lots, Of, Different, Classes, At, Once) Foo where ... would be cool
23:17:45<Peaker>ray: I directly skimmed to code examples, without reading the top :) It sounds like class aliases
23:18:10<ray>the first bit is
23:18:48<ray>(and of course, substituting a class alias for that thing in parentheses should work)
23:19:24<Phyx->union dataK dataB :: [Buchi (Integer, [Char]) [Char]] <-- atleast it type checks :)
23:20:13<Phyx->"[*** Exception: Prelude.undefined" <-- always hate these errors
23:20:16<Phyx->now where is it..
23:20:50<Cale>Phyx-: are you explicitly using undefined somewhere?
23:21:00<Twey>Phyx-: C-s undefined
23:21:12<Twey>undefined is the new TODO
23:21:19<Phyx->Cale: i used them to get a stub working, but i should have removed them by now i think
23:21:25<Cale>ah :)
23:21:39<Twey>But perhaps we should stick with TODOs for a while, in case of explicit undefineds...
23:21:53<Cale>error would be a little better
23:22:02<Cale>since then at least you'd know which one :)
23:22:09<Phyx->found it, heehe
23:22:11<Twey>foo = error "NIH"
23:22:12<ray>TODO can be an empty data declaration
23:22:17<Phyx->i had a boilerplate let code
23:22:32<Phyx->quick question
23:22:35<Twey>ray: How do you mean?
23:22:43<ray>data TODO
23:22:52<Phyx->why didn't this spit out a "redifining variable 'e'" error?
23:22:53<Phyx-> e@(e1,e2) <- ask
23:22:53<Phyx-> let e = undefined
23:22:55<ray>with a ghc extension enabled
23:22:57<Twey>But how would we use it?
23:23:06<Phyx->i had the second by accident
23:23:11<Twey>Phyx-: It will simply shadow it
23:23:12<Cale>Phyx-: Because shadowing isn't normally something it warns about
23:23:17<ray>then, you could write functions like [(a,b)] -> TODO
23:23:41<Twey>It will only warn (or was it an error?) about redefining if you do it in the same let block, I think
23:23:55<ray>where TODO is a Map-like data structure you haven't written yet
23:23:58<Phyx->i could swear i used an interpreter before that warned about shadowing
23:24:00<Phyx->hmm
23:24:02<ray>your code won't compile, and you'll remember to implement it
23:24:03<Twey>ray: But then the types would be different
23:24:14<Cale>Phyx-: if you set -Wall I think it will warn
23:24:16<ray>that's the idea
23:24:18<Twey>The idea is to get the code to compile so we can make sure it type-checks
23:24:27<Twey>Before implementing
23:24:38<Cale>But -Wall is annoying :P
23:24:43<Phyx->Cale: ah, lol
23:24:49<Phyx->was it on at some version of ghci?
23:24:53<Phyx->by default i mean
23:24:55<Cale>I don't know.
23:24:56<ray>that's the idea of undefined
23:25:04<ray>my idea is different
23:25:12<ray>and forces you to remember to implement stuff
23:25:23<ray>unless you use undefined in conjunction with it
23:26:02<Cale>ray: I think the point is that he wanted to load the code in ghci, and so stubbed some stuff out with undefined.
23:26:20<Cale>ray: If you want it not to compile, you can just fail to write it altogether :)
23:26:23<ray>yeah, that's totally different from my crazy idea, it just happened to inspire it
23:26:25<Twey>Wow, -Wall really is annoying.
23:26:37<Phyx->hm. why does foldl1 return an exception when the list is empty? i was expecting an empty list
23:26:45<Twey>It warns about missing type signatures :(
23:26:53<Cale>Phyx-: Because... that's the point of it
23:26:56<ray>well, i want to write the function body and the type signature, but not define the return type :)
23:26:56<Twey>Phyx-: Because it needs the first element
23:27:03<Cale>:t foldl
23:27:04<Cale>:t foldl1
23:27:05<lambdabot>forall a b. (a -> b -> a) -> a -> [b] -> a
23:27:05<ray>you want foldl
23:27:06<lambdabot>forall a. (a -> a -> a) -> [a] -> a
23:27:09<lament>why would fold return a list?
23:27:37<Cale>You only use foldl1 when the function you're writing makes no sense for an empty list.
23:27:48<Phyx->aha
23:27:59<Phyx->lament: when you're folding over [[a]]
23:28:21<Cale>Since it's polymorphic, it can't do anything different in the list case than in any other.
23:28:36<Phyx->hmm
23:29:09<Phyx->aha
23:29:09<hackagebot>Hieroglyph 2.23
23:29:09<Phyx->works
23:29:17<ray>lots of languages throw around the word "polymorphic", but only haskell throws around "monomorphic" too
23:29:40<FalconNL>Well that's nice: the example in http://hackage.haskell.org/packages/archive/HTTP/4000.0.5/doc/html/Network-HTTP.html fails with "openFile: does not exist (No such file or directory)". Is the example wrong or am I missing something?
23:29:45<Cale>That use of monomorphism is really confusing to me.
23:30:01<Cale>Because it conflicts with the standard meaning in mathematics.
23:30:25<Cale>Or it was, I'm pretty much used to it by now :)
23:30:55<ray>yeah, it's monomorphism the adjective not monomorphism the noun
23:31:09<ray>er
23:31:09<kniu>Since haskell has Data.Map, couldn't record types be implemented with Template Haskell, since they're just maps of names to values and their types?
23:31:13<ray>i think i'm right
23:31:21<Cale>I think so too.
23:31:36<mmorrow>Cale: heh, i thought the monomorphismrestriction had to do with some sort of injective mapping for the first while when i was learning haskell
23:31:55<Cale>kniu: Not with the same syntax.
23:32:01<Cale>mmorrow: me too
23:34:26<Cale>kniu: You could perhaps approximate the record syntax by constructing a plain algebraic type along with such a mapping, and then do lots of quasiquoter manipulations...
23:35:15<Cale>Seems like a troublesome thing to do, anyway.
23:35:39<pumpkin>damn overloaded words
23:36:17<kniu>Cale, I thought Template Haskell allowed you to do all sorts of crazy stuff with the syntax.
23:37:23<Cale>Not really. splices always look like $( ... ) where what's inside the parens is some code which evaluates to a Haskell syntax tree.
23:37:27<EvilTerran>kniu, template haskell is pretty noisy, it's not really changing the syntax
23:37:43<kniu>huh.
23:37:53<Cale>Though we now have a quasiquoter syntax which lets you do arbitrary parsing, but you still need a surrounding bracket.
23:38:10<EvilTerran>[$qqName| ... |], at that
23:38:47<FalconNL>Does anyone know any reasons why the first example in http://hackage.haskell.org/packages/archive/HTTP/4000.0.7/doc/html/Network-HTTP.html could fail?
23:38:48<Twey>http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=2502#a2502 — why is this considered non-exhaustive?
23:39:32<Twey>I would have thought it exhaustively covered by the x (y : z) pattern
23:39:36<Twey>(the ones it mentions)
23:39:46<Twey>And the one about not matching _...
23:40:16<Cale>Heh, I think the pattern match exhaustiveness checker is sort of broken
23:40:38<Twey>Is it not covering that because I've specified guards?
23:40:38<Cale>That, or it just doesn't like your crazy moon-language.
23:40:46<Zao>What about fanva "h"?
23:40:48<Twey>Haha
23:40:57<Cale>oh, maybe it can't tell that the guards are exhaustive?
23:41:14<Twey>Zao: Gets caught by (lerfu : loilErfu) | not $ isAlphaNum lerfu
23:41:26<Zao>Twey: But it's alpha.
23:41:37<Twey>ACTION blinks.
23:41:39<Twey>Point
23:41:56<Twey>ACTION nodnods.
23:42:16<Cale>I don't know how it would figure that out though.
23:42:46<Cale>It would either have to assume that the guards always fail or that one of them always succeeds... I don't think it's smart enough to really tell.
23:43:15<Twey>I would suspect it considers them incomplete if there's no ‘otherwise’
23:43:25<Cale>yeah, maybe that's it
23:43:36<Twey>After adding one, it seems okay with it
23:43:53<Twey>And I can feel elitist pride at getting -Wall to accept my measly code
23:46:41<Cale>Twey: hopefully after the other case though...
23:46:51<Twey>Other case?
23:47:01<Cale> fanva (zunsna : karsna : loilErfu) =
23:47:03<Twey>Oh, yes
23:47:06<Twey>I switched them :)
23:47:10<Cale>ah
23:47:48<Twey>The order of patterns and their matches can get quite delicate in complex use cases
23:48:43<MyCatVerbs>What language of variable name are zunsna, karsna and liolErfu?
23:48:59<Twey>loi**
23:49:00<MyCatVerbs>AIEEEE
23:49:01<Twey>Lojban
23:49:10<Twey>ACTION blinks.
23:49:12<MyCatVerbs>Ah, oops. Thanks.
23:49:18<Twey>Usually the screaming happens *after* I mention that it's Lojban.
23:49:27<MyCatVerbs>Not that, pumpkin.
23:49:32<Twey>Ohh.
23:49:35<Twey>A Thwog.
23:49:44<MyCatVerbs>The Thwog, apparently.
23:49:48<MyCatVerbs>I'm scared that he might try to help us.
23:49:57<Thwog>No.
23:50:14<MyCatVerbs>Phew.
23:50:19<Twey>Yes, I'm trying to work out a set of conventions that adhere to both Lojban and Haskell requirements
23:50:43<Twey>Luckily, Lojban allows word-demarcation by stress, so no separators are required
23:50:55<Twey>And Haskell allows ' in names, which is also very cool.
23:51:03<Thwog>no it doesn't
23:51:16<Twey>Thwog: Haskell disagrees.
23:51:23<Thwog>yeah, but I'm incompetent
23:51:26<Twey>> let ' = "foo" in '
23:51:27<lambdabot> <no location info>:
23:51:27<lambdabot> lexical error in string/character literal at chara...
23:51:28<MyCatVerbs>> let let'ssee = "whether or not it does" in let'ssee
23:51:29<lambdabot> "whether or not it does"
23:51:30<Twey>Aw.
23:51:34<Twey>Not there, apparently.
23:51:42<Thwog>http://thwog.kyth.org/Book_of_Thwog/book_of_thwog.html
23:51:59<MyCatVerbs>> let 'avaunt = "I can't remember what this word means" in "bacon"
23:52:00<lambdabot> <no location info>:
23:52:00<lambdabot> lexical error in string/character literal at chara...
23:52:05<MyCatVerbs>Not there, either. :3
23:52:40<Twey>thou: Bahaha
23:52:48<Twey>MyCatVerbs: It thinks it's a character literal
23:53:13<MyCatVerbs>Twey: yes, I can read the error message. ;P
23:53:15<Twey>Which is kind of silly — it should really be obvious that it isn't
23:53:21<MyCatVerbs>Erk!
23:53:41<Twey>A character literal will always be of the form '<char>' or '\<char>'
23:53:56<Twey>I guess it requires backtracking, though. Do we avoid that?
23:54:22<MyCatVerbs>"It should be really obvious that..." <- no, please no. I like my parsers to be as simple as possible. The simpler the parser, the easier it is to understand why it is barfing on some given piece of text.
23:54:25<Cale>> '\SOH'
23:54:27<lambdabot> '\SOH'
23:54:33<MyCatVerbs>Yes, we avoid that as much as possible.
23:54:33<Phyx->hrm... my trace statements became impressively useless since ghc reordered them
23:54:34<Phyx->lol
23:54:40<Twey>MyCatVerbs: Heh, okay.
23:54:41<MyCatVerbs>Heehee. "avaunt - interjection - [archaic] begone! go away! (N.B. useful for telemarketers)"
23:54:57<Cale>> "\SO" ++ "H"
23:54:59<lambdabot> "\SO\&H"
23:55:41<Twey>What does \SO mean?
23:55:56<MyCatVerbs>> chr '\SO'
23:55:57<lambdabot> Couldn't match expected type `GHC.Types.Int'
23:56:02<Twey>> "\S" ++ "OH"
23:56:03<lambdabot> <no location info>:
23:56:04<lambdabot> lexical error in string/character literal at chara...
23:56:05<MyCatVerbs>> ord '\SO'
23:56:07<lambdabot> 14
23:56:13<pumpkin>Cale: do you know why lambdabot has been giving low-level type names in errors recently?
23:56:21<Cale>Shift Out
23:56:24<Twey>Is \& a no-op?
23:56:27<pumpkin>a lot of GHC.Types.* instead of the more obvious ones
23:56:37<MyCatVerbs>"Shift Out". Which means...?
23:56:46<Cale>Twey: yeah, it's just there as a separator for that one special case :)
23:56:54<Twey>Heh
23:56:54<Peaker>I wonder if you can implement Python-like generators (yield) with ContT
23:57:00<Twey>> length "\&"
23:57:01<lambdabot> 0
23:57:03<Cale>http://en.wikipedia.org/wiki/Shift_Out_and_Shift_In_characters
23:57:14<MyCatVerbs>I sometimes wonder whether ∃ anyone on the planet who can remember what most of the control characters in ASCII mean, anyway. :D
23:57:16<Twey>Peaker: I believe you can, yes
23:57:29<Twey>Why is there an ‘exists’ in the middle of that sentence?
23:57:30<MyCatVerbs>Peaker: spoiler, you can implement Python-like generators with lazy lists. :P
23:57:38<Twey>ACTION laughs.
23:57:42<Peaker>MyCatVerbs: nope, Python generators do side effects
23:57:45<Twey>Only for pure values
23:57:49<Twey>ACTION nods.
23:58:16<MyCatVerbs>Peaker: unsafeInterleaveIO. ^^
23:58:23<Peaker>hah
23:58:28<Twey>>.<
23:58:31<Peaker>Twey: I am new to ContT, it seems like a horrible thing to ever use, but I want to get to know it and use it to write coroutines/etc so I can impress people with Haskell's mojo :)
23:59:22<Twey>Oh, it's not that horrible
23:59:36<Twey>It *can* be a bit mind-bending, but that's your responsibility :-P
23:59:39<RayNbow>btw Cale, what do you use to type Japanese? (as you did here http://www.reddit.com/r/programming/comments/8mmcu/i_tried_to_translate_the_ironpython_code_to/c09rkdu )
23:59:47<Cale>RayNbow: SCIM
23:59:52<Berengal>Continuations are not for the weak of mind
23:59:53<Cale>+Anthy
23:59:58<Peaker>Twey: it provides a "function" that never returns, and actually performs a goto/jump

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