Experimental IRC log haskell-2008-09-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:02:22<Saizan_>Igloo: yeah, i sent that, when i was unaware of the trac ticket, but it just solves the infinite recursion, not the other assumptions broken by that package
00:03:05<Igloo>Ah, OK
00:04:11<SamB_XP>isn't it just great when someone gets told about their own patch ;-) ?
00:04:32<Igloo>If you think the problems are insurmountable then can you let us know ASAP, please, and we might have to rethink shipping it?
00:05:50<Saizan_>Igloo: i don't know the dependency resolver code so well, sorry, i think dcoutts has written most of it
00:08:34<Igloo>OK, I'm sure he's on the case
00:08:49<shapr>newsham: ping
00:11:17<pastorn_>@pl \r (n,b) -> (n+1, b && (length r ==9))
00:11:18<lambdabot>(`ap` snd) . (. fst) . flip ((.) . (,) . (1 +)) . flip (&&) . (9 ==) . length
00:18:10<pastorn_>@pl \fp -> readFile fp >>= return . length
00:18:11<lambdabot>(length `fmap`) . readFile
00:18:33<pastorn_>@type (length `fmap`)
00:18:33<lambdabot>forall a (f :: * -> *). (Functor f) => f [a] -> f Int
00:18:50<newsham>shapr: hi
00:18:50<lambdabot>newsham: You have 1 new message. '/msg lambdabot @messages' to read it.
00:22:36<shapr>newsham: y0
00:24:43<pastorn_>is there any good way to make conditionals pointsfree?
00:25:02<pastorn_>ACTION can't think of any
00:26:42<Cale>pastorn_: liftM2 is usually helpful
00:26:48<SamB_XP>@pl if x == y then z else w
00:26:48<lambdabot>if' (x == y) z w
00:27:43<pastorn_>hehe
00:27:50<pastorn_>@src liftM2
00:27:50<lambdabot>liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
00:27:56<SamB_XP>but it only works if you define it ;-P
00:28:16<pastorn_>my code is going to look like shit
00:28:24<pastorn_>@type if'
00:28:25<lambdabot>Not in scope: `if''
00:28:41<FunctorSalad>pastorn_: ArrowIf represents falsity as the empty list
00:29:30<pastorn_>FunctorSalad: where? what?
00:29:40<pastorn_>it's not in Control.Arrow...
00:29:55<seydar>what *are* arrows?
00:30:01<FunctorSalad>http://hackage.haskell.org/packages/archive/hxt/8.1.0/doc/html/Control-Arrow-ArrowIf.html
00:30:01<shapr>poky things!
00:30:07<lambdabot>Title: Control.Arrow.ArrowIf, http://tinyurl.com/4hcas2
00:30:28<FunctorSalad>it's in hxt but the arrows there seem to be general-purpose
00:30:39<pastorn_>seydar: http://en.wikibooks.org/wiki/Haskell/Understanding_arrows
00:30:40<lambdabot>Title: Haskell/Understanding arrows - Wikibooks, collection of open-content textbooks
00:32:36<seydar>thank you all!
00:32:38<seydar>you all win!
00:32:39<seydar>a prize
00:33:08<FunctorSalad>in hxt everything returns a list (for example, getChildren :: IOSArrow XmlTree XmlTree)
00:33:26<FunctorSalad>so it's convenient to just let the empty list double as "false"
00:34:05<FunctorSalad>for example, getChildren >>> getText `orElse` constA "no children"
00:35:45<SamB_XP>@src Monoid
00:35:45<lambdabot>class Monoid a where
00:35:45<lambdabot> mempty :: a
00:35:45<lambdabot> mappend :: a -> a -> a
00:35:45<lambdabot> mconcat :: [a] -> a
00:37:03<SamB_XP>ACTION was thinking about saying something about mempty, only he had been thinking that it was called mzero but realized that that was (supposed to be) in MonadZero
00:46:51<pastorn_>http://hpaste.org/10685
00:47:00<pastorn_>i could use some help with that
00:47:20<pastorn_>speed is the goal here...
00:48:09<Cale>pastorn_: Is it really faster?
00:48:42<pastorn_>Cale: i don't know... i'm just avoiding nub since it's O(n^2)
00:48:53<pastorn_>or maybe it's O(n!)
00:49:12<Cale>That would be quite a bad algorithm ;)
00:49:24<Cale>It's O(n^2) worst case.
00:49:33<Cale>However, it's productive.
00:49:41<pastorn_>right
00:50:02<pastorn_>what is?
00:50:04<pastorn_>nub?
00:50:15<Cale>nub. It can operate lazily.
00:50:18<Cale>> nub [1..]
00:50:20<lambdabot> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28...
00:50:25<FunctorSalad>pastorn_: you could use a set, that would be O(n log n)
00:50:46<pastorn_>FunctorSalad: heh, the overhead might be too costsome
00:51:07<FunctorSalad>yeah
00:51:09<pastorn_>as i wrote, it's just 9 elements
00:51:23<pastorn_>though i could make myself a simple unbalanced binary tree
00:51:30<Cale>Try nub' = map head . group . sort
00:51:35<FunctorSalad>or some simple hash-table thing
00:51:38<Cale>But that will sort the elements.
00:51:55<roconnor>and requires Ord
00:52:20<pastorn_>please annotate your suggestions :)
00:52:24<Cale>Are you sure that the obvious code using nub is really too slow?
00:52:43<pastorn_>Cale: no, that's more of a guess
00:53:00<Cale>pastorn_: Note that the code you wrote has essentially the same complexity as the code with nub.
00:53:02<roconnor>what is slow is never what you think :P
00:53:21<roconnor>ACTION shakes his fist at rotate
00:53:27<newsham>> nub "premature optimization"
00:53:28<Cale>In fact, it almost does the same thing as nub.
00:53:28<lambdabot> "prematu oizn"
00:53:57<pastorn_>newsham: actually not, this is like the 10th time i'm doing this lab
00:54:15<newsham>> unnub "prematu oizn"
00:54:15<lambdabot> mueval: Prelude.read: no parse
00:54:20<pastorn_>i'm trying to make all my functions be as fast as possible
00:54:55<newsham>it cant be that fast if its your 10th time.
00:55:04<newsham>how many hours has it taken already?
00:55:12<pastorn_>newsham: has what taken?
00:55:20<newsham>the 9 other times
00:55:45<pastorn_>heh, this is one of the first labs that the students that arrive at CS at chalmers get to do
00:56:20<pastorn_>it's good training on working with lists
00:56:25<pastorn_>http://www.cs.chalmers.se/Cs/Grundutb/Kurser/funht/lab3.html
00:56:29<lambdabot>Title: Introduction to Functional Programming -- Lab 3
00:56:40<pastorn_>this is D1
00:57:25<newsham>i like this one http://web.math.unifi.it/users/maggesi/haskell_sudoku_solver.html
00:58:07<hackage>Uploaded to hackage: graphmod 1.1.2
00:59:31<ivanm>http://www.reddit.com/r/programming/comments/73hqm/does_literate_programming_help_you_in_what_way/c05kt12 <-- how is haskell literate programming not "real" literate programming?
00:59:33<lambdabot>Title: jerf comments on Does Literate Programming help you? In what way?, http://tinyurl.com/4ouxtz
00:59:39<luqui>Does anyone recognize a functor m with an operation of type: m (m a -> a)
00:59:50<luqui>is this equivalent to monad?
00:59:59<dibblego>looks a bit like a comonad
01:00:04<luqui>(looks like join... but I can't see how)
01:00:24<pastorn_>@pl \xs -> let ys = filter isJust xs in ys == nub ys
01:00:24<lambdabot>ap (==) nub . fix . const . filter isJust
01:00:40<pastorn_>@type const
01:00:41<lambdabot>forall a b. a -> b -> a
01:02:44<pastorn_>@type ap
01:02:45<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
01:03:28<pastorn_>how is ([a] -> [a]) a monad?
01:03:28<cjb>hm, want to write something in haskell
01:03:34<cjb>don't know what to write.
01:03:38<cjb>this happens a lot. :)
01:03:42<pastorn_>cjb: project euler?
01:04:05<pastorn_>@src ap
01:04:06<lambdabot>ap = liftM2 id
01:04:07<luqui>pastorn, it's not even functor
01:04:08<cjb>maybe, but I meant something that other people might want to use or be interested in afterwards
01:04:12<bjrn>New Project Euler problem tomorrow :)
01:04:15<dibblego>pastorn, forall t. ((->) t) is a monad since you can write it :)
01:04:46<pastorn_>dibblego: i tried understanindg ((->) a) once
01:04:50<pastorn_>didn't
01:04:57<dibblego>(t -> a) -> (b -> t -> b) -> t -> b
01:05:02<dibblego>oops
01:05:05<dibblego>(t -> a) -> (a -> t -> b) -> t -> b
01:05:08<luqui>pastorn, do you know about Reader?
01:05:27<pastorn_>dibblego: how might i end up with something like ((->) a)?
01:05:32<pastorn_>luqui: no
01:05:48<dibblego>pastorn, that's a type constructor on its own; it just so happens that it is also a monad
01:05:51<pastorn_>it's not partial application, is it?
01:05:56<luqui>dibblego, I prefer join for that one, actually. join :: (t -> t -> a) -> (t -> a); join f t = f t t.
01:06:04<dibblego>it's a partially applied type argument, yes
01:06:05<ddarius>pastorn: http://hpaste.org/10685#a1
01:06:31<luqui>you can think of it like (a ->), or \x -> (a -> x)
01:06:34<luqui>(type lambda)
01:06:50<pastorn_>ddarius: i like that!!
01:06:52<pastorn_>smart
01:07:06<pastorn_>Data.Bits usually doesn't feel very haskell-y
01:07:53<pastorn_>luqui: \x -> (\a -> x) ?
01:08:32<luqui>pastorn_, oh, no. the left arrow is the arrow from a lambda, as in (\x -> x + 1), the right arrow is *different*, it's the arrow for a type, as in Int -> Int.
01:08:43<luqui>but there are no type lambdas anyway, it's just a way to think.
01:09:14<pastorn_>i'm feeling that there's some fundamental thing here that i don't know about...
01:09:40<luqui>at least you know you don't know. next step is to know *what* you don't know :-)
01:10:46<luqui>pastorn_, ok, so the ((->) a) (a.k.a. Reader) monad just puts the entire computation under an assumed argument a.
01:10:59<pastorn_>huh?
01:11:04<pastorn_>what computation?
01:11:10<luqui>the monadic one...
01:11:22<pastorn_>where did that come from?
01:11:28<pastorn_>ACTION gets dizzy
01:11:30<luqui>so say you have: do { x <- foo; return (x+1) }
01:11:38<luqui>be patient :-)
01:11:43<pastorn_>ah, that's more like it!
01:11:59<luqui>let's give it a name. bar = do { x <- foo; return (x+1) }
01:12:17<luqui>this is the same as: bar a = let x = foo a in x + 1.
01:12:22<luqui>see the correspondence?
01:13:15<pastorn_>well, foo in the do-function doesn't take an argument, but i get it
01:13:25<luqui>likewise, do { x <- foo; y <- baz x; return (x+y) } becomes \a -> let x = foo a in let y = baz x a in x + y
01:13:39<luqui>pastorn_, that's *exactly* it, it does take an argument
01:14:00<luqui>because foo :: m Int, and m is (a ->), so foo :: a -> Int
01:14:55<pastorn_>hang on... still writing down that second do-function
01:15:38<luqui>ok. just note how it takes a parameter a, and then sends that parameter to each subcomputation (foo, baz, ...)
01:17:44<pastorn_>naaah, but see, how could i pass an argument to foo in bar
01:17:48<pastorn_>bar = do
01:17:49<pastorn_> x <- foo
01:17:49<pastorn_> return (x+1)
01:18:30<pastorn_>if any argumenst would be passed into bar they'd end up in the return statement
01:18:57<pastorn_>so maybe if i gave it something like (. (+20)) then it would be ok...
01:19:06<luqui>hmm, not quite sure what you're saying.
01:19:30<pastorn_>bar = foo >>= \x -> return (x + 1)
01:19:44<pastorn_>so how can i give argumenst to foo?
01:19:54<luqui>well what is the type of foo?
01:20:00<pastorn_>m Int
01:20:03<luqui>and what is m?
01:20:10<pastorn_>dunno
01:20:20<luqui>we're talking about the ((->) a) monad right?
01:20:39<pastorn_>might be Maybe, might be List or IO... what do i know?
01:21:00<luqui>those are all monads. so is ((->) a)
01:21:13<luqui>so yeah, bar works on whatever monad foo is in.
01:21:29<pastorn_>yeah
01:21:38<luqui>but since we're trying to understand reader (or ((->) a)), let's assume foo is in that one
01:21:43<lispy>bar y = foo x >>= \x -> return (x + 1)
01:21:59<pastorn_>ooookay?
01:22:02<luqui>lispy, what?
01:22:12<lispy>18:18 <pastorn_> bar = foo >>= \x -> return (x + 1)
01:22:12<lispy>18:18 <pastorn_> so how can i give argumenst to foo?
01:22:12<luqui>so m = ((->) a)
01:22:16<lispy>(I was answering that)
01:22:36<luqui>so then what is the type of foo, which was m Int ?
01:22:50<pastorn_>did you do a typo there?
01:22:56<pastorn_> bar y = foo x >>= \x ...
01:23:02<lispy>oh yeah foo y
01:23:04<lispy>sorry
01:23:27<lispy>bar y = foo y >>= \x -> return (x + 1)
01:23:51<luqui>right, which is certainly legal, and to be clear has nothing to do with our monad.
01:23:59<pastorn_>luqui: ok... foo :: ((-> a) Int)
01:24:15<luqui>well, modulo the typo you just made, yeah :-)
01:24:29<luqui>foo :: ((->) a Int)
01:24:38<luqui>which just means: foo :: a -> Int
01:25:00<pastorn_>heh, so type arrows can be prefix? kinda cool...
01:25:25<luqui>yeah that's the hack that makes it possible for -> to be a monad :-)
01:25:27<lispy>:t id :: ((->) a a)
01:25:29<lambdabot>forall a. a -> a
01:25:41<pastorn_>heh
01:25:52<lispy>:t [1] :: [] Int
01:25:54<lambdabot>[Int]
01:26:01<lispy>That one can be prefix too
01:26:03<pastorn_>luqui: so what kind of function is foo then?
01:26:16<luqui>pastorn_, any kind. one that takes an a.
01:26:19<pastorn_>does it take an argument of type a and produce an Int?
01:26:23<luqui>in this monad, "actions" are just functions from a.
01:26:29<luqui>yes
01:26:29<pastorn_>or is foo in itself a function from a to Int?
01:26:36<luqui>uh... both?
01:26:39<pastorn_>ok
01:27:08<pastorn_>lemme guess...
01:27:43<pastorn_>return :: (a -> m a); return x = \_ -> x
01:27:49<lispy>f >>= g = do { a <- ask; b <- f a; return (g b) } -- I think this is bind
01:27:49<pastorn_>or?
01:27:54<luqui>> (do { x <- (+1); return x }) 41 -- odd demonstration. (+1) :: Int -> Int, so (+1) :: m Int for our m
01:27:56<lambdabot> 42
01:27:59<luqui>pastorn_, exactly!
01:28:00<pastorn_>gah!!
01:28:05<pastorn_>not su much!!
01:28:09<pastorn_>chill
01:28:51<luqui>lispy, what are you talking about?
01:29:09<lispy>luqui: isn't that how Reader ((->) a), defines (>>=) ?
01:29:29<luqui>lispy, you mean in terms of do notation, which is itself defined in terms of >>=.
01:29:33<pastorn_>let f = do {x <- (+1); return x}
01:29:34<pastorn_>Prelude> :t f
01:29:34<pastorn_>f :: Integer -> Integer
01:29:34<luqui>doubtful :-)
01:29:44<pastorn_>hmmm... I MIGHT be onto something here...
01:29:49<vininim>@instances (>>=)
01:29:50<lambdabot>Couldn't find class `(>>=)'. Try @instances-importing
01:30:00<lispy>luqui: um...I didn't mean how is it implemented, just how it's semantically defined
01:30:00<vininim>uh
01:30:11<vininim>@src (>>=)
01:30:12<lambdabot>Source not found. :(
01:30:13<lispy>?undo do { a <- ask; b <- f a; return (g b) }
01:30:14<lambdabot>ask >>= \ a -> f a >>= \ b -> return (g b)
01:30:28<luqui>m >>= f = \x -> f x (m x)
01:30:38<luqui>that's what it means and how it is implemented :-)
01:31:02<luqui>wait I might be confusing that with <*>...
01:31:11<luqui>m >>= f = f (m x) x
01:31:14<lispy>Doesn't Reader ((->) a), need to call ask?
01:31:16<luqui>that's the one :-)
01:31:23<luqui>ugh, with a \x -> in front
01:31:24<pastorn_>hang on here... in (>>=) f :: (a -> m b)
01:31:57<luqui>lispy, oh, if you do it the newtype way; i.e. Reader r a = Reader (r -> a), and define ask = Reader id, then yeah
01:32:17<luqui>we're working directly on ((->) a) though, which is the same thing without the newtype
01:32:53<pastorn_>m (:: m a) >>= f (a -> m b)= \x (:: ?) -> f x (m x) (:: m b, somehow...)
01:33:35<luqui>(m :: r -> a) >>= (f :: a -> (r -> b)) = \(x :: r) -> f x (m x) :: r -> b
01:33:48<luqui>I just replaced m with r ->, which is what it is in this case
01:34:21<Olathe>In "class BuildList a r | r -> a where", what does "| r -> a" mean ?
01:34:21<luqui>oh, but not \x -> f x (m x), that was wrong. it's \x -> f (m x) x
01:35:00<luqui>Olathe, that's a functional dependency. see haskell wiki
01:35:00<bjrn>Olathe: http://www.haskell.org/haskellwiki/Functional_dependencies
01:35:02<lambdabot>Title: Functional dependencies - HaskellWiki
01:35:08<Olathe>Thanks :)
01:35:42<pastorn_>weird
01:36:03<thoughtpolice>Olathe: it basically means if you have BuildList TyA TyB, you can not also have BuildList TyA TyC -- TyA uniquely determines TyB, always
01:36:15<thoughtpolice>so it establishes a relation for any two types
01:36:26<pastorn_>let f = do {x <- (+1); return x} <-- this works and f :: Integer -> Integer
01:36:29<pastorn_>but
01:36:45<pastorn_>x <- (+1) doesn't work
01:36:54<thoughtpolice>Olathe: personally I think assoc. types are easier to grok
01:37:09<Olathe>thoughtpolice: Ahh, OK :)
01:37:14<Olathe>Hmm, never heard of those.
01:37:23<Olathe>Then again, I'm very new to type theory.
01:37:42<Olathe>Functional dependencies seem very nice.
01:40:25<thoughtpolice>i never knew what fundeps really meant for the longest time
01:40:39<thoughtpolice>but i like associated types because they are more functional in nature than a fundep
01:41:49<thoughtpolice>and with ghc 6.10 they should be pretty much fully go
01:42:08<Olathe>Is there a page on associated types ?
01:42:18<Olathe>I searched, but it didn't seem to find one.
01:42:19<thoughtpolice>http://haskell.org/haskellwiki/GHC/Type_families
01:42:21<lambdabot>Title: GHC/Type families - HaskellWiki
01:42:24<Olathe>Thanks :)
01:43:03<the_unmaker>haskell has good facilities for working on lists and sets? even complicated intersections?
01:43:46<ddarius>> intersect "abcde" "def"
01:43:47<lambdabot> "de"
01:43:54<thoughtpolice>Olathe: example - http://hpaste.org/10686
01:44:41<thoughtpolice>i think you might see what i mean by 'more functional' :]
01:45:27<vininim_>> gcs "attgccgat" "aaaagctcacct"
01:45:28<lambdabot> mueval: Prelude.read: no parse
01:48:17<pastorn_>ddarius: did you use some special parameters for your notation?
01:48:22<pastorn_>(!bitset)
01:48:34<pastorn_>i can't seem to get it to typecheck
01:48:35<ddarius>-XBangPatterns
01:49:03<ddarius>There's also a more efficient shiftL called uncheckedShiftL somewhere.
01:49:10<ddarius>(or something like that)
01:49:20<pastorn_>difference?
01:49:39<ddarius>shiftL checks for overflow and I guess throws an error in that case or something.
01:51:05<pastorn_>btw, what's the notation for that -XBangPatterns?
01:51:23<dibblego>it's a GHC extension
01:51:32<pastorn_>{-#GHC lol lol -XBangPatterns lol lol -}
01:51:36<ddarius>That's a commandline parameter or you can add a {-# LANGUAGE BangPatterns #-} or I don't understand your question.
01:52:00<dibblego>that's called a Haskell comment
01:52:04<dibblego>{- this is a comment -}
01:52:25<int-e>pastorn_: uncheckedShiftl# (from GHC.Base) has an odd overflow in the shift, similar to C ... W# (uncheckedShiftL# (int2Word# 1#) 64#) gives 1 for me.
01:53:02<int-e>> shiftL (1 :: Word) 64
01:53:03<lambdabot> 0
01:53:31<pastorn_> shiftL (1 :: Word) 65
01:53:36<pastorn_>> shiftL (1 :: Word) 65
01:53:37<lambdabot> 0
01:53:44<pastorn_>> shiftL (1 :: Word) 63
01:53:45<lambdabot> 9223372036854775808
01:53:49<pastorn_>nice
01:54:27<Olathe>> (up :: Word)
01:54:28<lambdabot> mueval: Prelude.read: no parse
01:54:54<pastorn_>@pl \x -> fromJust x ++ transpose x
01:54:54<lambdabot>liftM2 (++) fromJust transpose
01:59:17<pastorn_>ddarius: btw, why do you want to have !bitset?
01:59:24<pastorn_>it's for strictness, right?
02:05:13<ddarius>pastorn: Yes. You don't want that integer to be boxed.
02:05:51<pastorn_>boxed = lazy?
02:06:28<ddarius>lazy => boxed, but no.
02:06:54<pastorn_>what happends if it's boxed?
02:13:33<lispy>pastorn_: do you know what the box is?
02:13:53<pastorn_>lispy: no
02:14:39<lispy>pastorn_: if I recall correctly, the box is a wrapper used at the C/asm level to hold the value. I think it may help with things like garbage collection
02:14:53<pastorn_>ok
02:15:06<lispy>pastorn_: so not having the box (and the level of indirection it adds) speeds things up
02:15:13<lispy>takes less memory, etc
02:15:22<pastorn_>well, i'm allocating a Word16 for this, so i don't think the GC will be of much trouble here :D
02:17:08<lispy>Oh, maybe the reason values get boxed is also to deal with laziness
02:17:21<lispy>That would explain why ddarius said lazy => boxed
02:17:30<pastorn_>yeah...
02:17:44<lispy>So the thunk could be the box
02:18:04<lispy>and if you don't need the thunk (because it's strict) then you can toss the box ad use the value directly
02:21:58<pastorn_>@src splitAt
02:21:58<lambdabot>splitAt n xs = (take n xs, drop n xs)
02:22:11<lispy>I think the bit I was thinking about garbage collection is that you can use boxing as an alternative to tagging
02:22:23<Cale>dibblego: heh, was that you commenting on the MSDN blog where the guy was discussing how people must follow the instructions provided in the API documentation?
02:22:37<pastorn_>isn't it possible to do that quicker?
02:22:42<Cale>pastorn_: yes
02:22:51<dibblego>Cale, prolly :)
02:22:55<Cale>pastorn_: The code provided by @src need not be the actual source.
02:23:01<pastorn_>oh
02:23:08<Cale>dibblego: The thing about GetEnvironmentStrings/FreeEnvironmentStrings
02:23:12<pastorn_>@hoogle splitAt
02:23:12<lambdabot>Prelude splitAt :: Int -> [a] -> ([a], [a])
02:23:12<lambdabot>Data.ByteString splitAt :: Int -> ByteString -> (ByteString, ByteString)
02:23:12<lambdabot>Data.List splitAt :: Int -> [a] -> ([a], [a])
02:23:13<dibblego>yep
02:23:36<Cale>I wrote this: http://blogs.msdn.com/oldnewthing/archive/2008/09/25/8965129.aspx#8965837
02:23:42<lambdabot>Title: The Old New Thing : Even if a function doesn't do anything, you still have to ca ..., http://tinyurl.com/3zkfqn
02:25:45<bd_>Cale: Unfortunately, the windows API didn't have that luxury at the time it was designed (due to simple compilers and extreme memory constraints), and inherited the basic design due to years of legacy code :)
02:26:15<bd_>legacy third-party code*
02:28:48<Cale>bd_: right.
02:30:09<Cale>bd_: and it would probably be easier to throw it all away and start over than to try and patch things up slowly by deprecating some calls and making core language improvements :)
02:30:21<Cale>bd_: I wonder what the corresponding calls look like in .NET ;)
02:30:28<ddarius>Why would you call FreeEnvironmentStrings and then use the memory?
02:30:51<Cale>ddarius: hm?
02:30:58<bd_>Cale: mmm, unfortunately windows' commercial success depends on supporting legacy code
02:31:24<bd_>ddarius: because it worked fine in NT4! and therefore you never noticed that routine X stored that pointer you passed it
02:31:49<SamB_XP>than why can't Win64 run simtower?
02:31:55<pejo>bd, just like Intel and AMD.
02:32:08<ddarius>bd_: That's just a bug. I'm talking about intentionally doing this.
02:32:10<Cale>bd_: Right. On the other hand, I'm continually impressed at how well wine works these days, and it doesn't even have the benefit of being able to look at MS's code. :)
02:32:24<SamB_XP>ddarius: um, what makes you think MS doesn't support bugs ?
02:32:30<Saizan_>hah, when regions become widespread withFile-like functions will look like hazardly dangerous things
02:32:31<bd_>Cale: http://msdn.microsoft.com/en-us/library/1h5xxewc.aspx is the .NET version, incidentally
02:32:32<lambdabot>Title: Environment.GetEnvironmentVariables Method (System)
02:32:46<SamB_XP>Saizan_: what ?
02:32:48<ddarius>SamB_XP: That has nothing to do with what I said.
02:33:08<Saizan_>?type withFile
02:33:09<lambdabot>Not in scope: `withFile'
02:33:13<SamB_XP>ddarius: MS has a commitment to making even BUGGY code continue to work!
02:33:17<SamB_XP>for some reason
02:33:26<ddarius>SamB_XP: I'm not talking about MS's behaviour.
02:33:28<SamB_XP>as long as it's sufficiently popular
02:33:29<bd_>SamB_XP: because they have customers whose business depends on said buggy code
02:33:38<bd_>if a new version of windows breaks the buggy code, the customers won't upgrade.
02:33:44<Cale>bd_: Oh, good, and it appears there's no Free, because they're using garbage collection. :)
02:33:53<SamB_XP>I always thought it was because they had customers who really hated it when their games stopped running
02:34:12<ddarius>Cale: There's nothing particularly "CPS" about withFoo.
02:34:13<bd_>Of course, this isn't microsoft's fault. But their customers don't know that. And their customers no longer have the consultant who wrote the code working for them; and may not have the source.
02:34:32<bd_>But they keep using it. Because it works. On windows 3.1.
02:34:34<SamB_XP>and it may have been written by a hardware vendor or something too
02:34:44<bd_>And it had better work on every future version of windows too!
02:34:49<Cale>ddarius: Well, you can view it as the withFoo function taking a local continuation as a parameter.
02:35:05<SamB_XP>bd_: you do know that 3.1 apps don't work in 64-bit, right?
02:35:18<bd_>SamB_XP: yeah, but they work on every version until there
02:35:20<ddarius>Cale: Is every HOF taking a "local continuation"?
02:35:50<SamB_XP>for no intelligable reason, considering they had 'em working on Alpha and so forth ...
02:35:54<Cale>ddarius: In some sense, I suppose so. :)
02:36:00<bd_>SamB_XP: nice, emulation?
02:36:01<Olathe>Isn't there some kind of DOSboxy thing for running old Windows stuff ?
02:36:05<SamB_XP>bd_: yes!
02:36:19<SamB_XP>I have NO IDEA why they didn't just dust that off
02:36:21<Olathe>Hmmm...I guess VMware or something would work.
02:36:24<Saizan_>ddarius: the type nicely matches ContT IO in this case though :)
02:36:28<Cale>ddarius: But with* functions are so naturally manipulated in the Cont monad, that it makes sense to think of them that way.
02:36:28<bd_>SamB_XP: I guess they've finally decided to kill it?
02:36:42<SamB_XP>bd_: I don't see how it saved them any work ...
02:36:44<Cale>(or ContT over something, right.)
02:36:57<bd_>SamB_XP: it takes work to 'dust off' that stuff :)
02:37:05<SamB_XP>well, I mean, compared to all the explaining they have to do
02:37:10<bd_>and to make sure it stays working, and to QA it, and to localize it, and etc...
02:37:18<SamB_XP>localize what?
02:37:25<bd_>SamB_XP: the configuration dialogs, if any
02:37:27<bd_>and error messages
02:37:36<bd_>and msdn documentation for it
02:37:43<SamB_XP>um
02:37:55<ddarius>What you're going to write callCC withFoo >> doStuff instead of withFoo doStuff?
02:37:57<bd_>I mean, this is a full emulator now, I'm sure there are some user-visible strings lurking awway
02:38:05<SamB_XP>hmm.
02:38:12<bd_>but point is, yes, it's probably pretty close to release
02:38:17<bd_>or well, pretty close to 'working'
02:38:20<dibblego>I always forget about the widespread ignorance of what *really* happens inside corporate software development
02:38:27<bd_>but they don't want to have to support 16-bit stuff forever, I guess
02:38:50<bd_>besides, a third party can always write a emulator
02:39:28<Saizan_>ddarius: more like do foos <- sequence [withFoo1,withFoo2]; ...
02:40:29<Cale>ddarius: or something like do x <- ContT (withFoo); doStuff x
02:40:47<ddarius>This is "natural"? I personally think describing withFoo as CPSy is obfuscatory and misleading. It's just a HOF.
02:41:18<Cale>ddarius: Suppose I want n things allocated with withFoo, provided to me in a list.
02:41:34<ddarius>mapM withFoo list
02:41:58<lispy>dibblego: which is?
02:42:15<dibblego>like bd_ describes except a lot worse :)
02:42:28<Cale>as in, withFoo :: (A -> IO B) -> IO B, and I have doStuff :: [A] -> IO B, and I want doStuff to be passed a list of n values of type A
02:42:29<shrughes>forM_ list . ((withFoo .) .)
02:42:44<shrughes>^^ not in response to your latest comment
02:43:00<Cale>ddarius: Does that make sense? :)
02:43:17<shrughes>Cale: still then, you can do a bunch of nested withFoos
02:43:39<ddarius>You want withFoo $ \a -> withFoo $ \b -> doStuff [a,b] for an arbitrary deep nesting?
02:43:39<Cale>shrughes: Yes, if n is not a variable, or you can write a handy little recursive function...
02:43:44<Cale>ddarius: yes :)
02:43:55<Cale>However, the monadic view makes things simpler.
02:44:02<Cale>There's already a function which does this. :)
02:44:59<shrughes>meh, it's not much of a win. The real win would be getting my coworkers to accept WithFoo
02:45:04<Cale>hehe
02:45:20<shrughes>I've had to compromise with using blocks in some interesting ways
02:46:25<Cale>:t \n -> runContT . replicateM n . ContT
02:46:26<lambdabot>forall a (m :: * -> *) r. (Monad m) => Int -> ((a -> m r) -> m r) -> ([a] -> m r) -> m r
02:46:48<Cale>So, modulo that wrapping/unwrapping, this is just replicateM.
02:47:24<ddarius>Cale: I've never, ever seen someone do that and I don't see that particular case coming up and making a primitive withFoos is more idiomatic, more readable, and almost certainly more performant. If you only had withFoo to work with then using that would be helpful, but it still isn't particularly CPSy. It could be, but that is not what is communicated with 'with'.
02:48:09<Cale>ddarius: I think of it as taking a continuation over which the resource that the function manages is allocated.
02:48:27<Cale>But perhaps that's strange for lots of people :)
02:48:34<shrughes>Cale: say that again?
02:49:06<shrughes>"over" a continuation?
02:49:28<Cale>That is, during the continuation's execution, the resource is made available.
02:50:53<Cale>I suppose that the continuation style allows you to think of withFoo as if it were getFoo.
02:51:17<ddarius>Cale: If what was passed was usually or intended to be "the rest of the program," I'd agree with you, but the idea is nested, block-like structure. Note a foreach-like loop could have type: (A -> IO ()) -> IO () and again describing this as CPS-like is silly in my opinion.
02:51:20<SamB_XP>Cale: so it has TWO continuations ?
02:51:54<Cale>I'm not thinking of the *whole* program as being translated into CPS.
02:53:06<Cale>SamB_XP: Well, it has the continuation up to the resource not being needed anymore, and then that returns, and there's a continuation through the rest of the program.
02:53:12<Cale>So, at least two, yes.
02:53:25<Cale>(as you have with any Cont/ContT monad computation)
02:55:23<Cale>Is that nonsense?
02:55:33<Cale>Or does it at least make some kind of sense.
02:55:56<SamB_XP>I think it makes enough sense to get you committed
02:56:00<Cale>Like, if you imagine the lifting of the with* style function to the ContT monad, (by just applying the ContT constructor)
02:56:11<SamB_XP>ACTION tries to figure out what repository to commit Cale to
02:56:25<Cale>Then you get to use it in that monad as if it were get* instead.
02:57:05<Cale>and it'll do the deallocation business somewhere at the end of the execution of the ContT action.
02:57:11<ddarius>Cale: That's a good insight, but getFoo is significantly different from withFoo.
02:57:59<Cale>ddarius: Well, in terms of not cleaning up after itself, sure.
02:58:47<shrughes>okay it all makes sense
02:59:06<Saizan_>here you can pretend that all the cleaning happens when you exit the ContT world
02:59:39<ddarius>Cale: getFoo = ContT withFoo would be useful for when I wanted to work with some disparate set of things and not worry about allocation. withFoo is when I want to specifically control the scope of allocation.
03:00:36<Cale>ddarius: Of course, you control the scope of the allocation by the size of your ContT action, but yes.
03:01:20<the_unmaker>is there any snmp monitor done in haskell?
03:01:53<Cale>Everything you end up allocating in a ContT computation in that way, gets deallocated at the very end, and not somewhere before it... for that, you'd have to nest runContT calls.
03:02:02<Cale>(which would be possibly too awkward)
03:02:47<[R]ayneHaskell>Bah.
03:02:52<[R]ayneHaskell>ACTION Ghosts himself.
03:03:05<ddarius>Cale: Which would be somewhat silly and suggest that you are going against the grain of that particular ContT usage (which is exactly the grain of usage with* supports).
03:04:07<ddarius>Cale: It's like how, by using continuations, events and threads are dual but we don't usually say threads are CPSy events.
03:05:48<Cale>ddarius: That's fair.
03:09:20<Cale>the_unmaker: I don't know of any.
03:12:50<lament>hey, where's ICFP? I can't find the address :(
03:14:27<Olathe>http://www.icfpcontest.org/
03:14:30<lambdabot>Title: ICFP Programming Contest 2008
03:15:24<lament>no, the physical address of the ICFP conference...
03:15:39<cjb>heh
03:15:47<ddarius>OLathe knows not of this "physical world" you speak of.
03:16:17<Olathe>http://www.icfpconference.org/icfp2008/local_info/travel.html
03:16:22<lambdabot>Title: ICFP 2008 - Travel to Victoria, British Columbia
03:16:26<Olathe>"The conference will be held at the Delta Victoria Ocean Pointe Resort and Spa located at 45 Songhees Road, Victoria, British Columbia, Canada.
03:16:49<lament>true, thanks
03:16:56<lament>i hope it's findable inside the hotel
03:17:53<SamB_XP>lament: I'm sure the employees will be able to direct you in sneaking in to ICFP
03:18:00<Olathe>Heheh.
03:18:17<lament>nah, my boss is paying for me :D
03:18:26<SamB_XP>oh
03:18:32<lament>even though i do nothing related to FP...
03:18:44<SamB_XP>wow sweet
03:19:02<SamB_XP>so who was complaining about the registration closing a couple days early ?
03:19:34<lament>me, iirc
03:19:56<lament>but that was online registration
03:20:12<SamB_XP>oh
03:20:16<kyevan>offtopic: is the jabber.org xmpp server down for you, too?
03:20:22<SamB_XP>lament: I thought it was you
03:20:30<lament>yeah, i'm pretty sure it was me
03:20:30<SamB_XP>I didn't realize it was possible to register offline
03:20:45<lament>that's what the site says now: "Please register on-site"
03:20:48<SamB_XP>so I was assuming you were going with the suggestion that was offered at that time
03:21:23<lament>if i sneak in, and convince my boss to give me $230 in cash, that would be even better :)
03:21:25<Olathe>Wait ?!
03:21:30<Olathe>Isn't this the website ?
03:21:46<lament>Olathe: yes...
03:22:06<Olathe>It was a horrible joke.
03:22:22<lament>yeah, pretty bad :)
03:23:17<SamB_XP>ACTION wonders why mcdonalds doesn't serve hotdogs
03:24:18<ddarius>ACTION would never buy a McDonald's hotdog, but then he almost never buys a McDonald's hamburger.
03:24:51<SamB_XP>hey, I never said I thought they'd be worth buying
03:25:00<SamB_XP>it just seems a bit odd that they don't sell them ;-)
03:25:08<dolio>ddarius only buys the McRib.
03:25:15<lament>maybe there was an antitrust suit!
03:25:32<SamB_XP>all suits are antitrust
03:25:37<ddarius>ACTION should be having slow smoked ribs tomorrow.
03:25:46<SamB_XP>probably because they are also backstabbing liars
03:25:49<ddarius>SamB_XP: Mine's pinstriped.
03:26:12<lament>mine used to be polka-dot but somebody cut out all the dots
03:26:14<SamB_XP>ddarius: I thought slavery was illegal
03:26:22<SamB_XP>lament: what?
03:26:27<SamB_XP>you have a swiss coat?
03:26:30<SamB_XP>er. suit
03:27:14<lament>yes. It is made of moon rock.
03:27:26<SamB_XP>what the ???
03:27:44<pastorn_>this is the SECOND time today! either my brain isn't working now or i don't know what
03:27:56<pastorn_>i would like to do some list recursion, to... say...
03:28:01<Olathe>@yow
03:28:01<lambdabot>Yow! I want to mail a bronzed artichoke to Nicaragua!
03:28:09<pastorn_>pair the sum of a list with the last value in the list
03:28:23<ddarius>pastorn: Order a new brain.
03:28:30<Olathe>let xs = (sum xs, last xs) ?
03:28:37<Olathe>Or, with recursion...
03:28:40<ddarius>Olathe: That certainly won't work.
03:28:51<pastorn_>f (x:xs) = x + f xs
03:29:08<Olathe>f lastOne sum listToGo
03:29:12<Olathe>Maybe f'
03:29:26<pastorn_>f [x] = 0 (somethingMagicalWith ,) x
03:29:29<Olathe>f' previousItem sum xs =
03:29:47<Olathe>f' previousItem sum [] =
03:30:11<ddarius>Let's add an accumulating parameter and then ignore it
03:30:21<ddarius>> foldl (flip const) (error "foo") [1..10]
03:30:22<lambdabot> 10
03:30:31<Olathe>f (x:xs) = f' x x xs
03:30:35<pastorn_>it's impossible to do this with a stack of function applications, right?
03:30:36<dmwit>> (sum &&& last) [1..10]
03:30:37<lambdabot> mueval: Prelude.read: no parse
03:30:44<dmwit>pastorn_: No, of course not.
03:30:48<dmwit>Why would you think that?
03:30:53<pastorn_>syntax
03:30:59<pastorn_>f (x:xs) = x + f xs
03:31:03<pastorn_>f [x] = 0 (somethingMagicalWith , x
03:31:07<dmwit>You're already wrong.
03:31:15<dmwit>f (x:xs) /= x + f xs
03:31:17<pastorn_>f [x] = 0 `(,)` x
03:31:36<pastorn_>though that MIGHT work
03:31:39<pastorn_>hmmm...
03:31:46<Saizan_>the syntax for a tuple is (0,x)
03:32:07<dolio>`(`(`(,)`)`)`
03:32:16<Olathe>zomg
03:32:18<Saizan_>but your first case is wrong, because it's trying to sum a number and a tuple
03:32:19<pastorn_>Saizan_: i know, but i want a stack of function applications to be applied to the left value
03:32:30<Olathe>You want a what ?
03:33:07<Saizan_>pastorn_: just pattern match on the recursive call, extract the left value, and build a new tuple
03:33:24<Saizan_>this is going to use O(n) stack
03:33:41<pastorn_>Saizan_: yeah, i know
03:34:30<Olathe>Do it without the stack of evilness.
03:35:04<pastorn_>f [x] = let g a b = (a,b) in 0 `g` x
03:35:04<pastorn_>f (x:xs) = x + f xs
03:35:10<pastorn_>infinite type complaint
03:35:27<Olathe>pastorn: You don't really need g.
03:35:35<dmwit>Your (x:xs) case is still wrong, for the same reason it was wrong before.
03:35:49<dmwit>And, yeah, g is kind of pointless there.
03:35:54<Saizan_>pastorn_: i was talking about the (x:xs) case
03:36:15<pastorn_>what's wrong with it?
03:36:15<dmwit>pastorn_: What is the type of f?
03:36:34<pastorn_>Num a => [a] -> (a,a)
03:36:37<dmwit>pastorn_: Now, think about what that means on the RHS of the (x:xs) case. (f xs) has what type?
03:37:15<pastorn_>dmwit: "RHS"?
03:37:20<dmwit>right-hand side
03:37:35<dmwit>respectively, LHS =)
03:37:47<Olathe>MHS
03:37:56<pastorn_>oh, f xs :: (a,a)
03:38:01<dmwit>exactly
03:38:02<pastorn_>well, at least in the end it will
03:38:05<Olathe>What is the type of x ?
03:38:07<ddarius>ACTION wonders how this PDF was made to be 6MB.
03:38:08<pastorn_>a
03:38:18<dmwit>pastorn_: So, do you know how to fix it now?
03:38:23<pastorn_>no
03:38:31<Saizan_>ok, so you can't sum an 'a' and a '(a,a)'
03:38:31<dmwit>Pattern match on (f xs), as Saizan_ suggested.
03:38:33<pastorn_>because i want a pair in the en
03:39:01<Saizan_>and so?
03:39:06<Olathe>pastorn: What is 3 + (5, 6) ?
03:39:15<pastorn_>Olathe: syntax error
03:39:19<dmwit>Olathe: I'm pretty sure we're past that particular misconception by now.
03:39:28<SamB_XP>ddarius: oh, it was padded out with unreferenced porno
03:39:45<Olathe>pastorn: Well, it's fine syntax.
03:39:50<Saizan_>pastorn_: can you write a function that substitutes the first element of a tuple with something else?
03:39:52<roconnor>> fmap (3+) (5,6)
03:39:54<lambdabot> (5,9)
03:40:00<SamB_XP>ACTION makes up a silly, but possible, explanation
03:40:22<pastorn_>i don't think i will get it... could i please get the correct definition?
03:40:25<Olathe>SamB_XP: PlagiarismError
03:40:34<SamB_XP>Olathe: what ?
03:40:36<pastorn_>i will probably understand a lot better when i see it
03:40:40<SamB_XP>I didn't plaigerize it
03:40:43<ddarius>SamB_XP: That would make more sense than the reality probably does.
03:40:50<Olathe>SamB_XP: You have to reference the porno or else you've plagiarized it.
03:40:54<SamB_XP>ddarius: sadly yes
03:41:01<SamB_XP>Olathe: *groan*
03:41:03<Olathe>;)
03:41:08<Saizan_>pastorn_: f (x:xs) = let (s,l) = f xs in (x+s,l)
03:41:20<SamB_XP>Olathe: what I meant was ... image objects in the PDF that were not actually used in any of the pages
03:41:35<Olathe>Ahh
03:41:50<pastorn_>oh, riiiight...
03:41:52<pastorn_>that
03:42:06<SamB_XP>as I said -- doable but unlikely
03:42:34<pastorn_>Saizan_: thanks :D
03:42:37<newsham>?src (,) fmap
03:42:37<lambdabot>fmap f (x,y) = (x, f y)
03:42:54<Olathe>@src (->)
03:42:54<lambdabot>Source not found. Are you on drugs?
03:43:01<Saizan_>@src (->) first
03:43:01<lambdabot>first f = f *** id
03:43:30<dmwit>?src (->) (&&&)
03:43:31<lambdabot>Source not found. You speak an infinite deal of nothing
03:43:36<dmwit>?src (&&&)
03:43:36<lambdabot>f &&& g = arr (\b -> (b,b)) >>> f *** g
03:43:39<pastorn_>Saizan_: i was thinking from the start of the list, i should've been thinking from the bottom...
03:43:56<pastorn_>:)
03:44:22<dmwit>pastorn_: But, you shouldn't bother writing the explicit recursion for anything but language practice.
03:44:27<Saizan_>pastorn_: you should focus less on the order of evaluation and more on what things represent
03:44:28<dmwit>Here's an alternative implementation:
03:44:34<ddarius>pastorn: You shouldn't be thinking from the bottom, top, left, or right. You should be thinking about the cases.
03:44:36<dmwit>sumAndLast xs = (sum xs, last xs)
03:45:11<pastorn_>dmwit: nah, that traverses the list two times
03:45:16<pastorn_>can't have that :p
03:45:21<SamB_XP>(_|_)s up
03:45:36<SamB_XP>ACTION can't get over that pun
03:45:37<dmwit>pastorn_: sufficiently smart compiler, premature optimization, etc., etc.
03:46:09<pastorn_>dmwit: well, i have to leart to optimize _somehow_ won't i?
03:46:13<newsham>it would be cool if the bot could expand out definitions, like "?expand (sum &&& last)" could somehow give you "\xs -> (sum xs, last xs)", or further expand sum and last.
03:46:16<dmwit>SamB_XP: It's a pretty good one, especially since (_|_) kind of looks like a bottom. =)
03:46:22<ddarius>pastorn: The code you want to write would build up as many stack frames as list elements and then would unwind them, so you end up traversing the list twice as well.
03:46:28<pastorn_>hence making shitloads of mistakes on the way
03:46:28<SamB_XP>dmwit: that's what I meant about it being a pun
03:46:33<dmwit>pastorn_: The first step in learning to optimize is learning to profile.
03:46:41<Olathe>> foldr (\x (s, _) -> (s + x, x)) (0, 0) [1..100]
03:46:43<lambdabot> (5050,1)
03:46:45<ddarius>newsham: When should it stop?
03:46:49<Olathe>That didn't quite work.
03:46:56<newsham>the first step in learning to optimize is picking the right optimization function
03:47:01<SamB_XP>it looks a bit like a butt, AND it is a parenthesized form of the asciization of bottom
03:47:08<Olathe>> foldl (\(s, _) x -> (s + x, x)) (0, 0) [1..100]
03:47:09<lambdabot> (5050,100)
03:47:15<newsham>ddarius: after 1 step, unless directed by the user otherwise?
03:47:21<newsham>*shrug*
03:47:30<newsham>obviously lots of room for exploration of that question
03:47:30<pastorn_>dmwit: that's probably true
03:47:41<Olathe>> foldl (\(s, _) x -> (s + x, x)) (0, undefined) [1..100]
03:47:42<lambdabot> (5050,100)
03:47:56<pastorn_>actually i managed to hook the ghc profiler up to a binary for the first time yesterday :)
03:48:08<Saizan_>> foldl (\(s, _) x -> (s + x, x)) (0, undefined) [1..10000000]
03:48:10<SamB_XP>pastorn: it's ALIIIIVE!
03:48:19<lambdabot> mueval: Prelude.read: no parse
03:48:28<pastorn_>Olathe: nice
03:48:31<dolio>Woo, stack overflow.
03:48:33<ddarius>@quote ghc
03:48:34<lambdabot>ghc says: This is very gruesome indeed
03:49:04<newsham>s/optimization function/objective function/
03:49:45<Olathe>@bot
03:50:04<lambdabot>:)
03:52:10<the_unmaker>grue
03:52:15<the_unmaker>so heh
03:52:25<the_unmaker>making apps work among 100 boxes is tuff eh
03:52:27<newsham>does lambdabot's eval not allow control.arrow.***?
03:52:37<the_unmaker>i guess there is always load balancing
03:52:51<dmwit>newsham: Yeah, Control.Arrow seems to be missing.
03:53:07<newsham>how come it knows the types fromcontrol arrow but wont let you eval it?
03:53:13<newsham>> (+1) *** (+2)
03:53:14<lambdabot> Overlapping instances for Show ((b, b') -> (b, b'))
03:53:14<lambdabot> arising from...
03:53:19<shapr>the_unmaker: Have you considered writing an snmp monitor in Haskell? It wouldn't be difficult.
03:53:20<newsham>> ((+1) *** (+2)) (1,1)
03:53:21<dmwit>It turns out that :t and > are not the same plugin.
03:53:25<lambdabot> mueval: Prelude.read: no parse
03:53:26<dmwit>(Maybe?)
03:53:31<newsham>thats not :t
03:53:44<dmwit>Oh, right.
03:53:49<Olathe>> foldb (\(a, _) (b, x) -> (a + b, x)) (0, undefined) $ map (\a -> (a, a)) [1..1000000]
03:53:53<lambdabot> (500000500000,1000000)
03:54:18<dmwit>I like foldb.
03:54:24<dmwit>I use it every once in a while.
03:54:29<newsham>?src foldb
03:54:30<lambdabot>Source not found. Sorry.
03:54:45<dmwit>I wrote it based on some ideas from Oleg.
03:54:52<dmwit>No type hackery, just the algorithm, though. =)
03:55:33<Olathe>Interesting.
03:55:34<dmwit>http://hpaste.org/10687
03:55:38<Olathe>Cale wrote it, too.
03:55:39<Olathe>http://hpaste.org/1893
03:56:03<dmwit>Mmm, then his implementation is probably better than mine. =)
03:56:46<dmwit>Oh, his has a different type.
03:57:14<dmwit>I wonder why he uses g at all.
03:57:16<Olathe>http://hpaste.org/10688
03:57:20<Olathe>That's mine.
03:57:40<dmwit>It seems like foldbCale f g z xs = g . foldbDmwit f z xs
03:57:56<dmwit>His implementation is better, but his type is worse. =)
03:58:11<Olathe>@type foldb
03:58:13<lambdabot>forall a. (a -> a -> a) -> a -> [a] -> a
03:58:16<Olathe>Let's see.
03:58:19<dmwit>err... s/g ./g $/, of course
03:59:22<newsham>wouldnt foldb make more sense on a tree?
03:59:34<dmwit>newsham: It is exactly a tree fold on a list.
03:59:36<Olathe>@let foldbDmwit op def xs = foldb1 op (def:xs) where foldb1 op = head . foldb'; pairwise (x:y:rest) = op x y : pairwise rest; pairwise shortList = shortList; foldb' xs@(x:y:rest) = foldb' (pairwise xs); foldb' shortList = shortList
03:59:38<lambdabot> Defined.
03:59:44<Olathe>@type foldbDmwit
03:59:46<lambdabot>forall a. (a -> a -> a) -> a -> [a] -> a
03:59:46<newsham>so why do it on a list?
03:59:56<dmwit>newsham: Because lists are pretty convenient to construct.
04:00:22<dmwit>newsham: For example, foldb (*) 1 [1..n] is way faster and more convenient than just about any other multiplication order.
04:00:43<Olathe>@let foldbCale f g z [] = z; foldbCale f g z [x] = g x; foldbCale f g z xs@(_:_:_) = foldbCale f g z (combinePairs xs) where combinePairs [] = []; combinePairs [x] = [x]; combinePairs (x:y:xs) = f x y : combinePairs xs
04:00:44<newsham>let (a,b) = splitAt (length xs `div` 2) xs in zipWith f a b
04:00:45<lambdabot> Defined.
04:00:50<Olathe>@type foldbCale
04:00:51<lambdabot>forall a t. (a -> a -> a) -> (a -> t) -> t -> [a] -> t
04:00:54<Olathe>Ehh ?
04:01:10<newsham>why pair adjacent elements whe you can pair elements half a list away? :)
04:01:16<dmwit>Olathe: I told you already the relationship between the foldb you know and the foldb Cale wrote.
04:01:32<dmwit>newsham: Because elements half a list away aren't the same size, for example?
04:01:38<int-e>newsham: so it works for associative operators which aren't commutative
04:01:50<dmwit>There's a few reasons, yeah.
04:02:10<newsham>i dont see what it has to do with associativity or commutivity
04:02:19<dmwit>Worse, your version will take O(n log n) time just calculating length! =)
04:02:26<Olathe>Well, if you multiply neighbors, commutativity is irrelevant.
04:02:37<Olathe>If you multiply things halfway across a list, commutativity is required.
04:02:41<int-e>(my favourite foldb has type (a -> a -> a) -> [a] -> a and doesn't work on empty lists)
04:02:43<dmwit>newsham: If your operator isn't commutative, then (a * b * c * d) is different from (a * c * b * d).
04:02:52<newsham>you're assuming a single mapping from trees to lists
04:03:02<dmwit>That's true.
04:06:21<pastorn_>i need to sleep now
04:06:29<pastorn_>see ya laterz
04:06:37<[R]ayne>Bai.
04:06:45<Olathe>An excellent idea.
04:07:06<Olathe>11 PM is a poison that sneaks up on you and then kills you tomorrow.
04:08:12<[R]ayne>11 pm is usually just waking up for me.
04:08:19<dmwit>?remember Olathe 11 PM is a poison that sneaks up on you and then kills you tomorrow.
04:08:19<lambdabot>I will remember.
04:08:48<[R]ayne>?remember Haskell is a bitching language.
04:08:49<lambdabot>I will never forget.
04:08:57<dmwit>?quote Haskell
04:08:58<lambdabot>Haskell says: is a bitching language.
04:09:09<dmwit>[R]ayne: Probably not exactly what you were intending. =P
04:09:14<[R]ayne>LOL.
04:09:19<[R]ayne>I failed.
04:09:22<Olathe>@forget Haskell is a bitching language.
04:09:22<lambdabot>Done.
04:09:28<[R]ayne>Hmmm...
04:09:34<Olathe>I will never...I mean...umm...forget ?
04:09:39<dmwit>?quote Haskell
04:09:40<lambdabot>Plugin `quote' failed with: getRandItem: empty list
04:09:43<dmwit>boo
04:09:46<dmwit>?quote Haskell
04:09:46<lambdabot>Plugin `quote' failed with: getRandItem: empty list
04:09:55<Olathe>@quote
04:09:55<lambdabot>mikaeli says: My friend bought a new laptop; it had MSBLASTER preinstalled. I couldn't believe it either and installed XP and the apps many times, run virus killers and everytime the blaster came
04:09:55<lambdabot>back. Everything was packed on a rescue cd. And virus was in m$ works installation files.
04:10:04<[R]ayne>?remember Haskell I'm a bitching language
04:10:04<lambdabot>It is forever etched in my memory.
04:10:09<[R]ayne>That will look cool LOL.
04:10:16<dmwit>Oh, hey, I bet this is a great clue for that bug!
04:10:28<dmwit>?quote Haskell
04:10:29<lambdabot>Haskell says: I'm a bitching language
04:10:30<[R]ayne>Whoa, binrapt was in here.
04:10:41<[R]ayne>He's an old friend. >_> I didn't know he was into haskell.
04:10:46<[R]ayne>He used to be a C++ freak o.o
04:10:53<dmwit>He still might be.
04:11:00<Olathe>@seen binrapt
04:11:00<lambdabot>I saw binrapt leaving #haskell 1m 36s ago, and .
04:11:39<Pseudonym>A lot of people like both Haskell and C++/.
04:11:47<Pseudonym>Indeed, C++ makes more sense once you know Haskell.
04:12:06<[R]ayne>He actually said he was "switching to functional"
04:12:10<Olathe>I'll have to try that.
04:12:39<lament>i suppose, once you can handle Haskell, you can handle anything
04:12:40<ddarius>ACTION likes Haskell and C++
04:12:42<lament>even C++ and Perl
04:12:58<ddarius>ACTION dislikes Perl quite a bit
04:13:00<Olathe>Even unlambda.
04:13:14<ddarius>Unlambda is easy. Just tedious
04:13:22<Olathe>I was looking over that yesterday.
04:17:47<lament>Unlambda is like C#, then
04:40:06<dancor>(>>=) is called "bind"; what is (>>) called
04:40:25<Olathe>"Throw that thingy away !"
04:40:35<Olathe>@src (>>)
04:40:35<lambdabot>m >> k = m >>= \_ -> k
04:42:05<Olathe>> (>>"A")$"Hello, world !"
04:42:06<lambdabot> "AAAAAAAAAAAAAA"
04:42:23<Olathe>Perhaps replace.
04:44:17<flux>@src (>>)
04:44:17<lambdabot>m >> k = m >>= \_ -> k
04:44:36<dmwit>dancor: Maybe some variation on "sequence"?
04:45:02<Olathe>> (>>"A")$Nothing
04:45:03<lambdabot> Couldn't match expected type `[]' against inferred type `Maybe'
04:45:10<Olathe>> (>>'A')$Nothing
04:45:11<lambdabot> Couldn't match expected type `m b' against inferred type `Char'
04:45:37<Olathe>> (>>'A')$Just 'b'
04:45:38<lambdabot> Couldn't match expected type `m b' against inferred type `Char'
04:46:06<Olathe>> (>>Just 5)$Just 'b'
04:46:07<dmwit>> Just 'b' >> Just 'a'
04:46:08<lambdabot> Just 5
04:46:08<lambdabot> Terminated
04:46:15<vinicius>vut
04:46:18<dmwit>Terminated?
04:46:19<dmwit>> Just 'b' >> Just 'a'
04:46:20<lambdabot> Just 'a'
04:46:23<Olathe>> (>>(return 5))$Just 'b'
04:46:25<lambdabot> Just 5
04:46:33<Olathe>> (>>(return 5))$"omg, hi !"
04:46:35<lambdabot> [5,5,5,5,5,5,5,5,5]
04:46:47<Olathe>Weird.
04:46:57<dmwit>Olathe: Why are you using that wacky (>>foo)$ form instead of just writing >> foo?
04:47:03<Olathe>Oh.
04:47:15<Olathe>> (++"!!!").(>>"A")$"Hello, world !"
04:47:16<lambdabot> "AAAAAAAAAAAAAA!!!"
04:47:46<Olathe>I don't know.
04:48:09<dmwit>> ("hey" >> "AA") ++ "!!"
04:48:11<lambdabot> "AAAAAA!!"
04:49:09<Olathe>That's easier to decipher.
04:49:19<Olathe>We're going for pointlessness.
04:49:48<Olathe>And indecipherability.
04:50:09<Olathe>http://uncyclopedia.org/wiki/AAAAAAAAA!
04:50:12<lambdabot>Title: AAAAAAAAA! - Uncyclopedia, the content-free encyclopedia
04:53:18<dancor>dmwit: mm
04:53:46<dancor>how do i find the source for the Monad instance of Function (Const m)
04:53:58<dmwit>eh?
04:54:00<dmwit>Function?
04:54:07<dancor>Functor (Const m)
04:54:12<dmwit>Const?
04:54:46<dmwit>I would look in the module that defines Const. ;-)
04:54:53<dolio>newtype Const a b = Const a
04:55:02<dancor>the instance is mentioned in http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html
04:55:13<dmwit>That can't have a very interesting Functor (or Monad) instance.
04:55:15<lambdabot>Title: Control.Monad, http://tinyurl.com/y25qsm
04:55:41<dmwit>instance Functor (Const m) where fmap f (Const x) = (Const x)
04:55:44<dolio>Yeah. fmap _ (Const a) = Const a
04:56:08<dolio>I'm not sure you can do Monad. return is a problem.
04:56:10<dmwit>I doubt it can have any Monad instance at all.
04:56:12<dmwit>right
04:56:19<dmwit>great minds, etc.
04:56:23<dancor>dmwit: Const is defined in Control.Applicative, but the instance doesn't seem to be in http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Applicative.html
04:56:25<lambdabot>Title: Haskell Code by HsColour, http://tinyurl.com/5avvxt
04:56:37<dmwit>?src Applicative
04:56:38<lambdabot>class Functor f => Applicative f where
04:56:38<lambdabot> pure :: a -> f a
04:56:38<lambdabot> (<*>) :: f (a -> b) -> f a -> f b
04:56:52<dmwit>That's because it's *really hard* to write pure.
04:57:06<dmwit>?djinn-add type Const a b = a
04:57:21<dmwit>?djinn b -> Const a b
04:57:21<lambdabot>-- f cannot be realized.
04:57:27<dmwit>=)
04:57:35<rwbarton>That page contains both instance Functor (Const m) and instance Monoid m => Applicative (Const m).
04:57:49<dmwit>Ah, yes, that's possible.
04:57:56<dmwit>pure x = Const mzero
04:58:05<dmwit>Or mempty, or whatever Monoid's thing is.
04:59:00<dmwit>Similarly uninteresting for (<*>): f <*> (Const x) = Const x
04:59:28<dancor>rwbarton: ah, i was confused.
05:00:13<solrize>@seen byorgey
05:00:13<lambdabot>I saw byorgey leaving #haskell-blah, #xmonad and #haskell 6h 41m 42s ago, and .
05:01:18<dolio>Well, if you're doing monoids, you could even do (Const x) <*> (Const y) = Const (x `mappend` y).
05:02:15<dmwit>Sure.
05:02:30<dmwit>It's really a pretty vapid instance, though.
05:02:30<dolio>That's probably in the Idiom paper, actually.
05:03:04<dolio>Or, one of those.
05:03:17<dolio>Whichever has the 'crush' function in it.
05:05:21<dolio>Section 4 "Monoids are phantom Applicative functors"
05:12:55<dancor>what is a good example of a Functor that's not an Applicative
05:13:11<dmwit>Array is my favorite Functor counter-example.
05:13:59<dmwit>Const m (without the Monoid m constraint) is also an example, though it's not as good a one, I think.
05:23:57<nanothief>what is a good library to use to access a sqlite3 database? I found HaskellDB and HDBC, although I found a few blog posts saying that they were difficult to install/unmaintained
05:27:52<dmwit>dcoutts_: ping
05:28:48<dons>dmwit: he's in the pub i think.
05:28:59<dons>nanothief: hdbc
05:29:07<dons>nanothief: though takusen/sqlite is also good
05:29:14<dmwit>?ask dcoutts Did anything ever come of the comment at the end of this page? http://haskell.org/gtk2hs/archives/2005/07/24/writing-multi-threaded-guis/2/
05:29:14<lambdabot>Consider it noted.
05:29:15<dons>nanothief: you could also use the normal sqlite bindings
05:30:08<nanothief>dons: ok, which would you recommend? I'm not that great with haskell, so nice docs/tutorials would be nice
05:30:42<ivanm>dons: just wondering... with the mean blog post you did a while back, is there any reason why you defined the "go" function rather than using a fold?
05:30:56<ivanm>(i.e. is there a performance difference between implicit and explicit recursion?)
05:34:54<nanothief>dons: hdbc looks very nice. Thanks for the hint
05:36:43<dons>nanothief: there's a chapter on hdbc in "real world haskell", online.
05:37:02<dons>ivanm: i think the second post explains this.
05:37:02<ivanm>ACTION wondered how long it would take dons to spruke his book... :p
05:37:10<dons>the difference is the pair state in the fold
05:37:19<dmwit>spruke?
05:37:47<dons>ivanm: its online, free. no better resource for hdbc... :/
05:39:05<dons>i guess ivanm didn't really mean "spruiking", that has some negative connotations imo.
05:39:22<dons>oh, is that aussie slang?
05:39:24<quicksilver>dons: is there a recommended way to use curses from haskell?
05:39:27<ivanm>how does spruiking have negative connotations?
05:39:32<ivanm>and yes, I meant spruik
05:39:43<dons>ivanm: that i'm trying to sell goods.
05:39:51<ivanm>http://en.wiktionary.org/wiki/spruik
05:39:54<dons>quicksilver: hmm. hscurses is big, but there's nothing i really like.
05:40:06<nanothief>dons: wow that book is awesome
05:40:08<quicksilver>dons: vty?
05:40:11<ivanm>dons: well, you do want people to buy/use it in the sense you didn't want all that work wasted
05:40:13<dons>oh vty is ok.
05:41:04<dons>quicksilver: seems to work for yi.
05:41:15<dons>quicksilver: i can't help but think there's a pretty printer library waiting to write.
05:41:20<dons>that dumps to curses
05:41:33<ivanm>dons: OK, found your second post now... for some reason, I don't recall seeing that one :s
05:41:48<tseg>I want to say: "if Just(x)=m then .. else ..", in a long series of conditionals. Is there a better way than "case m of {Just(x)->..; otherwise->..}"? This requires progressive indentation.
05:41:48<ivanm>(though I've made major use of your optimised list mean function :p)
05:41:59<dons>heh
05:42:07<dons>ivanm: we should rewrite the hstats package to use fusion
05:42:12<quicksilver>dons: I guess it's not an itch that many people have
05:42:18<quicksilver>tseg: Yes, probably.
05:42:28<quicksilver>tseg: the Maybe monad is for patterns like that
05:42:50<ivanm>dons: well, I can't contact the maintainer :s
05:42:52<quicksilver>tseg: at least, if every "Nothing" branch is the same, or most of them are.
05:43:07<ivanm>dons: the email address bounces :(
05:43:27<dons>for hstats?
05:43:38<ivanm>yeah
05:43:40<dons>he's online. i spoke to him last week.
05:43:44<ivanm>:o
05:43:44<dons>hmm. let' see.
05:44:07<tseg>I sometimes use "let Just(result)=do {x<-m; ..} % do {..} % .. in result", but this feels klunky.
05:44:38<dons>ivanm: mbeddoe ?
05:45:25<quicksilver>tseg: well, for example "if Just(a) = n then (if Just (b) = m then Just (a+b) else Nothing) else Nothing
05:45:46<quicksilver>tseg: is written as do a <- n; b <-m; return a+b;
05:45:53<quicksilver>or, inded, liftM2 (+) n m
05:45:55<tseg>What would be nice is: "if just(x)=m && just(y)==n && .. then ..use(x,y).. else ..", and bind variables within a conditional, without the monad. Monads are nice until you need to use more than one simultaneously, and then it's combinator hell...
05:47:00<dibblego>tseg, actually quite the contrary, you want <*>
05:47:06<tseg>quicksilver, "if Just(a)=n then .. else .." gives me a syntax error. Is there an extension for that?
05:47:08<RayNbow>it's busy in #haskell in the early morning :p
05:47:33<quicksilver>fromMaybe (else part) (do x <- m; y <- n; return (use x and y))
05:47:52<tseg>I'm not nearly smart enough to understand "liftM2 (+) n m", and even if I were, readers of my code wouldn't be. :-)
05:47:54<quicksilver>tseg: I meant (==). I unconciously copied your error ;)
05:48:51<RayNbow>> let add = liftM2 (+) in Just 3 `add` Just 5
05:48:53<lambdabot> Just 8
05:49:11<quicksilver>tseg: you can't have it both ways.
05:49:25<quicksilver>tseg: you can't be smart enough to dislike nested ifs, and not smart enough to think about liftM2
05:49:29<dibblego>do n' <- n; m' <- m; return (n' + m')
05:49:33<quicksilver>liftM2 *is* the answer to nested ifs.
05:49:36<quicksilver>(well, one of them)
05:50:17<quicksilver>it might be easier to work iwth an actual, concrete fragment of code.
05:50:25<quicksilver>which is why I tried to give my a+b example.
05:50:40<tseg>?src liftM2
05:50:41<lambdabot>liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
05:51:35<quicksilver>the monad and monadplus instances of Maybe are the general solution to complex patterns of if statements for Just x.
05:51:51<quicksilver>the monad instance takes the view "as soon as we get a Nothing, we give up"
05:51:56<quicksilver>a bit like exception handling
05:52:09<quicksilver>the monadplus instance allows you to say "if we got a Nothing here, try something else"
05:52:13<quicksilver>like 'catch'.
05:52:36<quicksilver>combining the two you can do arbitrarily complex patterns
05:53:03<tseg>I understand. I just like to avoid the point-free programming style. I find comprehension-like constructs so much easier to read and understand than the corresponding higher-order function invocations.
05:53:33<dibblego>you should address that failure
05:53:39<quicksilver>well do notaiton is a comprehension like structure.
05:53:50<quicksilver>do notation is the pointful version.
05:53:56<ivanm>dons: yup
05:54:21<RayNbow>> let infixl 1 «, »; («) = flip ($); (») = ($) in Just 3 «liftM2(+)» Just 5 -- I'm still digging EvilTerran's hack <3
05:54:23<lambdabot> Just 8
05:54:44<quicksilver>(list comprehensions are just do notation for the list monad, with a slightly quirky syntax)
05:54:48<dibblego>> let f n m = (+) <$> n <*> m in Just 3 `f` Just 8
05:54:50<lambdabot> Just 11
05:55:50<RayNbow>dibblego: but backticks don't give me the same beautiful symmetry ;)
05:56:13<tseg>quicksilver, thanks for the tips!
05:56:52<quicksilver>not at all.
05:57:06<quicksilver>it's easier to demonstrate with real code than abstract questions, though :)
05:58:13<quicksilver>tseg: demonstrate with real code than abstract questions, thoug
05:58:16<quicksilver>sry
05:58:22<quicksilver>tseg: http://hpaste.org/10689
05:58:33<quicksilver>tseg: that's a longer example of maybe monad use from one of my programs.
06:02:24<dancor>what's a good Arrow that's not a Functor
06:03:59<quicksilver>dancor: all arrows will be functors
06:04:17<quicksilver>dancor: you can build 'fmap' out of 'pure' and (>>>)
06:04:36<tseg>?src $
06:04:37<lambdabot>f $ x = f x
06:05:11<quicksilver>tseg: the $ after return is just to save a pair of ( .. ) aronud that whole gs expression.
06:06:00<dancor>oh duh yeah (>>>) is like (<*>)
06:06:38<dancor>but there's no Applicative instance of Arrow
06:06:42<dancor>i guess no one cared
06:06:56<dolio>@src WrappedArrow
06:06:56<lambdabot>Source not found. Maybe if you used more than just two fingers...
06:07:27<tseg>thanks for the example. writing a game in haskell, wow.
06:08:37<dolio>WrappedArrow is the Applicative instance for arrows.
06:08:39<RayNbow>@pl amap f = (pure f >>>)
06:08:39<lambdabot>amap = (>>>) . pure
06:08:42<dolio>I don't know why they did it that way.
06:10:01<dancor>yeah they're nuts
06:11:03<dancor>maybe they were afraid you would want PersonalArrow to be an Applicative in a different way?
06:11:23<dancor>but it could be with newtype or whatevs right hmm
06:11:48<dolio>Well, if (->) r is defined as an applicative directly, it'd overlaps.
06:12:11<dolio>Technically '(Arrow a) => Applicative (a b)' isn't a valid Haskell 98 header, either.
06:12:24<dolio>Maybe that's why.
06:12:53<dolio>Or instance head. Whatever they're called.
06:13:15<dancor>is there anything else i should know about in Monad > Arrow > Applicative > Functor
06:13:34<dancor>like NewSuperMonad or NewSubArrowSupApplicative
06:13:52<dolio>I'm not sure Arrow is appropriate in there.
06:14:06<dancor>it's not cool enough?
06:14:15<dolio>It's different.
06:14:34<dolio>Different kind, at least.
06:14:46<dancor>are there other X with Monad > X > Applicative
06:15:13<dolio>You can also stick stuff in there. Monad > Applicative > Pointed > Functor.
06:15:24<dolio>Where Pointed has pure/return.
06:16:19<tseg>@src Applicative
06:16:19<lambdabot>class Functor f => Applicative f where
06:16:19<lambdabot> pure :: a -> f a
06:16:19<lambdabot> (<*>) :: f (a -> b) -> f a -> f b
06:16:24<tseg>@src Pointed
06:16:25<lambdabot>Source not found. :(
06:16:35<dolio>Pointed is in category-extras.
06:16:42<_zenon_>ACTION hopes the wifi won't be interesting today.....
06:17:10<dolio>I'm not sure I can name any pointed functors that aren't applicative, off the top of my head.
06:17:33<tseg>@src Category.Extras.Applicative
06:17:33<lambdabot>Source not found. Listen, broccoli brains, I don't have time to listen to this trash.
06:17:42<tseg>haha nevermind
06:19:16<dolio>And then you have Comonad > ??? > Copointed > Functor
06:22:27<rwbarton>I suspect ??? may be f (Either a b) -> Either (f a) (f b)
06:23:04<dolio>Huh, interesting.
06:24:06<rwbarton>That's kind of a guess. Can it be derived from a comonad?
06:24:20<dolio>I don't know. Let me try.
06:26:47<dolio>That kind of looks like costrength, actually...
06:26:51<tseg>@src Category-Extras.Applicative
06:26:51<lambdabot>Source not found. Your mind just hasn't been the same since the electro-shock, has it?
06:26:56<tseg>@src CategoryExtras.Applicative
06:26:56<lambdabot>Source not found. My pet ferret can type better than you!
06:26:58<rwbarton>(I took one of the definitions of Applicative and applied it to the category Hask^op. But Hask^op is not a CCC, so I don't know how sensible an operation that is)
06:27:30<rwbarton>Yeah, it should.
06:28:00<rwbarton>Because Applicative = f x -> f y -> f (x, y), while strength = x -> f y -> f (x, y) (and is free in Haskell)
06:28:15<dolio>Yeah.
06:28:20<dolio>But costrength isn't.
06:28:24<rwbarton>Right.
06:33:17<dolio>That's actually exactly the type of bi-traverse, too, if there is such a thing.
06:33:19<quicksilver>dancor: Monad and Arrow are more like parallel alternatives.
06:33:43<quicksilver>dancor: in that they both treat effects but they are incomparable
06:33:50<quicksilver>(after all, one has one parameter and one has two)
06:34:27<dolio>Or, bi-sequence.
06:38:56<dolio>I guess it'd be costrong colax comonoidal functors. :)
06:39:13<dolio>If colax means anything. I don't know what lax means.
06:39:30<rwbarton>People usually say oplax for some reason.
06:39:37<dolio>Huh.
06:39:55<rwbarton>oplax monoidal functor = functor F with a structure map F(X x Y) -> FX x FY, where x is the monoidal structure
06:40:42<rwbarton>If x is just the product, every functor is oplax monoidal.
06:41:40<rwbarton>(lax monoidal functor means the structure map goes the other way, strong monoidal means the structure map is an isomorphism.)
06:42:04<_zenon_>is this cat-theory talk?
06:42:45<rwbarton>Yes
06:43:35<_zenon_>yeah, I figured.
06:47:37<ivanm>rwbarton: theory of cats? you talking only about household-cats or the entire feline family?
06:47:39<ivanm>;-)
06:53:27<rwbarton>dolio: So here's an interesting point about Copointed.
06:53:49<rwbarton>When f is a functor, giving pure :: forall a. a -> f a is the same as giving pure' :: () -> f () (i.e. pure'' :: f ())
06:54:33<rwbarton>Giving copure :: forall a. f a -> a is almost the same as giving copure' :: f Void -> Void , but not quite
06:55:07<rwbarton>If I have copure' :: f Void -> Void and x :: f a I can only construct (a -> Void) -> Void
06:55:10<dolio>Hmm. How do you recover copure?
06:55:29<rwbarton>which is not quite a
06:55:41<dolio>Ah, yeah.
06:56:27<dolio>Interesting.
06:58:22<rwbarton>It makes me think the Either thing is not totally wrong (because Either Void b = b) but also that there will be pitfalls in this area...
07:00:20<rwbarton>@djinn Either Void b -> b
07:00:21<lambdabot>f a =
07:00:21<lambdabot> case a of
07:00:21<lambdabot> Left b -> void b
07:00:21<lambdabot> Right c -> c
07:00:30<rwbarton>what is "void"?
07:00:44<dolio>Eliminator for Void.
07:01:10<rwbarton>Oh, I see.
07:01:25<rwbarton>@djinn Void -> a
07:01:26<lambdabot>f = void
07:02:44<pprakash>can somebody point me to Haskell syntax which discusses type declarations like this: type CFoldLeft coll val m seed = coll -> CollEnumerator val m seed
07:04:17<dolio>There's not much to it. It declares a type alias.
07:04:32<dolio>type Name variables = some-other-type
07:05:32<dolio>Then any time 'Name variables' appears in a type, it gets replaced with 'some-other-type'.
07:05:32<pprakash>essentially, rhs replaces the left
07:05:40<dolio>Yeah.
07:05:52<pprakash>great, thanks
07:06:17<dolio>Of course, GHC keeps them around (sometimes) in error messages and such.
07:06:33<dolio>Keeps the left-hand side, that is.
07:07:39<unmarshal> is there any case where you'd use the state monad in combination of the reader monad or is that redundant
07:07:46<unmarshal>reading monad transformers step by step and they do it
07:07:53<unmarshal>but i think its just for didactic purposes
07:08:27<unmarshal>especially if what you're keeping state of is the same thing as what you'd be using reader for
07:09:16<dolio>Well, if you have some global state that's mutable, and some that's read only, separating them makes sure you don't accidentally modify the read-only part.
07:09:18<unmarshal>i.e.: type PMonad a = State Portfolio a
07:09:21<unmarshal>type PMonad2 a = ReaderT Portfolio (State Portfolio a)
07:09:29<unmarshal>dolio: yeah that makes sense
07:09:33<unmarshal>but in that case i just mentioned it doesn't
07:09:44<unmarshal>i just wanted to be sure i'm understanding this right
07:09:55<dolio>There's even RWS and RWST that has reader writer and state all together in one monad.
07:10:23<dolio>For read-only input, mutable state and write-only output, all separate.
07:10:37<dolio>(And somewhat more efficient than stacking 3 transformers.
07:10:39<unmarshal>yeah that's cool
07:10:44<unmarshal>excellent
07:10:45<unmarshal>thank you!
07:11:01<unmarshal>i'm building some finance tools and need a mutable portfolio type, so this will work out nicely
07:11:04<dolio>That's what you lose by keeping them separate. Performance.
07:11:18<dolio>In the stacked transformer case, that is.
07:11:19<rwbarton>Your PMonad2 case seems like the one where you'd want separate ReaderT and State the most, if your intention is to always have the original Portfolio accessible.
07:11:53<unmarshal>cool, def wasn't what i intended but if i needed to do that, it makes sense
07:11:59<unmarshal>thanks guys
07:12:00<unmarshal>night
07:12:10<rwbarton>I wonder if the optimizer can often do more with Reader x than State x, too
07:15:39<Baughn>"ld warning: in /usr/local/lib/libgmp.dylib, file is not of required architecture" <-- *grumble*
07:26:32<retybok>why doesn't this work? http://hpaste.org/10690
07:27:07<rwbarton>@djinn (((a -> Void) -> a) -> a) -> ((a -> Void) -> Void) -> a
07:27:07<lambdabot>f a b = a (\ c -> void (b c))
07:28:49<rwbarton>retybok: Because where clauses attach to declarations, not expressions. You can write let a = ... in putStrLn $ show (a+a), or move the "let a = ..." to its own line and drop the "in".
07:29:45<retybok>rwbarton: so there is no way to do this with a where clause?
07:30:35<retybok>ah, I hadn't understood the let on its own line
07:30:40<retybok>makes sense
07:30:41<retybok>thanks
07:30:43<rwbarton>retybok: No useful way. (If you really wanted to, you could write let action = putStrLn $ show (a+a) where a = ... in action)
07:31:00<retybok>thanks again
07:31:07<rwbarton>No problem
07:31:28<rwbarton>:t \callcc b -> callcc (\c -> c (b c))
07:31:29<lambdabot>forall t t1 t2. (((t -> t1) -> t1) -> t2) -> ((t -> t1) -> t) -> t2
07:35:49<mc__>Hi! I have a problem with QuickCheck. I've read through the manual. But I dont get how I'd test a method with 100 random numbers for example.
07:36:54<mc__>Could someone please point me out the right direction?
07:38:15<stulli>mc__: i suggest RWH: http://book.realworldhaskell.org/read/testing-and-quality-assurance.html
07:38:24<_zenon_>mc__ that would be the scaling of the tests
07:38:28<lambdabot>Title: Chapter 11. Testing and quality assurance, http://tinyurl.com/46ejvv
07:39:33<mc__>thank you! I did not realize that the book teaches QuickCheck
07:41:37<_zenon_>stulli, actually, that was quite a good link, I was about to put the link to the original manual :P
07:58:07<hackage>Uploaded to hackage: supercollider-midi 0.1
08:10:35<retybok>Can someone explain what's wrong here? http://hpaste.org/10691
08:14:34<hml>anyone here runing haskepp on mac os x?
08:14:38<BeelsebobWork>retybok: most likely a garbage collection issue, but is there a reason you aren't just using parMap?
08:14:50<FunctorSalad>hackage: heh... unsafeCollideHadrons
08:15:18<BeelsebobWork>hml: haskepp?
08:15:46<retybok>BeelsebobWork: no reason, where is it defined?
08:15:52<glguy>let a=((read . head) args)::Int is just let a = read (head args) :: Int
08:15:59<glguy>no need for extra functions and parens ;)
08:16:03<BeelsebobWork>retybok: Control.Parallel.Strategies
08:16:09<retybok>glguy: I'm still learning :)
08:16:10<glguy>did you run it with the RTS flag for more kernel threads
08:16:16<glguy>-N2 iirc
08:16:19<quicksilver>hml: yes, many of us are.
08:16:20<retybok>glguy: yes, I did
08:16:24<quicksilver>hml: osx quite popular in this channel.
08:16:26<retybok>It only runs on one cpu
08:16:43<retybok>BeelsebobWork: actually I wanted to experiment a bit with the Concurrent framework
08:17:13<Itkovian>meuning
08:17:14<BeelsebobWork>retybok: heh, I'd suggest experimenting with things that don't only need the nice pure interface of Control.Parallel.Strategies :)
08:17:32<BeelsebobWork>also, you need to compile with -threaded, and run with +RTS -N<number of system threads>
08:18:08<retybok>BeelsebobWork: I did all this stuff
08:18:14<retybok>I'll try again, just to make sure
08:18:22<hml>BeelsebobWork , quicksilver : what is the easiest way to install haskell on osx?
08:18:23<BeelsebobWork>then probably just the garbage collector getting in your way
08:18:29<BeelsebobWork>hml: sudo port install ghc
08:18:51<hml>err, isntall mac ports? I heard that it was shit
08:19:13<BeelsebobWork>no, there seems to be some odd rumor to that effect going round
08:19:16<BeelsebobWork>dunno why
08:19:26<BeelsebobWork>MacPorts is a fairly stable, mature package management system
08:19:30<hml>let's have a vote; ppl vote whether mac port is good or bad
08:19:36<tnks>dibblego: so I just did an "apt-get search" for haskell packages, and it's nothing near what's on hackage. Is there a packaging mechanism for Haskell? Or do people just copy around source code?
08:19:39<quicksilver>macports is less shit than the alternatives
08:19:47<BeelsebobWork>I think quicksilver nailed it there
08:19:49<retybok>yep, only one cpu
08:19:55<quicksilver>I think source-based package management is about as sensible as wood-burning combustion engines
08:19:58<dibblego>tnks, yes cabal-install
08:20:03<quicksilver>but, since macports works, I use it.
08:20:03<BeelsebobWork>retybok: profile it -- I bet you'll find most of your time is spent in the garbage collector
08:20:14<ivanm>quicksilver: what's wrong with source-based?
08:20:24<BeelsebobWork>ivanm: it takes friking ages
08:20:26<quicksilver>ivanm: I don't want to waste 8 hours compiling ghc and apache.
08:20:26<BeelsebobWork>and gats you no gain
08:20:34<quicksilver>that's what I have distributions for
08:20:48<quicksilver>installing a new package on this box (debian with decent net connection) takes under a second.
08:20:55<quicksilver>installing a new package on my mac takes 1 hour - 8 hours
08:21:01<quicksilver>depending how hard they are to compile.
08:21:17<BeelsebobWork>unfortunately, fink, which has a binary distribution option is much more shit than ports
08:21:23<retybok>BeelsebobWork: all right, I'll do that. I'll try with parMap too. Thanks for the help!
08:21:25<BeelsebobWork>(in that it's very poorly maintained)
08:21:29<quicksilver>fink's heart is in the right place
08:21:36<quicksilver>but it doesn't have enough people working on it
08:21:40<BeelsebobWork>idd
08:21:43<quicksilver>so it doesn't have enough packages / new enough packages.
08:21:55<BeelsebobWork>IIRC ghc was at 6.6 until only a month or two ago
08:22:13<ivanm>quicksilver: only takes me about 25 minutes to compile ghc... :p
08:22:21<quicksilver>ivanm: yes, but that's not really the point.
08:22:25<ivanm>heh
08:22:30<quicksilver>(8 hours was my iBook G4)
08:22:36<ivanm>so you don't think much of all of us that use gentoo? ;-)
08:22:38<BeelsebobWork>ivanm: snap, you have an 8 core mac pro don't you
08:22:56<quicksilver>ivanm: I don't presume to question your decisions.
08:22:59<quicksilver>I'm explaining mine.
08:23:05<ivanm>BeelsebobWork: nope, just a c2d laptop
08:23:08<BeelsebobWork>o.O
08:23:09<ivanm>quicksilver: yeah, I know ;-)
08:23:14<BeelsebobWork>how on earth do you compile ghc that fast?
08:23:21<BeelsebobWork>my C2D laptop takes about 2 hours
08:23:38<tnks>sound like some Gentoo fan made a noise.
08:23:51<ivanm>BeelsebobWork: make that 1/2 hr
08:24:03<ivanm>how old is yours?
08:24:05<quicksilver>retybok: I had a bit of al ook at your code.
08:24:11<BeelsebobWork>not very, but it is only 2Ghz
08:24:20<quicksilver>retybok: most likely I can't answer your quesiton without seeing the definition of ll and facto.
08:24:25<BeelsebobWork>but yeh... an 8 core 2.8Ghz MacPro takes 25 minutes
08:24:33<BeelsebobWork>so I'm struggling to see how you're getting that speed
08:24:49<quicksilver>retybok: I agree with BeelsebobWork that parMap is a better approach; but it's still interesting to ask why nmergeIO isn't working.
08:24:55<Gast_314_>http://www.meine-privaten-nacktvideos.net?id=4812552
08:24:58<BeelsebobWork>quicksilver: true dat
08:25:00<quicksilver>BeelsebobWork: difference between single compile and full bootstrap?
08:25:06<BeelsebobWork>quicksilver: could well be
08:25:09<quicksilver>BeelsebobWork: macports does a full bootstrap IIRC.
08:25:10<lambdabot>Title: Meine Homepage mit meiner Webcam , Bilder und Videos
08:25:11<BeelsebobWork>I am talking full bootstrap here
08:25:33<quicksilver>single compiles of ghc are 15-30 minutes on fast 2-core hardware
08:25:49<quicksilver>but a full bootstrap is more (3x more perhaps?)
08:27:12<moenicke>morning
08:28:52<mc__>is it a good idea or simply useless to test little input methods?
08:29:52<retybok>quicksilver: I'll post the full code in a moment
08:32:48<retybok>Ok, I've reiplemented it with parMap, still no luck: http://hpaste.org/10692
08:34:50<retybok>I should probably mention that I'm running the code on a bi dual-core xeon machine
08:35:27<retybok>I think it's acutally a quad-xeon machine (no dual core), if that matters at all
08:35:51<BeelsebobWork>retybok: use rnf, not rwhnf
08:36:18<retybok>ok, I will try. What's the difference?
08:36:39<BeelsebobWork>rwhnf reduces to weak head normal form -- i.e. it discovers it's not an empty list and then stops computing anything
08:36:47<BeelsebobWork>meanwhile rnf reduces to normal form, completely
08:36:54<retybok>awesome!
08:37:00<retybok>I thought it was the contrary
08:37:05<retybok>thanks for fixing my problem
08:37:12<BeelsebobWork>that's got you the parallelism?
08:37:20<retybok>yep
08:37:29<BeelsebobWork>:)
08:37:48<BeelsebobWork>that's possibly where it was missing in the other version too
08:37:50<mc____> where (a,b) <- getInput what is wrong with his?
08:38:04<mc____>getInput returns IO (Int,Int)
08:38:17<quicksilver>retybok: that was probably your problem with nmergeIO too
08:38:24<quicksilver>retybok: all it does it 'evaluate' the lists
08:38:26<BeelsebobWork>mc____: binds using <- must happen in a do block
08:38:32<Deewiant>you can't put a monadic binding in a where
08:38:36<quicksilver>(Which just forces them to [])
08:38:38<BeelsebobWork>otherwise it doesn't know what order to do it in
08:38:42<quicksilver>(or (x:xs))
08:39:12<retybok>maybe they should be renamed to "no_parallelism" "good_parallelism_chose_me" for noobs like me ;-)
08:39:20<BeelsebobWork>haha
08:39:32<BeelsebobWork>rnf requires an NFData instance
08:39:49<BeelsebobWork>so it's not quite so easy to use
08:40:15<quicksilver>BeelsebobWork: I dislike the choice of 'r' because I keep thinking it should stand for 'recursive'
08:40:23<quicksilver>(actually it presumably stands for 'reduce to')
08:40:29<quicksilver>maybe that's just me, though.
08:40:34<BeelsebobWork>quicksilver: yeh, I always guessed at reduce to too
08:40:43<BeelsebobWork>nf and whnf would be nicer though
08:40:46<retybok>most basic types seem to implement NFData, though
08:40:52<BeelsebobWork>I didn't see the whnf in rwhnf first time I read it
08:40:53<quicksilver>yes, any 'simple data' type should
08:40:58<BeelsebobWork>retybok: yep
08:41:04<quicksilver>basically anything that doesn't have functions or actions buried inside it.
08:41:16<BeelsebobWork>all you need to do to implement it is write something for your type that forces all the inner bits
08:41:22<retybok>that does limit quite a bit
08:41:24<BeelsebobWork>i.e. strictness anotations everywhere
08:41:54<quicksilver>retybok: I find all this slightly unfortunate
08:42:09<quicksilver>Control.Parallel.Strategies requires you to understand GHC's evaluation model in quite some detail
08:42:21<quicksilver>much more detail than the haskell language spec.
08:42:26<BeelsebobWork>I'm not sure that's true quicksilver
08:42:29<quicksilver>that feels like an abstraction leak, to me.
08:42:38<quicksilver>but I don't have a better suggestion.
08:42:40<BeelsebobWork>you don't need to understand any more than what "normal form" and "weak head normal form" are
08:42:51<BeelsebobWork>which admitedly is more than you should
08:43:02<mc__>Is it possible to test a method that does not take any parameters but only does input using QuickCheck?
08:43:02<BeelsebobWork>but it's not something specific to ghc -- it's general to all non-strict evaluators
08:43:17<quicksilver>it's a specific ghc choice that seq = rwhnf
08:43:31<BeelsebobWork>oh?
08:43:38<quicksilver>seq is permitted, by its spec to do anything between rwhnf and rnf as long as it doesn't create bottoms
08:43:43<BeelsebobWork>ah, I see
08:44:27<BeelsebobWork>so rwhnf is not actually necessarily what it says on the tin
08:44:40<BeelsebobWork>but instead "reduce to whatever your compiler reduces to when using seq"
08:44:54<quicksilver>I'm not sure if that's true. Maybe rwhnf should be defined to be what it says on the tine
08:45:01<quicksilver>but rwhnf = seq might not be true
08:45:09<quicksilver>I honestly don't know.
08:45:20<quicksilver>it just feels like the abstraction boundary is a bit weak here.
08:45:24<BeelsebobWork>I'm fairly sure in the current implementation it is seq
08:45:41<BeelsebobWork>yeh, but the abstraction boundary is weak in general when adding parallelism anotations
08:45:43<quicksilver>I want to be able to define sensible parallel evaluation strategies without having to explain so much.
08:45:52<quicksilver>but maybe I'm just too optimistic.
08:45:59<BeelsebobWork>parallelism has nothing to do with what your program *is*, only to do with how it should be computed
08:46:25<BeelsebobWork>so the only way to fix it is to build a super-clever-compiler that recognises where to stick `par`s itself
08:49:16<quicksilver>BeelsebobWork: that's the perfect fix, certainly.
08:49:25<quicksilver>I'm not sure it's feasible even in principle.
08:49:25<mapreduce>Or a monad that does it?
08:49:33<quicksilver>although I'm sure you can get some good heursitics.
08:49:41<quicksilver>(feasible to get it perfect, I mean)
08:49:42<BeelsebobWork>mapreduce: just putting something in a monad doesn't stop it being an abstraction leak
08:50:02<BeelsebobWork>quicksilver: yeh, I doubt it's feasible too, at least not without a *lot* of inspired research
08:50:38<mapreduce>BeelsebobWork: Are you considering parallelism to be something that should be hidden from interfaces?
08:50:47<mapreduce>interfaces = function types
08:51:18<BeelsebobWork>mapreduce: parallelism is something I should not have to write in my program -- a functional program describes what the result *is*, not how to get it
08:53:17<BeelsebobWork>o.O did anyone else jut get sent a message from "SecurityTest" saying "dcc send startkeylogger 0 0 0"
08:53:28<mapreduce>I'm suggesting to use a monad as an evaluation strategy.
08:53:41<mapreduce>BeelsebobWork: That's an old mirc exploit.
08:54:35<BeelsebobWork>mapreduce: yeh, I'm suggesting that that would be (a) messy (b) not something I should be describing in my program at all
08:55:11<quicksilver>mapreduce: we're talking about either not having to specify the strategy at all
08:55:18<quicksilver>or making the strategy as lightweight as possible
08:55:23<quicksilver>DPH is in this direction, I think.
08:55:27<mapreduce>I see.
08:55:37<quicksilver>Control.Parallel.Strategies is relatively heavyweight
08:55:43<BeelsebobWork>yeh, I need to have a good dig at DPH
08:55:44<quicksilver>(although lighter than explicit threads, of course)
08:56:17<Baughn>I wanted to rush in and claim the, no, Strategies is the best parallelism system yet.. but of course you're right.
08:56:36<BeelsebobWork>well, strategies *is* the best yet
08:56:39<BeelsebobWork>it's just not the idea
08:56:41<BeelsebobWork>ideal*
08:58:08<hackage>Uploaded to hackage: numeric-prelude 0.0.4
08:59:51<BeelsebobWork>o.O
09:00:02<BeelsebobWork>why did ghc just install itself with 700 permissions
09:18:42<retybok>So no rnf for recursive data types?
09:19:39<sjanssen>retybok: I'm just jumping in to the conversation here, but why couldn't there be rnf for recursive types?
09:19:51<sjanssen>you only run into trouble for types that are cyclic
09:20:38<retybok>sjanssen: well, they're not instances of NFData
09:21:20<retybok>Maybe it would be possible to implement the interface for your data types, I just don't see how one would do that
09:21:21<dolio>[a] has a NFData instance.
09:21:55<retybok>dolio: but data MyType = MyType | Other doesn't
09:23:06<dolio>So... write one?
09:23:26<retybok>well, maybe, but I really have no idea how to do it
09:23:38<retybok>I don't even know where to start
09:23:44<Baughn>Seen in a duplicate instance declaration error: "instance [overlap ok] Typeable2 IOArray" <-- What sort of syntax is this?
09:24:17<ivanm>is there a simple way of testing each distinct pair of elements in a list?
09:24:32<ivanm>s/testing/applying a function on/
09:25:10<dolio>instance NFData MyType where rnf ...
09:25:13<BeelsebobWork>retybok: instance NFData MyType where rnf MyType = MyType; rnf Other = Other
09:25:25<mc__>How would i get the (Int,Int) out of Maybe(Int,Int) ?
09:25:27<BeelsebobWork>just add appropriate strictness anotations to make sure it all gets evaluated
09:25:28<sjanssen>retybok: it isn't too difficult. See the source for that module for examples
09:25:42<BeelsebobWork>mc__: with pattern matching
09:25:48<dolio>No strictness annotations needed.
09:26:02<BeelsebobWork>dolio: they are for more complex things than the type he just gave
09:26:12<dolio>Matching against a constructor in a branch is strict.
09:26:21<mc__>BeelsebobWork: f Just(a,b) = ... for example?
09:26:22<BeelsebobWork>unsafeFromMaybe (Just x) = x; unsafeFromMaybe Nothing = error "this is why it's unsafe"
09:26:23<sjanssen>strictness annotations are never really needed
09:26:33<sjanssen>one can always use `seq`
09:26:43<BeelsebobWork>sjanssen: yes, but seq is just a strictness annotation
09:26:46<BeelsebobWork>@src seq
09:26:47<lambdabot>Source not found. Your mind just hasn't been the same since the electro-shock, has it?
09:26:49<mc__>beelsebobis there a safe way too?
09:26:50<BeelsebobWork>bah
09:26:58<BeelsebobWork>mc__: yes -- do something sensible on the Nothing case
09:27:40<dolio>seq x y = y, of course. :)
09:27:51<sjanssen>BeelsebobWork: ah, sorry, thought we were talking about bang patterns
09:27:53<retybok>BeelsebobWork: that's it?
09:28:04<retybok>will that really do the job?
09:28:20<BeelsebobWork>retybok: all you need to do is make sure that rnf is a function that really does evaluate something to normal form
09:28:34<BeelsebobWork>so insert appropriate bang patterns/seqs/other strictenss annotations
09:29:08<retybok>BeelsebobWork: all right, I see. Thanks!
09:29:17<mc__>BeelsebobWork: so what is wrong with this then? http://pastebin.com/m10fb0287
09:29:42<BeelsebobWork>mc__: it'll give an even less useful error in the Nothing case that what I showed you
09:29:50<BeelsebobWork>specifically, it'll give you "pattern match failure"
09:30:03<Botje>mc__: you don't have to incorporate the Maybe into the type ..
09:30:17<Botje>prop_validateInput (a,b) = .... ==> (a,b) == validateInput (Just (a,b))
09:30:48<mc__>Botje: that does not change anything
09:31:00<Botje>yes it does :)
09:31:07<Botje>it stops quickcheck from generating Nothing as input
09:31:13<Botje>which you are clearly not interested in
09:31:29<BeelsebobWork>mc__: the other option is to use the maybe function to lift a non-maybe-typed function up
09:31:56<BeelsebobWork>> maybe (\(x,y) -> x + y) (error "zomg nothing") (Just (5,6))
09:31:57<lambdabot> Overlapping instances for Show ((t, t) -> t)
09:31:57<lambdabot> arising from a use ...
09:32:02<mc__>but I still get the same error
09:32:08<Botje>what error?
09:32:08<BeelsebobWork>o.O
09:33:22<BeelsebobWork>oh, wrong way round
09:33:31<BeelsebobWork>> maybe (error "zomg nothing") (\(x,y) -> x + y) (Just (5,6))
09:33:33<lambdabot> 11
09:33:39<BeelsebobWork>> maybe (error "zomg nothing") (\(x,y) -> x + y) Nothing
09:33:41<lambdabot> mueval: Prelude.read: no parse
09:33:41<lambdabot> mueval: *** Exception: zomg nothing
09:33:49<mc__>this error http://pastebin.com/m7cbceebc
09:34:16<BeelsebobWork>mc__: well... validateInput returns a Maybe
09:34:19<BeelsebobWork>(a,b) is not a Maybe
09:34:22<BeelsebobWork>that's easy to fix
09:36:01<Botje>BeelsebobWork: if validateInput expects (a,b), why are you feeding it Maybe (a,b) ?
09:36:22<BeelsebobWork>Botje: I'm not... mc__ is
09:36:25<Botje>doh
09:36:33<Botje>ACTION slaps his irssi around a bit
09:36:36<BeelsebobWork>hehe
09:36:43<BeelsebobWork>also, I was talking bollocks about the error
09:36:46<BeelsebobWork>I managed to miss a line
09:36:51<Botje>mc__: you want prop_blah = Just (a,b) == validateInput (a,b)
09:37:27<BeelsebobWork>mc__: also, that property is rather vaccuous
09:37:37<BeelsebobWork>in that you're testing the function by running it's algorithm
09:38:11<BeelsebobWork>what may be more interesting for you to do is to write a generator that always generates valid data
09:38:18<BeelsebobWork>and remove the ==> part
09:38:51<mc__>sorry, connection problems
09:39:02<mc__>BeelsebobWork: how else should I do the test?
09:39:35<BeelsebobWork>mc__: I'm not certain in this particular case -- this may be a case of something that's untestable
09:39:45<BeelsebobWork>or at least, that exact property is
09:40:20<BeelsebobWork>how about... anything that gets through validateInput doesn't cause the rest of your program to error out?
09:47:29<mc__>BeelsebobWork: good idea
09:53:40<mc__>but for that I would first have to implement the rest of the programm, ah what should I use for storing a tictactoe board, what do you think of a map?
09:53:52<mc__>data structures are still confusing the hell out of me in haskell
09:53:56<Botje>i'd use an array,really
09:53:59<BeelsebobWork>I don't see why you would have to do that?
09:54:00<Twey>An Array, mc__
09:54:20<BeelsebobWork>you would only have to decide the output type -- most likely Either String SomethingInteresting
09:54:32<Botje>board = listArray ((0,0),(2,2)) $ repeat Nothing
09:54:46<mc__>BeelsebobWork: output type?
09:54:49<Botje>replace Nothing with whatever your "empty place" is going to be :)
09:54:50<Twey>data Piece = Nought | Cross
09:54:56<BeelsebobWork>and you wouldn't even need to know what the SomethingInteresting was to write the property
09:54:59<Twey>And the type would be Maybe Piece
09:55:06<BeelsebobWork>because all you need to know is that it doesn't produce Left _ ever
09:55:24<BeelsebobWork>(given input that validateInput said was good)
09:55:30<Botje>#haskell: parallellising your homework answers!
09:55:41<Twey>Haha
09:55:45<BeelsebobWork>:D
09:55:59<BeelsebobWork>@remember Botje #haskell: parallellising your homework answers!
09:56:00<lambdabot>Okay.
09:56:10<Twey>'s my favourite way of responding to homework questions
09:56:36<mc__>my question was not a homework question
09:56:48<Twey>Writing them in such a complex way that if the student wants to pass them off as their own, they have to actually understand all the principles involved
09:56:58<Twey>Aye, mc__, we know :)
09:57:00<BeelsebobWork>Twey: :D
09:57:24<BeelsebobWork>Twey: hardly gonna encourage them that they actually want to study haskell
09:57:37<Twey>ACTION grins.
09:57:44<Twey>Maybe not, but when you do it in Javascript it's a riot
09:57:56<BeelsebobWork>haha
09:58:08<BeelsebobWork>ACTION pushes Twey into #squirrelfish
09:58:18<Twey>#squirrelfish? What's that then?
09:58:35<BeelsebobWork>it's the channel for WebKit's javascript engine
09:58:43<BeelsebobWork>it's reasonably interesting to hang about in actually
09:58:52<Twey>Oh ah
09:59:02<BeelsebobWork>mostly to watch them bitching about how V8 is horribly broken
09:59:17<Twey>No WebKit-using browsers on Linux :(
09:59:23<BeelsebobWork>yeh there are
09:59:28<BeelsebobWork>Gnome browser does
09:59:34<BeelsebobWork>and Konqueror has the option to use it
09:59:50<BeelsebobWork>I believe they're in the process of dropping khtml
10:00:06<Twey>Konq 4?
10:00:33<BeelsebobWork>not sure -- I just know various people who have compiled it with WebKit
10:00:44<Twey>Oh ah
10:02:52<quicksilver>there is a compile of epiphany with webkit
10:02:53<quicksilver>IIRC.
10:22:33<mc__>whats wrong with this? board // ((0,0) , Just 1)
10:23:00<mc__>this is the definitoin of board: let board = listArray ((0,0),(2,2)) $ repeat Nothing
10:23:57<dancor>> let board = listArray ((0,0),(2,2)) $ repeat Nothing in board // [((0,0), Just 1)]
10:23:57<lambdabot> mueval: Unsafe functions to use mentioned.
10:24:07<dancor>anyway (//) takes a List
10:24:16<mc__>ah
10:24:22<dancor>lbot is totally wack
10:24:33<Deewiant>> array
10:24:35<lambdabot> Overlapping instances for Show ((i, i) -> [(i, e)] -> Array i e)
10:24:35<lambdabot> ...
10:24:40<Deewiant>> listArray
10:24:41<lambdabot> mueval: Unsafe functions to use mentioned.
10:24:45<Deewiant>> Array
10:24:45<lambdabot> mueval: Unsafe functions to use mentioned.
10:24:55<dancor>@ghc
10:24:56<lambdabot>ghc says: even with cunning newtype deriving the newtype is recursive
10:25:20<quicksilver>is listArray unsafe? surely not.
10:25:34<Deewiant>quicksilver: anything with "Array" in it clearly is
10:25:39<Deewiant>> let fooArray = 1 in fooArray
10:25:40<lambdabot> mueval: Unsafe functions to use mentioned.
10:25:41<quicksilver>Deewiant: why?
10:25:43<quicksilver>ah.
10:25:44<ziman>> let board = array ((0,0),(2,2)) $ zip (range ((0,0),(2,2))) (repeat Nothing) in board // [((0,0), Just 1)]
10:25:46<lambdabot> array ((0,0),(2,2)) [((0,0),Just 1),((0,1),Nothing),((0,2),Nothing),((1,0),...
10:25:48<Deewiant>> let unsafeX = 1 in unsafeX
10:25:49<lambdabot> mueval: Unsafe functions to use mentioned.
10:25:58<quicksilver>mc__: I think there is an array version of //
10:26:09<mc__>quicksilver: I'm using an array
10:26:24<quicksilver>yeah, but you need to hide the Data.List version
10:26:28<quicksilver>and make sure you get the IArray version.
10:26:29<BeelsebobWork>ACTION ponders if there's a Haskell board game DSL
10:26:31<Deewiant>Data.List has \\
10:26:34<Deewiant>it's // for arrays
10:26:37<quicksilver>oh.
10:26:44<BeelsebobWork>would be nice to have a DSL for specifying who's turn it is, how pieces can move etc
10:26:44<Deewiant>?ty (\\)
10:26:46<lambdabot>forall a. (Eq a) => [a] -> [a] -> [a]
10:26:47<Deewiant>?ty (//)
10:26:49<lambdabot>forall i e. (Ix i) => Array i e -> [(i, e)] -> Array i e
10:26:49<flux>beelsebobwork, I've wondered for a long time if there was a language for designing games
10:26:54<mc__>I think it is using the array version
10:26:55<mc__>*Main Data.Array> :t (//) (//) :: (Ix i) => Array i e -> [(i, e)] -> Array i e
10:26:58<flux>beelsebobwork, but I was thinking something more like Prolog
10:27:03<quicksilver>mc__: ok, what's the error then?
10:27:07<BeelsebobWork>that would make sense flux
10:27:11<quicksilver>mc__: "why doesn't this work" doesn't tell us much ;)
10:27:19<mc__>quicksilver: sorry
10:27:58<Deewiant>?ty ((0,0) , Just 1)
10:27:59<lambdabot>forall t t1 t2. (Num t2, Num t1, Num t) => ((t, t1), Maybe t2)
10:28:08<Deewiant>mc__: ^ that's not [(i,e)], that's (i,e)
10:28:20<flux>beelsebobwork, I've also wondered if you could express short "programs" board games - some games just appear to have quite large sets of rules, but they don't always make a set that feels coherent
10:28:41<mc__>http://pastebin.com/m39fdcd7d
10:28:44<flux>sort of like invariants that would make the game work :)
10:28:54<BeelsebobWork>hmm, that's true
10:29:29<BeelsebobWork>I guess I was thinking only of games that have sensible rule sets, like chess, checkers or the viking game
10:29:47<mc__>quicksilver: there you can see the error
10:29:55<quicksilver>mc__: I think Deewiant already answered :)
10:30:01<quicksilver>\\ takes a list.
10:30:13<quicksilver> // also
10:30:38<quicksilver>ah well, partly.
10:30:43<mc__>quicksilver: oh, now I got it
10:30:45<mc__>thank you both
10:30:50<quicksilver>what you've written is a list of two things of different types :)
10:30:52<quicksilver>that's the type error
10:30:53<flux>beelsebobwork, oh, I was thinking games such as Puerto Rico
10:31:01<quicksilver>you're missing a set of () just inside the []
10:31:07<flux>although expressing Carcassonne in a prolog-like language might be interesting..
10:31:12<BeelsebobWork>flux: yeh, it would be nice to be general enough to cover games like that
10:31:13<mc__>yeah, already have it, thank you
10:32:03<quicksilver>BeelsebobWork: I thought about it whilst working on one
10:32:17<quicksilver>BeelsebobWork: it wasn't obvious to me you could get the right balance between expressivity and elegance
10:32:28<quicksilver>BeelsebobWork: but, I need to think about it for quite a while longer.
10:33:02<BeelsebobWork>quicksilver: I think that that's why I wanted to go for a subset of board games -- i.e. ones where you take turns to move pieces about a board
10:33:20<quicksilver>ACTION nods
10:33:29<quicksilver>yes. The trick is choosing the interesting subset.
10:33:35<BeelsebobWork>yep
10:40:18<Deewiant>hpaste> Deewiant pasted "Timing various ways of snoc" at http://hpaste.org/10696
10:42:28<quicksilver>Deewiant: in the case that 'ret' is a list
10:42:35<quicksilver>Deewiant: $! is only checking if it's empty or not.
10:43:03<Deewiant>quicksilver: yes, I am aware.
10:43:11<Deewiant>in this case it's an Int, so that's fine.
10:43:20<Deewiant>the whole thing is a quick hack.
10:43:25<quicksilver>oh, I didn't read carefully enough :)
10:44:08<Deewiant>it's just forcing the computation of 'length'.
10:46:18<Deewiant>I was interested to see the (:)-reverse method perform so well, that was actually my motivation for doing the whole test.
10:46:53<Deewiant>and to prove that (++) is really almost as dubious as (!!). ;-)
10:47:08<Twey>Oo-er
10:48:38<Twey>So a ++ [b] is better written as `reverse (b : (reverse a))`?
10:48:56<Twey>What about `a ++ b`?
10:49:37<Baughn>a++b has O(length a) cost, of course
10:50:27<Baughn>That's usually fine, so long as you manage to avoid calling ++ again on the result of a++b. Call it in the expression constructing b instead - laziness to the rescue. :P
10:50:30<Deewiant>Twey: more that, if you're doing a ++ [b] repeatedly you should instead consider building up the [b]s to append with (:) and then reverse it.
10:50:51<Deewiant>and if you're doing a lot of ++, consider DList.
10:52:17<Deewiant>correction: for the former, it's not "consider", it's "definitely do it by". :-)
10:52:19<Twey>Baughn: But then doesn't reverse (b : reverse a) have O(length a^2)?
10:52:40<Baughn>Twey: Eh? No, that'd be O(2*length a)
10:52:52<Twey>ACTION thinks.
10:52:54<Twey>Oh aye.
10:52:56<Twey>Sorry, I'm ill :-P
10:53:07<Twey>Still, it's more expensive than a ++ [b]
10:53:07<Baughn>I don't see how it could possibly be better than a ++ [b], though
10:53:16<Baughn>Yeah. That's just /one/ copy.
10:53:25<Twey>Laziness?
10:53:25<Axman6>test it
10:53:30<Deewiant>Doing n snocs with ++ to a list of length l is O(l*n)
10:53:47<Deewiant>Whereas with (:) and reverse, it's O(l + n).
10:53:50<Deewiant>I think.
10:53:55<Baughn>Well, true
10:54:05<Twey>Er, for my poor dumb brain before we proceed further: what's a snoc? A cons in reverse?
10:54:10<Baughn>That's if you reverse once at the end. With just one snoc, it doesn'T help
10:54:12<Deewiant>Twey: append one element to the end, yeah.
10:54:21<Twey>Ah
10:54:32<Twey>Right
10:54:49<Twey>So why isn't ++ defined in terms of reverse and (:)?
10:54:54<Baughn>Twey: So: If you *must* snoc repeatedly, use reverse twice instead - or Seq, perhaps. But preferably, build up lots of bs before appending them to a
10:55:11<quicksilver>Twey: because the win is only there if you (++) more than once.
10:55:11<Baughn>Twey: Because it'd be slower
10:55:16<quicksilver>Twey: ++'ing once is fine.
10:55:22<Twey>Oh right.
10:55:28<Twey>I seeee.
10:55:32<quicksilver>so you'd need a clever fusion rule to notice multiple (++)s
10:55:40<Baughn> ((a ++ b) ++ c) ++ d is bad
10:55:42<quicksilver>which would be neat, but like all rule approachs static only.
10:55:43<Twey>ACTION nods.
10:55:45<Twey>It makes sense now.
10:55:47<Baughn>a ++ (b ++ (c ++ d)) is good
10:55:51<quicksilver>and if this occurs in real programs, I bet it isn't static.
10:55:53<Baughn>(And does the same thing, of course)
10:56:19<Deewiant>quicksilver: what do you mean, static?
10:56:29<quicksilver>Deewiant: visible in the source
10:56:36<Deewiant>gotcha.
10:56:38<quicksilver>possibly after some inlining and so on.
10:56:40<Baughn>Deewiant: Not triggered at runtime
10:56:46<Baughn>Which would be nice, too
10:56:55<quicksilver>'visible with purely syntactic analysis'
10:57:07<quicksilver>GHC's optimisations are all syntactic (like all compilers)
10:57:15<quicksilver>sometimes you wish the RTS could spot things dynamically
10:57:22<quicksilver>like hotspot.
10:57:24<Baughn>Has anyone looked at adding support for that?
10:57:36<quicksilver>in the specific context of GHC, not as far as I know.
10:57:43<quicksilver>it's hard because GHC erases so much
10:57:46<Baughn>..true, but hotspot is much slower than ghc. Clearly, static analysis is a larger win if you must have one
10:57:56<quicksilver>(and brining back what it erases is a cost)
10:58:05<quicksilver>actually hotspot is much faster than GHC
10:58:10<quicksilver>for a hundred different reasons.
10:58:44<quicksilver>the general problem has been the subject of lots of research I have no doubt.
10:58:45<Baughn>Hm. Wait, hotspot isn't the default java interpreter?
10:59:11<Deewiant>it is, it's the Sun JVM.
10:59:26<Baughn>Thought as much
10:59:41<quicksilver>hotspot is faster than compiled C, in those cases where the JIT really kicks in.
10:59:42<Baughn>..so how come java applications all come across as sluggish, and it scores badly in the shootout?
10:59:50<quicksilver>if that matters in real programs is up for discussion.
11:00:06<Deewiant>java applications come across as sluggish mostly because the JVM takes 10 secons to start up, in my experience.
11:00:12<Axman6>Baughn: think they usually take a long time to initialise
11:00:14<quicksilver>it's a very impressive piece of software engineering.
11:00:33<Deewiant>as for its shootout scores, it beats GHC in the single core benchmarks, for instance.
11:00:38<Axman6>i think sun cop a lot of bad press for a lot of good work
11:00:59<quicksilver>there are some really bad things about java
11:01:09<Deewiant>as can be seen at http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=java&lang2=java the biggest problem is the startup time.
11:01:10<quicksilver>but they are mostly in the libraries and to some extent the language design.
11:01:12<lambdabot>Title: Java 6 -server benchmarks | Gentoo : Intel® Pentium® 4 Computer Language Bench ..., http://tinyurl.com/r88cc
11:01:19<quicksilver>sun's VM is pretty impressive.
11:01:34<Deewiant>when it actually starts running code, it's C++-level.
11:01:37<matthew-_>sun's VM is in many cases world leading
11:01:46<matthew-_>the hotspot system is awesome
11:01:48<Axman6>java -server adds to the startup time i think, but it's faster at running things
11:02:03<Baughn>I see. Then it would be very interesting to see the shootout rwith long-running tests
11:02:16<Deewiant>yeah, -server just means that it JITs the whole code at startup.
11:02:17<matthew-_>Axman6: yeah, it makes the profiler work harder and more code gets compiled to native
11:02:18<Baughn>Say, chop off the first eight iterations, only count the last two
11:02:32<Deewiant>Baughn: the startup time isn't included in the other benchmarks.
11:02:51<Baughn>Deewiant: The optimization time would be, though
11:02:54<Deewiant>I don't think, anyway, since otherwise all the times would be >= the startup time, which they clearly aren't. :-)
11:03:15<Deewiant>Baughn: yeah, but it kinda has to be, because that's part of the actual runtime
11:03:27<Baughn>Perhaps it caches those calculations? They'd be the same every time, right?
11:03:54<Deewiant>What do you mean?
11:04:48<Baughn>Well, with all this runtime optimization - and long startup times - it would make sense to cache that for the next time you run the program
11:05:01<Deewiant>Baughn: you mean this? http://shootout.alioth.debian.org/gp4/faq.php#dynamic
11:05:03<lambdabot>Title: Read the FAQ! | Gentoo : Intel® Pentium® 4 Computer Language Benchmarks Game
11:05:49<Baughn>Deewiant: Thanks. ^_^
11:05:54<Deewiant>:-)
11:06:11<Baughn>Although what I meant was, java should be storing the optimizations for reuse in the next invocation
11:06:59<Baughn>..that's... a rather unimpressive graph
11:07:58<Deewiant>I'm still not clear on what you're after with "the optimizations". It profiles code at runtime and then aggressively optimizes the hot spots---all it remembers thereafter is that there was a hot spot at point X in the code, which has been optimized. (I guess, anyway.)
11:08:18<Deewiant>Do you mean it should remember that the bytecode foo,bar,baz can be optimized to qux?
11:08:39<Baughn>Or that spot foo, in class-file bar with hash baz, can be optimized to qux
11:09:00<Deewiant>Why would it remember that? It's already optimized it. :-)
11:09:12<Baughn>For the next time you run the application. -_-
11:09:21<Baughn>That'd only be important if the benefit was actually large, though. The graph suggests it isn't
11:10:11<Deewiant>Meh, I wouldn't like it storing optimization information in an on-disk database
11:10:38<Axman6>couldn't it just modify the .class files?
11:11:27<Baughn>Axman6: It might want to optimize them differently later, under different loads
11:11:38<Baughn>Or the user might want to copy said file to a different computer
11:11:57<Axman6>ah yeah, optimises to native code doesn't it
11:39:33<BeelsebobWork>ACTION really doesn't get why people insist on using the GPL or it's variants
11:40:26<quicksilver>no? it's not all that hard to understand si it?
11:40:40<quicksilver>they want to write free software and they want anyone else building on their work to keep it free?
11:40:55<Zao>So basically, blackmail.
11:41:07<BeelsebobWork>"keep" it free -- it's not free
11:41:14<BeelsebobWork>if it was free, that restriction wouldn't be there
11:41:20<SamB_XP>well, consider what MS would do given half a chance ...
11:41:24<quicksilver>well for one very precise and particular definitoin of free
11:41:33<quicksilver>I agree they redefined the word, but let's not argue about definitions?
11:41:36<Zao>SamB_XP: Your bashing is rather irrelevant to the discussion.
11:41:39<BeelsebobWork>SamB_XP: okay, considering -- they might actually use some GPLed code and make windows more compatible with it?
11:41:56<SamB_XP>compatible ?
11:41:57<SamB_XP>what ?
11:41:58<quicksilver>"they want to write gnuish software and wany anyone else building on their work to keep it gnuish" ?
11:42:02<Zao>SamB_XP: So what if they use your free library to improve interoperability of the OS or their products.
11:42:07<Zao>I do not see any problems with that.
11:42:11<quicksilver>Zao: no it's nothing like blackmail, don't be ridiculous.
11:42:13<BeelsebobWork>SamB_XP: maybe if they were able to use the code they would be able to use it to interact well with others
11:42:18<BeelsebobWork>instead af having to completely reimplement everything
11:42:19<SamB_XP>Well, I think it's more relevant to applications
11:42:21<Zao>"I don't earn anything, and thus should no-one else"
11:42:24<quicksilver>Zao: blackmail is when I demand money in order to no expose pictures of your boyfriend.
11:42:41<SamB_XP>quicksilver: ... Zao is gay?
11:42:48<quicksilver>I don't know, or mind.
11:42:52<quicksilver>that's not the point ;)
11:42:53<Zao>SamB_XP: News to me.
11:42:55<SamB_XP>or perhaps a girl?
11:44:06<mm_freak>is there some preferred method to extract a range of elements from a mutable array, do reordering and then put them back? in-place would be great
11:44:28<quicksilver>I can entirely understand people not agreeing with the notion, and don't intend to argue.
11:44:38<quicksilver>however I can't understand people not *understanding* the notion ;)
11:44:41<quicksilver>it seems clear enough.
11:44:50<SamB_XP>yeah, it's not actually blackmail
11:45:01<BeelsebobWork>quicksilver: well to me it's a contradiction in terms -- they want things to be free... yet they don't make it free
11:45:17<SamB_XP>BeelsebobWork: so ... they don'
11:45:30<quicksilver>they have chosen a different definition of free, to you.
11:45:32<SamB_XP>t have the BSD definition of Free ...
11:45:34<BeelsebobWork>they impose constraints on work that *I* do, not work that they do in fact
11:45:47<quicksilver>and to be fair, they go to enormous lengths to explain why they made that choice.
11:45:57<quicksilver>there are essays and treatises on the subject :)
11:46:03<Deewiant>and the constraints are essentially that you don't impose any additional constraints on others.
11:46:10<BeelsebobWork>quicksilver: I think the enormous lengths they go to are perhaps an indication that it's a non-obvious thing to do
11:46:22<quicksilver>yes, it's non-obvious.
11:46:28<SamB_XP>it made sense at the time!
11:46:31<vegai>GPL is fine, but admittedly they claiming it's the Freest Freedom in all of Freestania is a bit dishonest
11:46:35<SamB_XP>and sometimes it makes sense now
11:46:35<BeelsebobWork>Deewiant: exactly -- a contradiction -- they're imposing constraints on me and *my* work -- not on their work at all
11:46:36<quicksilver>But most things which are against established orthodoxy are non-obvious.
11:47:29<Deewiant>BeelsebobWork: yes, that's the license. Whether it's a contradiction or not depends on your definition of "free as in speech". :-)
11:47:32<SamB_XP>BeelsebobWork: they don't wan't you wresting control of the project away from free codebases...
11:47:38<quicksilver>In any case with due respect I'm going to call "off-topic" on this one.
11:47:46<quicksilver>Let's take it to -blah if we're interested.
11:47:53<BeelsebobWork>that's true
11:48:07<SamB_XP>does that mean we get to include more sex in the discussion?
11:48:12<quicksilver>I've seen this conversations run and run and I don't want it to happen here.
11:54:16<mm_freak>hmm… haskell's array functionality is quite limited =/
11:55:34<Cale>mm_freak: oh?
11:55:53<Cale>mm_freak: What's missing?
11:57:14<mm_freak>Cale: simple functions like elemsRange, swapArray, etc.
11:57:39<Axman6>swapArray?
11:57:40<Cale>elemsRange?
11:57:48<mm_freak>elemsRange like: get (MArray) or be (IArray) the list of elements from a certain range
11:58:00<mm_freak>swapArray (MArray) like swap two elements
11:58:10<mm_freak>i reinvent the wheel all the time, when writing array code
12:00:36<Deewiant>swapArray a i j = do i' <- readArray a i; j' <- readArray a j; writeArray a i j'; writeArray a j i'
12:00:52<Cale>The first is just map (a !) (range (u,v)), or [a ! i | i <- range (u,v)], of course.
12:01:18<mm_freak>Deewiant: yes, i've written that function a million times… and that's exactly the point
12:02:12<mm_freak>Cale: sure, but what is it for a mutable array? sure, you can come up with a function quickly, but it's wasted effort to do that all the time, and the performance sucks
12:02:54<Deewiant>mapM (readArray a) (range (u,v))
12:03:46<mm_freak>it's just like for most interactive programs i reinvent a lot of monad functions all the time
12:03:51<mm_freak>particularly 'while'
12:03:59<Cale>mm_freak: What's wrong with the performance of those?
12:04:11<Deewiant>whenM, ifM, whileM, yeah
12:04:44<mm_freak>Cale: compared to equivalent C code it's bad, according to my benchmarks
12:05:15<Cale>mm_freak: C code which builds a linked list?
12:05:44<mm_freak>Cale: in many cases the list building isn't necessary… you can avoid that easily in C
12:05:44<rhox>hello, may someone help me with this http://pastebin.com/m464456b5 ?
12:06:03<mm_freak>Cale: of course, if you add the development time, haskell is still much faster in most cases
12:06:08<mm_freak>but IMO it could be done better
12:06:36<mm_freak>Deewiant: whenM is there (simply 'when'), for ifM you'd just use the regular 'if' or 'case'
12:06:43<Cale>Well, you might hope for map fusion, but if the map isn't fusing, you could of course do it by hand.
12:06:48<mm_freak>Deewiant: but while is missing
12:06:58<Cale>(which would be still not quite as ugly as the C code ;)
12:07:25<Deewiant>mm_freak: whenM and ifM take m Bool, not Bool
12:07:34<Deewiant>very handy in my experience
12:07:35<mm_freak>hmm… maybe i should become a base lib developer =)
12:07:51<mm_freak>Deewiant: oh, never heard of them
12:08:10<mm_freak>but what would they do other than extract the bool and check it?
12:08:28<besiria> i think i saw somewhere sth about removing monomorphism restriction
12:08:28<Deewiant>whenM a b = do a' <- a; when a (b >> return ())
12:08:31<besiria> in haskell' , is that true?
12:09:06<ivanm>rhox: you're mixing pure code with unpure
12:09:21<ivanm>if you want to define pure variables in IO (), you need to use let
12:09:27<quicksilver>besiria: yes.
12:10:06<mm_freak>Deewiant: well, that would save a few characters of typing, but somehow it would feel incorrect to me
12:10:12<mm_freak>i'd prefer to extract explicitly
12:10:49<Deewiant>I've been thinking of writing a GHC extension that allows me to write "if <- foo" instead of "x <- foo; if x"
12:11:25<besiria>ACTION loves eta reduction
12:11:48<mm_freak>Deewiant: why? we have enough sugar already, don't you think? really, that one additional line you need to write wouldn't kill you =)
12:12:12<Twey>rhox: You basically just forgot your 'let' keyword.
12:12:30<Deewiant>mm_freak: it's so common in my code that it's beginning to annoy me
12:12:32<Zao>You should make it C-style and do if *foo
12:12:39<mm_freak>Deewiant: short code is often a virtue, but also often a nightmare
12:13:01<Deewiant>mm_freak: I think it's much worse to have a variable called "x'" which is used only once
12:13:54<mm_freak>true… maybe 'if' should be a function instead of a language construct
12:14:12<Deewiant>I'd still have to write ifM
12:14:38<paczesiowa>and flip it inside-out
12:14:38<mm_freak>not with a "swapped if"
12:14:59<mm_freak>if' a b p = if p then a else b
12:15:06<mm_freak>getSomeBool >>= if' whenTrue whenFalse
12:15:22<zeno>anyone on ubuntu get yi running?
12:15:26<Deewiant>yeah, and I'd still write ifM. ;-)
12:15:57<paczesiowa>zeno: are you trying hackage or darcs?
12:16:12<zeno>parodyoflanguage: with cabal
12:17:03<paczesiowa>zeno: I had plenty of problems with installing that, try darcs version that worked out of the box
12:17:23<mm_freak>Deewiant: well… go ahead… fortunately most auxilliary functions you have to rewrite all the time are in fact one-liners
12:17:24<zeno>yi-0.4.6 depends on Cabal-1.4.0.2 which failed to install. cabal --version using version 1.4.0.2 of the Cabal library
12:17:37<zeno>paczesiowa: thanks
12:18:06<paczesiowa>zeno: 0.4.6? I did that when 0.4.4 was out so maybe they fixed it and broke other stuff
12:18:26<Deewiant>mm_freak: including while. ;-)
12:19:13<mm_freak>Deewiant: yeah, sure
12:19:17<mm_freak>it's just annoying =)
12:19:43<mm_freak>while p x c = if p x then c x >>= \y -> while p y c else return x
12:19:45<mm_freak>all the time
12:19:48<mm_freak>all over again
12:19:50<byorgey>@seen solrize
12:19:51<lambdabot>solrize is in #haskell. I last heard solrize speak 7h 19m 38s ago.
12:19:51<Deewiant>once per project
12:19:58<byorgey>solrize: you were looking for me?
12:20:05<mm_freak>yeah, but i have a lot of small one-filers ;)
12:20:44<Deewiant>mm_freak: make a private "utils" package and have them depend on that :-P
12:21:05<mm_freak>since as soon as you get used to haskell, you hack up things quite fast, if you wouldn't have to write the same aux functions all over again, you'd probably save most of development time =)
12:21:44<Deewiant>yep
12:29:23<mm_freak>hmm… it's sad that the GHC devs had to abandon darcs… that turned a lot of people away from haskell and placed its maturity into question
12:29:44<mm_freak>many people believe that haskell is almost useless in the real world
12:30:23<Philippa>tbh, I'm not sure how many people that's affected who weren't having poison dripped into their ears by Jon Harrop
12:30:46<mapreduce>darcs just has some algorithmic problems, I thought.
12:30:46<quicksilver>mm_freak: I think it was a very hard decision to take for exactly that reason.
12:30:55<mapreduce>That aren't related to Haskell.
12:31:01<quicksilver>yes, the problem with darcs was not haskell.
12:31:10<quicksilver>but of course mm_freak is right that it didn't 'look good'
12:31:14<mapreduce>Then all is well.
12:31:19<jeffz>mm_freak: who did it turn away?
12:31:27<mapreduce>Haskell is better off without people who react like that.
12:31:37<quicksilver>the way to show that haskell is mature is to provide counter exaples
12:31:42<quicksilver>not worry about failures
12:31:52<quicksilver>if we all write one excellent haskell application
12:32:02<quicksilver>which breaks new ground, leads its field, and people love it
12:32:05<quicksilver>there will be no more doubt
12:32:08<quicksilver>who's up for that? ;)
12:32:16<quicksilver>(one each, I mean, of course)
12:32:22<mapreduce>ACTION hears a pin drop.
12:32:23<mm_freak>jeffz: a few people i know, some of which i convinced of haskell myself
12:32:42<mm_freak>quicksilver: but what?
12:32:55<Philippa>mm_freak: were they aware that darcs is in many regards a research project? That it's not just a clone of systems that already existed?
12:33:01<mapreduce>mm_freak: Are you actually short of ideas?
12:33:13<mapreduce>Every time I use software I have ideas about how it could be better. :)
12:33:27<mm_freak>unfortunately many haskellers are so busy with theory that they aren't even interested in real world apps… haskell is a true virtue for theoreticians
12:33:48<Philippa>mm_freak: I think that's quite the misunderstanding too
12:33:50<mapreduce>mm_freak: Can you give an example of such a haskeller?
12:33:51<mm_freak>mapreduce: yeah, but then you look at how much effort it takes to rewrite it in a new language
12:34:08<mm_freak>mapreduce: me
12:34:20<Philippa>the theoretician contingent's pretty small, enough that I start to look that way
12:34:20<zeno>ok got it to install, but Yi.Mode.Shim could not be found
12:34:26<quicksilver>mm_freak: I'm writing a couple of games, some visualisation applications, a true relational database with full serialisation and synchronous replication and its own query language, and a Reactive-based network server framework.
12:34:31<Philippa>(admittedly there are other reasons for that - I'm not good at getting stuff done full stop)
12:34:37<quicksilver>mm_freak: so I reckon I have two or three of us covered.
12:34:44<BONUS>or that guy who writes Comonad.Reader
12:34:51<quicksilver>unfortunately I have a job ;(
12:34:57<Philippa>what is true is that the biggest cases of real world haskell uses are behind NDAs or stronger
12:35:26<quicksilver>oh yes, there is also my secret investment product which was single-handedly responsible for the last 9 months of financial turmoil
12:35:30<quicksilver>but I'm not allowed to talk about it
12:35:39<quicksilver>(sorry about the mess, guys, but it made my clients very rich)
12:35:45<Deewiant>heh
12:35:49<quicksilver>could never have done it without haskell.
12:35:56<zeno>quicksilver: cool I just started a game server maybe ill use your framework :)_
12:35:57<mm_freak>don't get me wrong… IMO haskell is great
12:36:29<mm_freak>but unfortunately not everybody likes to bother with the theory behind it… those who do are mostly actually quite interested, and those who don't fail to use haskell
12:37:01<Philippa>mm_freak: what do you have in mind with "the theory behind it"?
12:37:34<mm_freak>Philippa: particularly monads and what it means to be "purely functional"
12:37:35<Philippa>(FWIW, I know a number of intermittent dabblers who're slowly building to the point of being ready to use it for their real world apps, they just don't have time to absorb that much new stuff in one sitting)
12:37:50<besiria>> <besiria> i think i saw somewhere sth about removing monomorphism restriction
12:37:50<besiria><besiria> in haskell' , is that true?
12:37:50<besiria>*** #haskell modes: +tnc
12:37:50<besiria>*** #haskell was created on Sunday 2006/11/26 8:42:48 AM
12:37:51<lambdabot> mueval: Prelude.read: no parse
12:37:54<besiria><Deewiant> whenM a b = do a' <- a; when a (b >> return ())
12:37:57<besiria>*** seafood (n=sseefrie@220-244-208-214.static.tpgi.com.au) has quit:
12:38:00<besiria><ivanm> rhox: you're mixing pure code with unpure [15:09]
12:38:04<besiria><ivanm> if you want to define pure variables in IO (), you need to use let
12:38:05<besiria><quicksilver> besiria: yes.
12:38:08<besiria><mm_freak> Deewiant: well, that would save a few characters of typing, but
12:38:10<Philippa>mm_freak: which is a problem because 1) you don't need theory for monads and 2) you /need/ to get the consequences of being purely functional and that's not a matter of theory
12:38:11<besiria> somehow it would feel incorrect to me [15:10]
12:38:15<besiria>*** paczesiowa (n=paczesio@87-205-177-246.adsl.inetia.pl) has joined channel
12:38:18<besiria> #haskell
12:38:21<besiria><mm_freak> i'd prefer to extract explicitly
12:38:24<besiria>*** binrapt (i=binrapt@e180073079.adsl.alicedsl.de) has joined channel
12:38:26<ivanm>besiria: ummmm.... what are you doing and why?
12:38:27<osfameron>being unforgiving of minor mistakes is great for robust mission critical stuff, but it does make it hard to get started for "just good enough" real world apps
12:38:33<quicksilver>ivanm: he accidentally pasted.
12:38:40<ivanm>ahhh
12:38:54<quicksilver>slip of the finger I imagine :)
12:39:11<Philippa>mm_freak: tbh, that's not even about theory, it's "don't wanna learn a new paradigm"
12:39:19<ivanm>I just saw my name pop up and was wondering why he'd pasted my previous two messages, then saw that he was pasting _everyone's_ ;-)
12:39:21<besiria>sry
12:39:25<quicksilver>besiria: it's OK :)
12:39:31<quicksilver>besiria: finger slipped I imagine?
12:39:37<mm_freak>Philippa: well, if you don't understand monads, at some time you'll arrive at a point where your code works but you just don't understand it yourself
12:39:37<besiria>quicksilver: exactly
12:39:48<quicksilver>it took me a while to remember that you can ban without kicking
12:39:54<quicksilver>and that effectively silences someone.
12:39:59<SamB_XP>oh does it?
12:40:01<quicksilver>I'm not much good at this IRC lark.
12:40:02<SamB_XP>cooooool
12:40:02<quicksilver>ACTION nods
12:40:32<quicksilver>in a way it's a shame that irc clients have the anti-flood feature
12:40:32<Deewiant>I'd've kicked without banning personally :-P
12:40:39<mm_freak>Philippa: not using a language (no matter how great it is) is better than not understanding your own code
12:40:45<quicksilver>otherwise they'd get sorted automatically.
12:40:52<mm_freak>(unlambda being an exception) =)
12:41:04<besiria>> mconcat (fromList ["foo","bar"])
12:41:05<lambdabot> mueval: Prelude.read: no parse
12:41:11<Philippa>mm_freak: there's an awful lot of STL users don't understand the innards of the STL, to pick an example
12:41:15<zeno>@src unlambda
12:41:15<lambdabot>Source not found. Sorry.
12:41:19<Philippa>being willing to go a while without getting it all is important
12:41:33<Philippa>come back and understand monads more later on, like when you're starting to build your own
12:41:37<zeno>@hoogle unlambda
12:41:38<lambdabot>package unlambda
12:41:44<quicksilver>Philippa: I wouldn't be surprised if 100% of them didn't understand the entire innards :)
12:41:44<mm_freak>Philippa: yes, but they understand their own code… that's a difference… although they don't understand templates well, they know why their code works the way it does
12:41:45<Philippa>(and even then, you don't need to know the categorical definition let alone understand it)
12:42:07<Philippa>mm_freak: and all you need to understand is return, >>= and the associated type constructor
12:42:25<Philippa>oh okay, and the desugaring for do I guess
12:42:43<Philippa>but you can get by on return, do and the constructor for your own code, even
12:43:03<mm_freak>Philippa: until i understood the list monad, the code (do x <- [1,2,3]; y <- [4,5,6]; return (x+y)) appeared extremely confusing to me, so i wouldn't use it
12:43:15<mm_freak>sure, understanding haskell monads, that code gets quite self-explaining
12:43:19<mm_freak>but until then…
12:43:26<Philippa>mm_freak: sure. So don't use the list monad until then
12:43:51<mm_freak>yeah and now mix that with the bad habit of most people to be lazy to learn new stuff
12:44:05<Philippa>and they don't learn the list monad until they've got a strong use case for it. Big deal?
12:44:08<besiria>> mconcat ["foo","bar"]
12:44:09<Botje>they'll be the first against the wall when the revolution comes
12:44:09<skorpan>how do you group a list of elements into groups of three?
12:44:10<lambdabot> "foobar"
12:44:19<Botje>@where chunk
12:44:19<lambdabot>I know nothing about chunk.
12:44:20<Botje>damn
12:44:23<Botje>@src chunk
12:44:23<lambdabot>Source not found. My pet ferret can type better than you!
12:44:26<byorgey>ah, chunk =)
12:44:26<Philippa>now if people're having similar trouble with error and state monads that's more problematic
12:44:29<Botje>silly lambdabot.
12:44:39<Philippa>but list's weird because it's effectively writing a local program in a whole unfamiliar paradigm
12:44:39<byorgey>most-asked for function that's not actually in the standard libraries.
12:44:41<Philippa>of course it's confusing!
12:44:54<besiria>> mconcat (fromList ["foo","bar"] :: Seq String)
12:44:57<lambdabot> mueval: Prelude.read: no parse
12:45:04<besiria>?
12:45:20<quicksilver>skorpan: chunksOf n = takeWhile (not.null) . map (take n) . iterate (drop n)
12:45:21<Botje>anyway, skorpan: unfoldr (\l -> if null l then Nothing else Just ( splitAt 3 l)
12:46:12<byorgey>besiria: weird, maybe Seq isn't imported
12:46:22<Deewiant>> empty :: Seq String
12:46:24<lambdabot> Ambiguous occurrence `empty'
12:46:24<lambdabot> It could refer to either `Control.App...
12:46:24<Botje>I just noticed this is really unfoldr (\l -> (splitAt 3) `fmap` listToMaybe l)
12:46:27<byorgey>besiria: wait, that wouldn't typecheck anyway
12:46:29<byorgey>@type mconcat
12:46:30<lambdabot>forall a. (Monoid a) => [a] -> a
12:46:35<byorgey>mconcat only works on lists
12:46:47<quicksilver>Botje: no it's not.
12:46:55<quicksilver>Botje: listToMaybe only gives you the first item.
12:46:59<Botje>oh
12:47:02<Botje>that's so sad
12:47:09<Botje>it looks so beautiful otherwise :)
12:47:12<quicksilver>;)
12:47:31<Deewiant>?pl \x -> if null x then Nothing else Just x
12:47:31<lambdabot>ap (flip if' Nothing . null) Just
12:47:47<quicksilver>it's (guard . null $ l) >> return (splitAt 3 l)
12:48:01<quicksilver>which is morally
12:48:15<Deewiant>?src guard
12:48:16<lambdabot>guard True = return ()
12:48:16<lambdabot>guard False = mzero
12:48:16<Botje>ugly :(
12:48:16<quicksilver>(guard . null) >> (return . splitAt 3)
12:48:28<quicksilver>but you need ReaderT constructors in there
12:48:32<quicksilver>to make it work in haskell.
12:49:14<quicksilver>(other wise it thinks you're working in the l -> a monad, not the l -> Maybe a monad)
12:49:21<quicksilver>(and I meant MaybeT constructors, not ReaderT)
12:49:36<quicksilver>I think this is an expressivity hole
12:49:39<quicksilver>but I don't know how to patch it.
12:50:27<Botje>compile with -XTelepathy
12:50:36<besiria>> mconcat (toList (fromList ["foo","bar"] :: Seq String))
12:50:37<lambdabot> mueval: Prelude.read: no parse
12:50:44<Deewiant>> fromList
12:50:46<lambdabot> mueval: Prelude.read: no parse
12:50:54<Deewiant>doesn't know about it
12:53:05<mm_freak>Philippa: i wouldn't have a problem with that since it's precisely the way i learned haskell
12:53:14<mm_freak>i don't understand arrows, so i don't use them
12:53:48<quicksilver>that's very odd.
12:53:51<quicksilver>> Data.Sequence.fromList
12:53:52<lambdabot> Overlapping instances for Show ([a] -> Data.Sequence.Seq a)
12:53:53<lambdabot> aris...
12:53:57<quicksilver>^^ this error says its in scope
12:54:00<quicksilver>> Data.Sequence.fromList ["foo","bar"]
12:54:01<lambdabot> Not in scope: `Data.Sequence.fromList'
12:54:10<quicksilver>^^ this one says it isn't.
12:54:12<quicksilver>wtf ?
12:54:25<besiria>wow i found a bug. im so proud :)
12:54:46<Deewiant>lambdabot is so broken these days
12:57:50<besiria>how could i concat Seq?
12:58:07<Deewiant>foldr append empty
12:58:28<Deewiant>where append = (><)
12:58:43<besiria>thx
12:58:53<Deewiant>?src concat
12:58:53<quicksilver>or use mconcat
12:58:53<lambdabot>concat = foldr (++) []
12:58:56<quicksilver>:t mconcat
12:58:58<lambdabot>forall a. (Monoid a) => [a] -> a
12:59:07<quicksilver>which is the natural generalisation of concat :)
12:59:28<quicksilver>well if you have a list of seqs
12:59:32<quicksilver>rather than a seq of seqs
12:59:33<besiria>quicksilver: but first i need to do sth like toList, right?
12:59:40<quicksilver>which do you have? a seq of seqs?
12:59:48<besiria>o Seq of Strings
12:59:52<Deewiant>quicksilver: no, in any case, since foldr is of course Data.Foldable.foldr ;-)
12:59:56<quicksilver>oh, a Seq of strings.
13:00:01<geezusfreeek>:t Data.Foldable.fold
13:00:02<lambdabot>forall (t :: * -> *) m. (Monoid m, Data.Foldable.Foldable t) => t m -> m
13:00:06<geezusfreeek>:)
13:00:06<quicksilver>and you want 1 string, not 1 seq
13:00:14<besiria>quicksilver: yeap
13:00:16<quicksilver>yes, then you want just plain "fold"
13:00:19<Deewiant>besiria: Data.Foldable.concat
13:00:21<quicksilver>as geezusfreeek showed.
13:01:29<geezusfreeek>@src Data.Foldable.concat
13:01:29<lambdabot>Source not found. Your mind just hasn't been the same since the electro-shock, has it?
13:01:40<geezusfreeek>well, it's concat = fold
13:03:50<besiria>wow , beautiful! fold,concat is the great haskell thing i learned this day
13:06:17<Deewiant>Foldable and Traversable should be in the Prelude
13:07:38<geezusfreeek>ACTION always wishes for more generic functions in the prelude and less specific ones
13:07:45<geezusfreeek>well, almost always
13:07:49<Deewiant>always
13:08:23<geezusfreeek>if i rephrase to say more polymorphic and less monomorphic then i can say always
13:09:17<Philippa>mm_freak: non-determinism's a lot weirder than pure FP though :-)
13:11:15<mm_freak>Philippa: i get it quite well and since then i've found a lot of uses for it =)
13:12:03<Philippa>fair enough. You can see why I think the list monad's a bit of a "don't do that, then" case though?
13:12:10<subconscious>Can you put algorithms through lenses?
13:16:23<besiria>i wish Prelude.map was fmap and Prelude.concat was Data.Foldable.concat
13:17:14<Araneidae>I don't know if this is OT: the Ubuntu libghc6-cabal-dev depends on ghc6 == 6.6.1. In other words, it refuses to install with ghc 6.8.2 installed! This make sense to anybody?
13:17:21<osfameron>what would be the disadvantage of that?
13:17:32<osfameron>the error messages of a simple map on a list would be harder to read?
13:18:09<Deewiant>yep, that's about it
13:18:24<subconscious>I don't agree with tha
13:18:32<subconscious>I think the error messages are not harder to read
13:20:28<Deewiant>it's like getting "no instance of Num Char" instead of "expected an Int, got a Char"
13:21:37<byorgey>Araneidae: that's strange indeed.
13:21:47<BeelsebobWork>I would love Prelude.map to be implemented in terms of fmap
13:22:06<BeelsebobWork>but to actually *make it* fmap I think is too far -- it's a specialisation for the common case
13:22:14<BeelsebobWork>and documents the fact that you're using lists in your code
13:22:51<Araneidae>byorgey, there seems to be a bug report: https://bugs.launchpad.net/ubuntu/+source/haskell-cabal/+bug/231099
13:22:58<geezusfreeek>if i define a function which turns out to be polymorphic, i'd rather document that than the fact that i originally intended it to be for lists
13:22:59<lambdabot>http://tinyurl.com/5y6pu6
13:23:10<Araneidae>Think I'll install from source instead!
13:23:13<ddarius>Beelsebob: What do you care how map is implemented?
13:23:54<BeelsebobWork>ddarius: I don't really -- but I do care that it's a specialisation of fmap, not fmap itself
13:24:08<BeelsebobWork>similarly, I care that (.) is a specialisation, and not fmap itself
13:24:50<Deewiant>there's a clear advantage in being able to write "f . g . h" instead of "fmap f (fmap g h)"
13:25:07<geezusfreeek>> (5 +) . [1, 2, 3, 4, 5]
13:25:08<lambdabot> Couldn't match expected type `a -> t' against inferred type `[a1]'
13:25:15<ddarius>Beelsebob: Do you care that map isn't generalized because you think it is a bad idea or do you care simply because it is not H98?
13:25:16<BONUS>uh you mean f . g $ h
13:25:17<geezusfreeek>i thought lambdabot was all hacked up for that
13:25:26<Deewiant>geezusfreeek: not since it broke (i.e. mueval)
13:25:27<geezusfreeek>:t (.)
13:25:28<lambdabot>forall b c a. (b -> c) -> (a -> b) -> a -> c
13:25:33<geezusfreeek>oh
13:26:58<Araneidae>Hum. Bit puzzled about versioning of cabal. http://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package tells me to install version 0.5.2, but the (broken) Ubuntu package claims to install 1.1.3. Eh?
13:27:00<lambdabot>Title: Cabal/How to install a Cabal package - HaskellWiki, http://tinyurl.com/2ack74
13:27:12<subconscious>I would like to have f ∘ g ∘ h
13:27:12<geezusfreeek>BONUS: no Deewiant meant f . g . h in this case. f . g $ h would be fmap f (g h)
13:27:39<BONUS>oh i see
13:28:28<Araneidae>Oh good grief: that version must be ancient. There's a 1.4.0.2 out there!
13:28:38<BeelsebobWork>there's a 1.5.5 out there
13:28:44<BeelsebobWork>although that's unstable
13:28:44<Araneidae>where?!
13:28:50<Araneidae>ok, I'll stick with stabl
13:28:52<Araneidae>e
13:29:02<Deewiant>1.4.0.1 has worked fine for me so far
13:29:07<BeelsebobWork>version numbering is the same as linux's old system -- odds are unstable, evens are stable
13:29:28<Araneidae>Ahhh. 0.5.2 is the cabal-install version, 1.4... the cabal library version.
13:29:40<Deewiant>ah, yes :-)
13:31:09<geezusfreeek>BONUS: actually i think i was wrong. f . g $ h would be fmap f g h
13:31:38<geezusfreeek>i hate precedence sometimes
13:32:10<subconscious>@seen lunabot
13:32:10<lambdabot>I saw lunabot leaving #haskell 1d 3h 55m 13s ago, and .
13:32:14<Araneidae>Interesting: cabal's bootstrap.sh uses bashisms (pushd and popd) which fail given that it's invoked with /bin/sh
13:32:34<Deewiant>sh doesn't have pushd and popd? O_o
13:32:36<Deewiant>even cmd.exe has those
13:32:42<Araneidae>Not classic sh, no
13:32:53<Araneidae>Original sh is a bit basic, I'm afraid.
13:33:11<Deewiant>in most cases original sh is miles ahead of cmd.exe :-P
13:33:25<Araneidae>sh doesn't have array variables, so you can't have the directory array!
13:33:46<Deewiant>it doesn't have to implementable in sh to be in sh :-)
13:34:00<Araneidae>true, true. Anyhow, guess I need to raise a bug report somewhere...
13:34:16<mm_freak>Philippa: i fully agree with you but that's not how people think… if they don't understand monads they feel like they don't understand the language and eventually abandon it
13:38:06<Araneidae>Oh well: http://hackage.haskell.org/trac/hackage/ticket/354 , fixed in dev
13:38:13<retybok>is there a build of ghc for IA-64 somewhere? There is no package for fedora on IA64, and apparently bootstrapping ghc isn't exactly trivial...
13:38:17<lambdabot>Title: #354 (/bin/sh used for bootstrap.sh in cabal-install doesn't support pushd, popd ...
13:39:45<ivanm>what are the layout rules for list comprehensions?
13:40:14<ddarius>ivanm: There are none.
13:40:14<Araneidae>Blast. Cabal install bootstrap fails, and I don't know what to do next.
13:40:15<Araneidae>Setup: At least the following dependencies are missing:
13:40:15<Araneidae>HTTP >=3000 && <3002, network >=1 && <3
13:40:22<ivanm>ddarius: *nod*
13:40:29<Araneidae>I don't know what that means, let alone how to fix it!
13:40:42<Deewiant>Araneidae: it means you need to install the HTTP and network packages.
13:40:55<Deewiant>(this is what cabal-install what do for you if you had it installed)
13:41:01<Araneidae>Ok... but I've never installed anything, which is why I'm installing cabal.
13:41:20<Araneidae>Just so. I've just run cabal-install/boostrap.sh, and that's what it's saying.
13:41:35<Deewiant>yes, it somewhat sucks that you can't build cabal-install without having to install something manually first. :-/
13:41:38<ddarius>ivanm: The rule is layout only begins after a 'do', 'where', 'let', or 'of'
13:42:08<ivanm>*nod*
13:42:16<Deewiant>Araneidae: you can find the packages at http://hackage.haskell.org/packages/archive/pkg-list.html
13:42:17<lambdabot>Title: HackageDB: packages by category
13:42:26<ivanm>ddarius: not even for an if/then/else?
13:42:37<ddarius>ivanm: Nope.
13:43:03<Araneidae>Where are these packages actually being installed?
13:43:23<Deewiant>on *nix, I don't know.
13:43:31<Deewiant>I think "user" installs go into ~/.cabal.
13:43:36<Araneidae>It looks like the bootstrap managed to install quite a bit of stuff... maybe in ~/.cabal
13:43:40<Deewiant>system-wide ones into the normal /usr places, I guess.
13:43:54<Deewiant>on windows, system-wide ones go into %PROGRAMFILES%/Haskell.
13:44:34<Araneidae>Hmm. ok.
13:45:34<Araneidae>Hmm. Looks as if bootstrap managed to get started on HTTP, but forgot the network dependency.
13:46:17<besiria>is there a reason why if/then/else became a keyword and not a function
13:46:20<mm_freak>Deewiant: two aux functions which are particularly annoying to rewrite all the time are modExp and gcdEx
13:46:32<Deewiant>haven't needed either yet :-)
13:46:39<subconscious>besiria: I assume it's because of the popularity of imperative langugase
13:46:46<mm_freak>ah, and a fast primality test
13:47:03<Deewiant>but yeah, some kind of Math module would be nice.
13:47:13<mm_freak>yeah
13:47:25<Deewiant>Math.Arithmetic.Modulo etc.
13:47:29<mm_freak>interestingly it would be amazingly easy to implement into GHC, because GMP provides all those basics
13:47:29<Deewiant>or whatever.
13:47:42<subconscious>http://www.vex.net/~trebla/haskell/calculator/Calculator.html
13:47:49<lambdabot>Title: Calculator
13:48:33<ivanm>with the whole nub vs map head . group . sort debate, what happens if I _do_ want a sorted output?
13:50:52<r3m0t>then... you sort it?
13:51:01<besiria>subconscious: this must be the case , but i've gotten so familiar with if/then/else that i prefer it than a lisp's if
13:51:18<quicksilver>besiria: hysterical raisins.
13:51:34<quicksilver>having said that, I like it.
13:51:51<quicksilver>I don't think it should be correctly compared to having a function 'if'
13:52:12<quicksilver>I think it should be seen as short version of "case cond of True -> thenpart; False -> elsepart"
14:15:13<gbacon>I'm trying to run many random trials using replicateM n trial, but I'm having trouble getting it to run lazily
14:16:28<inimino>wouldn't that run them sequentially?
14:16:50<gbacon>?src replicateM
14:16:51<lambdabot>replicateM n x = sequence (replicate n x)
14:16:55<byorgey>gbacon: what do you mean by 'lazily' in this context?
14:17:46<gbacon>byorgey: if I were writing it imperatively, it'd be a simple counting loop, but I'm getting stack overflows
14:18:08<gbacon>as though it wants to grab all the trials first and then go count the whole lot
14:18:39<inimino>replicateM will run all of them before anything else in your program happens
14:19:22<gbacon>I tried (liftM length . sequence . take 100000 . repeat) trial, but no dice there either
14:19:24<inimino>pure code is lazy, but IO actions happen in order
14:19:30<byorgey>no, in theory sequence should be able to come along behind replicate, processing trials as they are generated
14:19:47<byorgey>the issue isn't order, it's whether this can be done in constant memory.
14:20:34<byorgey>gbacon: it's probably not that all the trials are getting generated before they are processed, but that the processing part is too lazy so it is building up a big thunk.
14:20:45<byorgey>gbacon: what do you do with the list which is the result of repliaceM n trial?
14:20:51<byorgey>*replicateM
14:21:35<gbacon>byorgey: I'm counting trials with a certain property.. it'd be a trivial loop with O(1) space if I were writing it imperatively
14:21:39<inimino>byorgey: I think by laziness he expects the list to be created and consumed at the same time
14:22:03<gbacon>inimino: correct, what's the proper term?
14:22:07<inimino>but that won't happen because it's in the IO monad so it's going to have to keep the whole list around
14:22:12<byorgey>right, laziness makes that possible
14:22:44<byorgey>is it in the IO monad?
14:22:51<byorgey>gbacon never said what monad is involved
14:22:52<gbacon>yes, getStdRandom
14:23:00<gbacon>i.e., IO
14:23:05<inimino>ok
14:23:07<byorgey>hm, inimino may be right
14:23:33<byorgey>gbacon: much better would be to generate an infinite list of random numbers (using 'randoms') and create and process your trials with that
14:23:42<byorgey>then IO will not be threaded throughout the whole thing
14:25:16<inimino>yeah
14:25:53<EvilTerran>?hackage MonadRandom
14:25:53<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadRandom
14:26:06<byorgey>or that =)
14:26:44<EvilTerran>abstracts away the infinite list of random numbers, so it still looks like a stateful random number generator
14:26:45<dmwit_>Or you could write an action that both produces and consumes one random number.
14:26:53<dmwit_>Then replicateM will do what you want it to.
14:27:06<dmwit_>(replicateM_ might even be better in such a case.)
14:27:33<inimino>or write something that manages your state
14:29:26<sw17ch>I want a function that runs an action and binds the action with itself until "fail" is called from that monad.
14:29:29<sw17ch>Does such a thing exist?
14:30:30<byorgey>@src forever
14:30:30<lambdabot>Source not found. My pet ferret can type better than you!
14:30:50<sw17ch>byorgey, ah yes... i thinks that's the one...
14:30:54<sw17ch>@src Control.Monad.forever
14:30:54<lambdabot>Source not found. Just try something else.
14:31:00<byorgey>@type forever
14:31:02<lambdabot>forall (m :: * -> *) a. (Monad m) => m a -> m ()
14:31:11<mightybyte>@pl (\n -> (n`mod`3) == 0)
14:31:11<lambdabot>(0 ==) . (`mod` 3)
14:31:18<dmwit>That doesn't do quite what you want, probably.
14:31:27<dmwit>:t iterateM
14:31:28<lambdabot>Not in scope: `iterateM'
14:31:31<sw17ch>i do'nt think quite
14:31:35<sw17ch>the part about stopping on fail isn't quite happening
14:31:48<dmwit>And the binding to your own tail won't happen, either. =)
14:31:53<sw17ch>:P
14:31:59<sw17ch>it's along the right path though...
14:32:01<pgavin>@seen dcoutts
14:32:02<lambdabot>I saw dcoutts leaving #ghc, #haskell, #gentoo-haskell, #haskell-soc and #haskell-icfp 17h 17m 19s ago, and .
14:32:09<sw17ch>i want a forever which eventaully stops
14:32:13<dmwit>:t \m x -> iterate (>>= m) (return x)
14:32:14<lambdabot>forall (m :: * -> *) b. (Monad m) => (b -> m b) -> b -> [m b]
14:32:36<dmwit>That will get you part of the way there, you just need a "sequence" that knows when to stop.
14:32:59<EvilTerran>sw17ch, something that is to "forever" what "until" is to "iterate"?
14:32:59<sw17ch>i was hoping for something along the lines of Fix
14:33:12<EvilTerran>?type until
14:33:13<lambdabot>forall a. (a -> Bool) -> (a -> a) -> a -> a
14:33:17<EvilTerran>?type forever
14:33:19<lambdabot>forall (m :: * -> *) a. (Monad m) => m a -> m ()
14:33:41<EvilTerran>?src until
14:33:41<lambdabot>until p f x | p x = x
14:33:41<lambdabot> | otherwise = until p f (f x)
14:33:42<sw17ch>EvilTerran: yes
14:34:04<sw17ch>i have something arount here somewhere that odes that
14:34:12<dmwit>?index until
14:34:12<lambdabot>Prelude
14:34:14<EvilTerran>er, what "until" is to "fix", either
14:34:16<EvilTerran>*even
14:34:21<sw17ch>but for this situation, it seems better to use something like "do the action until it fails"
14:34:34<EvilTerran>?type let untilM p f x = do px <- p x; if px then x else untilM p f =<< f x in untilM
14:34:35<lambdabot>forall (t :: * -> *) t1. (Monad t) => (t t1 -> t Bool) -> (t t1 -> t (t t1)) -> t t1 -> t t1
14:34:39<sw17ch>in this case... (Just x) >>= ... >>= Nothing
14:34:42<EvilTerran>hm
14:34:44<sw17ch>will stop at the Nothing
14:34:56<EvilTerran>should those be >>?
14:34:57<sw17ch>instead of Nothing >>= Nothing >>= ....
14:35:10<sw17ch>EvilTerran: with the maybe type, probably :P
14:35:13<EvilTerran>(>>) rather than (>>=), i mean
14:35:27<sw17ch>EvilTerran: but in this case i want to pass the result of the last action as the input to the next
14:35:37<sw17ch>(hopefully in a tail-recursive way)
14:35:39<EvilTerran>right
14:35:42<sw17ch>(it's a game loop!)
14:35:53<inimino>ah
14:36:15<EvilTerran>?src forever
14:36:15<lambdabot>Source not found.
14:36:28<dmwit>Just write one.
14:36:40<dmwit>I think the obvious consensus here is that no, it doesn't really exist in the libraries.
14:36:49<inimino>yeah
14:36:55<sw17ch>yes... now i suppose the problem is picking up on when fail happens
14:37:05<EvilTerran>ACTION is looking at Control.Applicative.many, but it doesn't seem quite right
14:37:06<dmwit>I recommend not trying to use fail for this.
14:37:18<dmwit>Either have an explicit condition, or use a MonadPlus.
14:37:26<sw17ch>dmwit: yeah, it was just the abstraction i figued it would exist as in a library
14:37:29<sw17ch>but since it doesn't exist :P
14:37:41<dmwit>There is no uniform way to catch a fail.
14:37:59<sw17ch>It will probably be Either with a Right -> continue, Left -> finish
14:38:54<sm>morning all
14:39:07<sm>anyone familiar with setting up a web-based hoogle ?
14:39:34<sm>is it possible to browse the code/config of http://haskell.org/hoogle/ ?
14:39:37<lambdabot>Title: Hoogle
14:39:50<dmwit>I think Hoogle is on Hackage.
14:40:01<sw17ch>@hackage hoogle
14:40:01<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hoogle
14:40:04<sw17ch>woot
14:40:19<dmwit>?hackage thisdefinitelydoesnotexist
14:40:20<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/thisdefinitelydoesnotexist
14:40:23<dmwit>;-)
14:40:27<sw17ch>hahahah
14:40:37<sw17ch>lambdabot: what a lazy bot
14:40:44<sw17ch>making things like assumptions...
14:41:19<dmwit>It certainly makes the response faster. No h.org round trip. =)
14:41:37<rizobs>join irc.esylum.net #bishes-chat type !rizobs for access to our pre-channel & fast bots
14:41:39<rizobs>join irc.esylum.net #bishes-chat type !rizobs for access to our pre-channel & fast bots
14:41:41<rizobs>join irc.esylum.net #bishes-chat type !rizobs for access to our pre-channel & fast bots
14:41:42<sw17ch>i'd rather have a longer correct response than a short possibly correct one
14:42:33<subconscious>how would you do this?
14:42:34<subconscious> unify x y = do deref'x <- deref x
14:42:34<subconscious> deref'y <- deref y
14:42:34<subconscious> case (deref'x, deref'y) of
14:42:36<EvilTerran>> runStateT (forever $ do (x,y) <- get; guard (x /= 0); put (x-1,y+x)) (10,0)
14:42:37<lambdabot> No instance for (Show (m ((), (t, t))))
14:42:37<lambdabot> arising from a use of `s...
14:42:44<subconscious>other than that way?
14:42:55<EvilTerran>> runStateT (forever $ do (x,y) <- get; guard (x /= 0); put (x-1,y+x) :: StateT (Int,Int) Maybe ()) (10,0)
14:42:56<lambdabot> Nothing
14:43:00<EvilTerran>hm
14:43:22<EvilTerran>i guess that needs to be MaybeT (State (Int,Int)) ()
14:43:31<dmwit>subconscious: What's wrong with that (other than the pointers)?
14:43:50<EvilTerran>?instances Error
14:43:51<lambdabot>IOError, String
14:44:00<dmwit>subconscious: If you really want to eliminate the case, you could write a function that does whatever that case does and then (liftM2 foo (deref x) (deref y)).
14:47:46<EvilTerran>> runState (runErrorT $ forever $ do (x,y) <- get; guard (x /= 0); put (x-1,y+x)) (10,0) :: (Either String (), (Int,Int))
14:47:47<lambdabot> (Left "",(0,55))
14:48:21<EvilTerran>sw17ch, there's an example of getting a meaningful result out of "forever" by using a MonadError
14:48:44<solrize>byorgey, yeah, i just wanted to ask/mention about the blogroll in HWN
14:48:48<EvilTerran>which lets you short-circuit the "tail" of a monadic computation, and so escape the "forever"
14:48:59<byorgey>solrize: oh, what about it?
14:49:18<sw17ch>EvilTerran, thanks
14:49:34<solrize>byorgey, the one at the upper right hasn't changed since last march or something like that
14:49:36<EvilTerran>it'd be a lot nicer with MaybeT instead of ErrorT
14:50:00<byorgey>solrize: oh, on sequence.complete.org you mean?
14:50:03<sw17ch>EvilTerran, yes, or with EitherT i'm guessing
14:50:06<solrize>yeah
14:50:23<EvilTerran>you could use execState instead of runState, too, seeing as the computation's "final value" is uninteresting (being of type ())
14:50:26<byorgey>solrize: those are blogs actually hosted on sequence.complete.org
14:50:37<byorgey>there aren't many which is why it doesn't update very often.
14:50:42<solrize>oh i see, that isn't part of HWN?
14:50:46<byorgey>nope
14:50:51<solrize>aha.
14:50:55<EvilTerran>sw17ch, er, ErrorT is what MTL calls the transformer version of Either
14:51:00<solrize>where is hwn canonically hosted?
14:51:05<EvilTerran>albeit with a stupid class constraint on the first parameter
14:51:08<sw17ch>EvilTerran, oh... good point :)
14:51:12<EvilTerran>MonadLib may have a more sensible EitherT
14:51:20<byorgey>solrize: sequence.complete.org is the canonical host.
14:51:31<byorgey>it just isn't used for much else these days.
14:51:35<EvilTerran>sw17ch, http://hackage.haskell.org/cgi-bin/hackage-scripts/package/monadLib
14:51:43<lambdabot>Title: HackageDB: monadLib-3.4.4, http://tinyurl.com/5ku9e4
14:51:50<EvilTerran>ACTION wanders off
14:51:54<solrize>k
14:52:01<thoughtpolice>monadLib = niceness :]
14:54:02<pmurias>when will be ghc 6.10.1 released?
14:54:58<sw17ch>has 6.10 been released?
14:54:59<byorgey>pmurias: the word on the street is, in a few weeks
14:55:07<byorgey>there is a release candidate
14:55:11<sw17ch>oic
14:55:21<sw17ch>can this one boot strap from C again?
14:55:27<byorgey>it kind of depends on how many bugs are found in the rc =)
14:55:39<thoughtpolice>no it can't
14:55:49<thoughtpolice>hc bootstrapping has been put off until 6.12
14:55:56<sw17ch>D:
14:56:07<thoughtpolice>because the build system is going under a massive overhaul in the HEAD after 6.10 has settled down
14:56:13<FunctorSalad_>any particularly funny novelties in ghc 6.10?
14:56:15<thoughtpolice>that is also why the new native code gen didn't make it in
14:56:16<maltem>byorgey: since if too little are found, then we must assume that most bugs have not been fixed? or the other way around? :)
14:56:24<sw17ch>will this overhaul allow me to port to an ARM chip finally? :D
14:56:24<FunctorSalad_>(yes I know I should just read the list ;-))
14:56:28<byorgey>maltem: hehe =)
14:56:43<thoughtpolice>sw17ch: hopefully the new backend + new buildsystem will help ghc be more like a cross compiler
14:57:00<byorgey>FunctorSalad_: I think it includes the Data Parallel extensions, and more solid support for type families
14:57:02<sw17ch>yes... the C-- backend should be easier to port
14:57:16<pmurias>FunctorSalad_: audreyt is waiting for quasi-quotes
14:57:24<thoughtpolice>byorgey: there's DPH there in a certain form, type families should be fully working, parallel garbage collector, quasiquoting+viewpatterns
14:57:37<thoughtpolice>all very nice things
14:57:45<byorgey>ah, quasiquoting and view patterns! nice! =)
14:57:53<FunctorSalad_>byorgey: I still have to look at those type families...
14:57:57<byorgey>ACTION is excited to play with quasiquoting
14:58:01<byorgey>FunctorSalad_: me too
14:58:01<thoughtpolice>type families = win
14:58:05<thoughtpolice>quasiquoting = win
14:58:10<sw17ch>ACTION thinks quasiquoting syntax looks ugly
14:58:13<thoughtpolice>especially because for QQ if you already have a parser
14:58:16<FunctorSalad_>pmurias: isn't quasiquoting what the TH [| |] brackets do?
14:58:20<thoughtpolice>you are about 90% done already
14:58:22<byorgey>[q|uasiquoting|]
14:58:55<thoughtpolice>if mmorrow ever makes a patch for ndm's derive package to derive TH lift, then you will have to do even LESS work to make a QQ for your language
14:59:00<thoughtpolice>making one built on Language.C was cool
14:59:17<pmurias>thoughtpolice: quasi-quotes support non-haskell syntax
14:59:45<thoughtpolice>sure, we built a C quasiquoter, there's a regex one and even a javascript one
14:59:48<thoughtpolice>it's real fun to play with
15:00:00<FunctorSalad_>the syntax tree datatypes from the TH library are not that hard either though
15:00:08<thoughtpolice>you just need a parser + a TH Lift instance
15:00:11<thoughtpolice>and you are on your way
15:00:13<FunctorSalad_>you can mostly figure it out from the @info
15:00:14<subconscious>ugh no instance for Applicative (GenParser Char ())
15:00:18<subconscious>there used to be :|
15:00:49<FunctorSalad_>and don't have to learn any new syntax issues
15:00:55<thoughtpolice>FunctorSalad_: the DPH stuff in the 6.10 release is usable but there are some pitfalls in there as well
15:01:04<thoughtpolice>rl was real helpful in pointing them out to me
15:01:26<FunctorSalad_>ACTION doesn't know about DPH :-(
15:01:29<subconscious>@instances Applicative
15:01:30<lambdabot>Couldn't find class `Applicative'. Try @instances-importing
15:02:42<subconscious>how do I get the applicative instance back?
15:02:45<thoughtpolice>but yes hopefully if 6.12 can bring a cross compiler with the new backend and a new build system, that would be lovely.
15:02:57<thoughtpolice>i'll have to check out head and try the new codegen after 6.10 is settled
15:03:04<FunctorSalad_>btw was the spices-can't-use-other-splices thing fixed? the doc says it's hard to get right, but maybe add a -XSplicesImFeelingLucky flag? :)
15:03:29<FunctorSalad_>it's a bit annoying if you have some declareFoobar macro and need to declare several foobars referring to each other
15:05:21<FunctorSalad_>or maybe that particular example worked, I didn't use it much yet
15:06:07<subconscious>I wish they wouldn't keep breaking the libraries in incompatable ways
15:06:54<pmurias>is possible to have vim (or any other vi clone) print the type of thing under the cursor
15:06:59<pmurias>* it it
15:07:04<pmurias>* is it
15:07:13<FunctorSalad_>subconscious: I thought that was a feature, not a bug :)
15:07:30<FunctorSalad_>(remaining small so you can fix things)
15:07:31<quicksilver>pmurias: yes.
15:07:36<quicksilver>pmurias: _t, I believe.
15:07:42<quicksilver>but don't use vim :)
15:08:07<pmurias>quicksilver: what vi-like editor should i use?
15:09:31<FunctorSalad_>by the way, haskell-mode hint: it only shows prelude function types on its own but C-c C-t knows about all the functions currently loaded on the inferior haskell shell :)
15:09:39<FunctorSalad_>really useful
15:11:58<Araneidae>Think I'm missing something basic. I've followed the instructions to build and install Yi (runghc Setup configure --user && runghc Setup build && runghc Setup install) and there's nothing to execute anywhere in .cabal. Where's it gone?!
15:12:12<quicksilver>pmurias: sorry, there was a missing word.
15:12:18<quicksilver>pmurias: "I don't use vim" is what I meant to say
15:12:29<quicksilver>pmurias: so my information may not be fully complete :)
15:12:49<quicksilver>FunctorSalad_: in my experience it shows types in the current project too.
15:13:05<quicksilver>FunctorSalad_: pehaps only when it's been loaded in inf-haskell, I'm not sure.
15:13:23<dmwit>pmurias: I use http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/Vim/ and it provides the _t command quicksilver referred to.
15:13:26<lambdabot>Title: Haskell mode for Vim
15:13:46<FunctorSalad_>quicksilver: but it doesn't show types of imported modules even when they're loaded, /unless/ you've C-c C-t that function already
15:13:53<FunctorSalad_>then it remembers and shows it automatically
15:18:16<quicksilver>FunctorSalad_: Ah.
15:18:28<pcc1>if I have a module A which contains template haskell transformations, and a module B which uses those transformations, ghc does not recognise that B needs to be recompiled when A is (I get a message "compilation is not required"). is this a known bug?
15:18:30<quicksilver>FunctorSalad_: thanks. that would explain it.
15:18:48<pcc1>I mean, when A is changed
15:20:11<inimino>is there a function somewhere for fast intersection on sorted lists?
15:21:02<quicksilver>pcc1: is it http://hackage.haskell.org/trac/ghc/ticket/481
15:21:04<lambdabot>Title: #481 (Recompilation check fails for TH) - GHC - Trac
15:21:31<pcc1>quicksilver: yes, thanks
15:21:41<quicksilver>no problem.
15:21:47<quicksilver>my google-fu is strong :)
15:21:48<maltem>Araneidae: er, it should be there, actually
15:22:07<quicksilver>"inurl:trac site:hackage.haskell.org template haskell recompilation"
15:22:25<inimino>I want something like Data.List.intersect but I know the lists are sorted
15:22:31<quicksilver>inimino: not in the standard lib, though.
15:22:38<inimino>seems like it would be not that rare
15:22:41<maltem>Araneidae: Do you have at least a copy of the executable in ./dist/build/yi/ ?
15:22:43<quicksilver>inimino: you get the right complexity if you push through Data.Set.fromAscList
15:22:44<pmurias>dmwit: how should i install it?
15:22:48<Araneidae>maltem, maybe it's because I guilt from darcs head?
15:22:59<quicksilver>inimino: (but you pay a constant factor for the translation to Set and back)
15:23:07<inimino>oh, right
15:23:10<quicksilver>inimino: hmm. Or if theu're not unique, that's a bad idea :)
15:23:19<pmurias>i typed mkdir ~/.vim;vim haskellmode* and :%so and :q
15:23:23<inimino>they are unique
15:23:31<Araneidae>maltem, there are no executables in my Yi directory at all!
15:23:31<maltem>Araneidae: no (unless you got a version where building fails, but then there should be an error)
15:23:33<inimino>but it needs to be fast, so I'll just write it
15:23:46<Araneidae>`find -type f -perm /u+x` returns nothing
15:24:50<Araneidae>When I used cabal to install it instead, cabal first said it's already installed and then when I said --reinstall successfully dowloaded and built something (still can't get it to run, tho...)
15:24:52<maltem>Araneidae: and you really didn't get an error message about it?
15:25:14<Araneidae>Blast: running yi cleared my scrollback bufffer :(
15:25:23<Araneidae>Let me re-run the build
15:25:49<Araneidae>Preprocessing library yi-0.4.7...
15:25:50<Araneidae>Preprocessing executables for yi-0.4.7...
15:25:50<Araneidae>Building yi-0.4.7...
15:25:50<Araneidae>/usr/bin/ar: creating dist/build/libHSyi-0.4.7.a
15:25:59<maltem>Araneidae: btw I think that runghc Setup does not install into .cabal by default, but that's probably not relevant here
15:26:04<Araneidae>That's all it says, and there are still no executables to be found.
15:26:25<maltem>Araneidae: apparently no frontend has been compiled
15:26:32<Araneidae>Ok
15:26:42<maltem>Araneidae: ok, I think I know what's going on
15:26:59<Araneidae>Say more!
15:27:09<dons>?users
15:27:10<lambdabot>Maximum users seen in #haskell: 516, currently: 475 (92.1%), active: 14 (2.9%)
15:27:24<maltem>Araneidae: It didn't find enough libraries for any frontend, but it didn't tell you that's bad
15:27:50<maltem>Araneidae: That's what I suppose anyway. Do you have vty installed?
15:27:56<Araneidae>That makes sense. This is a pretty fresh ghc install
15:28:07<maltem>ah ok
15:28:16<Araneidae>I didn't, but when I asked cabal to do the install I saw it installing vty, I think.
15:28:18<maltem>Then start out with cabal install vty
15:28:26<maltem>uh
15:28:34<Araneidae>Yes it's there now.
15:28:42<maltem>damn, theory gone.
15:28:58<Araneidae>No, that could be right. I probably have to rerun configure as well.
15:29:09<Araneidae>Is there a clean step I can do?
15:29:16<maltem>cabal clean
15:29:18<pmurias>dmwit: thanks, it works now ;) but does it add to blank lines at the bottom of you terminal too?
15:29:24<maltem>(in the source tree)
15:29:38<Araneidae>Well ... but I didn't use cabal for the failing build, just runghc Setup.
15:29:57<maltem>oh, that should be no matter. Alternatively try, runghc Setup clean
15:30:03<maltem>that should be the same
15:30:16<subconscious>how do you copy a structure with STRefs in it?
15:30:19<Araneidae>Ok, building again.
15:30:41<maltem>Araneidae: the -fvty flag could also help on configure
15:30:46<quicksilver>subconscious: you mean you want to make new STRefs?
15:30:51<subconscious>yes
15:30:58<maltem>Araneidae: to make sure there will be an error if vty is not found
15:30:59<quicksilver>by recursion.
15:31:02<quicksilver>there is no general way.
15:31:03<Araneidae>However, the build I do have (0.4.7, installed by cabal) fails when I run it. (Seperate problem).
15:31:06<quicksilver>uniplate might help.
15:31:29<maltem>Araneidae: how does it fail?
15:31:51<Araneidae>Launching custom yi: "/home/michael/.yi/yi-i386-linux"
15:31:51<Araneidae>yi-i386-linux: Prelude.head: empty list
15:32:12<Araneidae>I copied a yi.hs from http://code.haskell.org/yi/examples/ into ~/.yi
15:32:12<lambdabot>Title: Index of /yi/examples
15:32:48<maltem>Araneidae: maybe try --recompile-force (or --force-recompile, whatever was the right spelling)
15:32:56<Araneidae>Without that it starts up, but whinges about not finding yi-i386-linux. This time it's built it, but bails
15:33:18<Araneidae>Aha: the new build has successfullly build dist/build/yi/yi! I'll try installing it.
15:33:53<Deewiant>-fforce-recomp
15:33:53<Araneidae>That's better.
15:34:31<maltem>Deewiant: no, that was a yi flag
15:34:31<Araneidae>So to recap (it's a bit muddled): 1/ building yi from source in a fresh environment silently failed to notice vty was missing!
15:34:35<quicksilver>abbreviations--
15:34:45<Deewiant>maltem: ah, darn
15:34:45<inimino>looks reasonable? http://hpaste.org/10703
15:34:53<quicksilver>the thing about abbreviations is that it is so hard to forget which one you chose.
15:34:56<mc__>I'm trying to do TDD for the first time. I wonder how one would test functions which only do I/O
15:35:10<Araneidae>2/ using cabal to install yi instead correctly installed vty (and some other stuff), but it's build wouldn't run properly...
15:35:25<Araneidae>3/ rebuilding from source once (2) was done seems ok (so far)
15:35:40<inimino>mc__: did you look at HUnit?
15:36:13<maltem>ad 1: Perhaps that's because *.cabal files cannot express "at least one frontend is needed"? not sure though
15:36:50<mc__>inimino: I'm using QuickCheck
15:36:59<maltem>ad 2: I suspect that your yi.hs wasn't suited for that yi version (the examples directory tends to be outdated, even)
15:37:07<mc__>I just dont get it how to write the test for an I/O function
15:37:34<Araneidae>maltem, yes that seems likely. Now I guess I have figure out how to configure it properly!
15:37:47<subconscious>why can't I use _ in type annotations?
15:37:58<inimino>oh, I don't know QuickCheck
15:38:20<Araneidae>Doesn't seem to understand <Home> and <end>, annoyingly, for a start. Time to do some reading...
15:38:34<mc__>well my question does not really have anything to do with QuickCheck itself anyways :)
15:39:42<BeelsebobWork>mc__: there shouldn't really be any IO to test
15:39:56<BeelsebobWork>it should all be in one or two functions at your top level
15:40:26<BeelsebobWork>in the mean time, testing IO is rather infeasable, because you need to test side effects, which gets you back to the same story as trying to do testing for imperative programs
15:42:01<inimino>you might just write an external program to do the test
15:43:40<mc__>hm, dont like that Idea, does anyone in here use TDD? I just wonder what practice others use then. Do you Simply skip the test for the I/O functions?
15:44:22<subconscious>@report
15:44:22<lambdabot>()
15:44:38<subconscious>this could like to the report
15:44:54<idnar>@help report
15:44:54<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
15:44:56<jeffz>what's wrong with testing side effects?
15:45:15<quicksilver>mc__: the point is that quickcheck is not designed for IO ()
15:45:19<quicksilver>mc__: so it *is* relevant.
15:45:22<BeelsebobWork>mc__: in practice, I don't need to test IO functions, because the entirity of my IO based stuff is 4 lines
15:45:34<quicksilver>however there are approaches that people use.
15:45:46<quicksilver>if you can push all the testable stuff out of IO, that's great.
15:45:52<quicksilver>if you can't, then...
15:46:03<quicksilver>a nice, but heavyweight approach, is to abstract the IO out into something abstract
15:46:07<quicksilver>and have a pure model of it
15:46:11<thoughtpolice>jeffz: it's difficult
15:46:16<quicksilver>I have a pure model of 'seekable files'
15:46:33<quicksilver>which I use to test code which is designed to work with hSeek etc.
15:46:43<mc__>I see
15:46:57<quicksilver>(the pure model makes it into functions from ByteString -> result)
15:47:04<quicksilver>or Bytestring -> Bytestring,a
15:47:08<thoughtpolice>jeffz: at least, relative to pure functions, it's more difficult
15:47:25<thoughtpolice>there was some paper about using quickcheck for the IO monad
15:47:32<quicksilver>yes, there was
15:47:38<quicksilver>there are various other approachs people have used
15:47:42<quicksilver>including unsafePerformIO
15:47:44<jeffz>thoughtpolice: do you mean more difficult to write automatic tests? because it's not difficult to write side effecting tests manually
15:48:09<inimino>mc__: what do you need to test?
15:48:54<mc__>inimino: the function just reads to lines, tries to parse them as Int's and returns them as a tuple
15:49:08<mc__>s/to/two
15:50:09<thoughtpolice>http://www.cs.nott.ac.uk/~txa/publ/beast.pdf
15:50:15<lambdabot>Title: Beauty in the Beast
15:50:17<maltem>mc__: you could leave off the "reads" part, then you can test a pure function and just hope that file I/O is implemented properly
15:51:28<mc__>i see
15:51:47<inimino>mc__: or you could write an external test that feeds it lines and expects a certain output
15:52:10<mc__>inimino: thats a bit overdoing it and it would not integrate nicely with my test suite
15:52:19<inimino>but I'd do what maltem suggested for something so simple
15:53:57<thoughtpolice>jeffz: no, hunit for example makes it pretty easy - but with pure (and total) functions, i just think it's easier to have just a declarative property that should hold, which is tested for you.
15:58:24<pmurias>mc__: you could write a mock IO monad
16:01:24<pmurias>or if you do lots of testing IO you could use TAP(testanything.org) and use perlish tools to process it
16:03:57<subconscious>ok
16:04:11<subconscious>I wrote out a unifier based from htat typed logic variables thing
16:04:25<subconscious>it seems to work I tested it on type checking a page of code
16:05:18<subconscious>?where moonpaste
16:05:19<lambdabot>I know nothing about moonpaste.
16:05:39<subconscious>oh well, here it is with a couple examples http://hpaste.org/10704
16:06:17<subconscious>so I would like to ask if there are some additions or anything which could be changed for the better?
16:07:07<subconscious>(It may be possible to use TH to generate the instances automatically for a large class of data types)
16:10:08<subconscious>oh I will add an occurs check actually
16:10:33<ulrivo>hello. I was looking at a gtk2hs-tutorial today. Everything fine with ghc. But when testing with ghci I got a "panic error". I found a similar report at ghctrac, but I did not find a solution. Is it possible to use gtk2hs with ghci?
16:11:19<dcoutts>ulrivo: on windows?
16:11:19<lambdabot>dcoutts: You have 1 new message. '/msg lambdabot @messages' to read it.
16:12:02<ulrivo>dcoutts: yes...on windows
16:12:21<dcoutts>ulrivo: on windows atm, you'll have to use gtk2hs with ghc --make
16:12:58<ulrivo>dcoutts: what a pity. but thanks a lot for your answer
16:13:40<dcoutts>ulrivo: I know it worked in an older release
16:14:19<dcoutts>ulrivo: it's a new problem with a later mingw and the ghci linker, I think it's fixed in the latest ghc
16:14:41<pgavin>dcoutts: c2hs in gtk2hs needs to be fixed for 6.10
16:15:01<dcoutts>pgavin: ah 'k
16:15:12<pgavin>dcoutts: I can do it, but I just wanted to let you know :)
16:15:14<ulrivo>dcoutts: I googled for the error but could not find it. I am using the latest releases of ghci, gtk and gtk2hs
16:16:57<dcoutts>ulrivo: sorry, I mean ghc-6.10 which is not quite released yet
16:18:28<ulrivo>dcoutts: my error is with ghc 6.8.3
16:33:09<Araneidae>How do I persuade Yi to build Yi.UI.Gtk?
16:34:09<mm_freak>what's a "higher order language"?!
16:35:24<Philippa>mm_freak: normally one that supports higher order functions or an equivalent
16:35:34<Araneidae>Hmm. There's a "flag gtk" entry in yi.cabal, but configure --gtk doesn't work.
16:35:49<mc__>mm_freak: which means you can use functions as values
16:36:10<Araneidae>So any functional language is automatically "higher order"?
16:36:18<dcoutts>Araneidae: configure -f gtk
16:36:25<Araneidae>-f? Thanks.
16:36:55<Araneidae>Ah: I see it in the help text now.
16:37:59<Araneidae>Hmm. I need the dependency "gtk >=0.9.13 && >=0.9.13" .. but `cabal install gtk` complains cabal: There is no package named gtk
16:39:28<Nafai>Is it gtk2hs?
16:39:54<thoughtpolice>dcoutts: what can you put in your ~/.cabal/configure to control where binaries installed with cabal-install go e.g. $HOME/bin?
16:40:09<byorgey>yeah, if you want a gtk front end, you have to install gtk2hs, which unfortunately is not yet Cabalized
16:40:17<byorgey>(unless someone did it while I wasn't looking)
16:40:21<byorgey>@where gtk2hs
16:40:22<lambdabot>http://haskell.org/gtk2hs/
16:40:28<byorgey>you can download it from that website though
16:40:33<Araneidae>Ok. Thought I'd installed it as a dpkg, but maybe that didn't work properly.
16:40:59<thoughtpolice>dcoutts: can you put something in your ~/.cabal/configure to control where binaries go?
16:41:05<byorgey>well, installing the gtk libraries and headers themselves (which you will also need) is not the same thing as the haskell bindings to it
16:41:15<mm_freak>Philippa, mc__: uhm… that appears like a "functional language", not a "higher order language" =)
16:41:20<Nafai>byorgey: How's school?
16:41:20<thoughtpolice>(with cabal install 0.5.2)
16:41:35<mc__>mc__: really? are you sure?
16:41:37<Araneidae>I installed libghc6-gtk-dev which claimed to be part of gtk2hs, but I'll follow that link
16:41:39<byorgey>Araneidae: don't worry, yi is particularly difficult to build, most things are much easier =(
16:41:55<byorgey>Araneidae: ah, I see what you mean. hm, then I'm not sure.
16:41:57<Araneidae>thanks for the encouragement! Well, it begins to work...
16:42:13<byorgey>Nafai: it's great!
16:42:28<byorgey>at the moment I'm working on a proof of type safety for System F + existential types =)
16:42:39<Nafai>ACTION has no idea what that means :)
16:43:00<byorgey>well, a week ago, I didn't either! =)
16:43:16<subconscious>I wrote a "simple" example http://hpaste.org/10705 :p
16:43:55<subconscious>I hope that maybe occurs can be written better but hopefully gives an idea
16:45:09<subconscious>but yeah I would appreciate any comments
16:45:19<subconscious>(on the unification thing)
16:48:08<Araneidae>Is Unification your own class, subconscious?
16:49:34<Araneidae>Just looking for the whole story...
16:54:02<Araneidae>subconscious, interested in your example ... but missing the important bit!
16:57:33<_zenon_>omg, they are 702 users over at #PHP
16:58:03<JuanDaugherty>not unusual, #debian and a number others are like that
16:58:50<_zenon_>yeah, but debian is not a programming lang :)
16:59:03<inimino>neither is PHP
16:59:07<inimino>ACTION ducks
16:59:10<_zenon_>:)
16:59:19<_zenon_>inimino, you are among friends here...
16:59:28<inimino>hehe
16:59:46<_zenon_>ACTION has to eat, damn... why do you have to eat?
16:59:52<JuanDaugherty>"PHP and HTML Coder Needed - Great for Students"
17:00:27<inimino>PHP is very easy to learn, it's true
17:01:05<JuanDaugherty>no I meant the tired ass line, like "will lead to more work if this works out"
17:01:19<inimino>heh
17:01:55<inimino>"no pay, but a chance to get in on the ground floor"
17:02:18<JuanDaugherty>Paklids All
17:04:29<JuanDaugherty>*Pakled ( http://en.wikipedia.org/wiki/Pakled )
17:04:31<lambdabot>Title: Samaritan Snare - Wikipedia, the free encyclopedia
17:06:14<JuanDaugherty><programProductX> Guru/Expert Needed is what I had in mind there
17:07:05<inimino>heh
17:07:20<subconscious>Araneidae: oops, sorry, that's here http://hpaste.org/10704
17:07:55<subconscious>I'd like to have this in a good enough state that it should be actually useful on its own, which is why I'm fishing for comments about it
17:10:18<subconscious>maybe I should automate it with TH
17:10:31<subconscious>something akin to deriving Unifiable
17:11:29<subconscious>would it be over complicating things to have it run in arbitrary monad plus transformers?
17:19:41<Araneidae>Cheers.
17:20:30<Araneidae>I'm thinking about unification, but I'm at a very basic level at the moment. I'll see if I can understand your code!
17:20:52<subconscious>ok ask me anything :)
17:21:17<subconscious>I am trying to improve bits of this.. adding error message support
17:24:07<Araneidae>There isn't an occurs method in that Unifiable!
17:24:18<subconscious>hehe
17:24:25<subconscious>I've added
17:24:27<subconscious> occurs :: Variable s tm -> tm -> Unify s Bool
17:24:31<subconscious>since I pasted it
17:24:45<subconscious>but there is no general definition, not sure if I can perhaps automate bits of it - I'll see
17:26:19<Araneidae>Also ghc complains about the instance declaration: Illegal instance declaration for `Unifiable s (T s)'
17:26:29<Araneidae>Am I missing a ghc extension flag?
17:26:54<Araneidae>Sorry: I should read the *whole* message!
17:38:01<dons>hey guys, a job. there's a rumour going around that haskell has been accepted as a language for the ACM programmign contest, http://twitter.com/jcchurch/statuses/933573132
17:38:11<dons>can anyone find more info on this, since it would be huge.
17:38:11<lambdabot>Title: Twitter / James Church: Programming language gurus ...
17:38:20<dons>"The Comp. is
17:38:20<dons>now C, C++, Java, Python, and Haskell."
17:39:44<znutar_>wow, that's surprising
17:40:12<dons>this would be a big deal. lots and lots of people enter the contest.
17:40:21<dons>and if haskell is the canonical functional language...
17:41:05<znutar_>Are the ACM programming questions as amenable to a functional approach as say the ICFP tasks are?
17:41:56<dons>ICFP isn't terribly amenable.
17:42:03<dons>i'd say ACM is far more amenable. More mathy.
17:42:31<subconscious>do view pattern like,
17:42:36<subconscious>foo (x -> Nothing) = ...
17:42:40<subconscious>foo (x -> Just e) = ...
17:42:51<subconscious>get compiled away so that x is performed once?
17:43:07<dons>you'd have to look at how views are compiled.
17:43:11<subconscious>ok
17:43:17<dons>that looks like:
17:43:26<dons>foo x | Just e <- x = ..
17:43:33<dons> | otherwise = ...
17:43:39<subconscious>I mean a function x
17:43:46<subconscious>something that is non trivial to compute
17:44:05<dons>right.
17:44:07<dons>like above :)
17:44:14<dons>pattern guards are less general than views.
17:44:19<dons>but 'x' is arbitrary
17:44:41<subconscious>um my code is different to your one
17:44:51<dons>it is?
17:45:01<dons>looks like you evaluate 'x' and case on it to me.
17:45:11<subconscious>what I meant is say, foo 348 and (x 348) may be Nothing or Just "somethiing"
17:45:15<dons>isn't it also just, foo x = case x of Just e -> .. ; Nothing -> ...
17:45:25<subconscious>no, view patters are like
17:45:38<subconscious>last (reverse -> e:_) = e
17:46:02<dons>what's the desugaring of that, according to the views wiki page?
17:46:09<subconscious>~~> last x = case reverse x in e:_ -> e
17:46:32<subconscious>oh I think it desugards to something like last x | e:_ <- reverse x = e
17:46:42<dons>right. same thing I wrote :)
17:46:50<subconscious>no different to what you wrote
17:48:58<arjanb>hmm then what's the point of views other than looking different from pattern guard?
17:49:32<dons>you can do parsing in the pattern match.
17:49:47<dons>good overview, http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns
17:49:48<subconscious>@seen lunabot
17:49:49<lambdabot>I saw lunabot leaving #haskell 1d 8h 12m 52s ago, and .
17:49:50<lambdabot>Title: ViewPatterns - GHC - Trac
17:50:00<arjanb>thx
17:52:48<Deewiant>hpaste> Deewiant pasted "argh, ugly" at http://hpaste.org/10706
17:53:05<plutonas>am i right that type is like aliasing complicated types, and data is for defining structures?
17:53:12<Deewiant>yep
17:53:27<subconscious>> liftM3 (,,) [0,1,2] [0,1] [0,1]
17:53:28<lambdabot> mueval: Prelude.read: no parse
17:53:37<plutonas>Deewiant: was this for me? :)
17:53:45<Deewiant>plutonas: yep :-)
17:53:49<plutonas>ok, thanks
17:53:51<subconscious>> let liftM3 f x y z = do x' <- x ; y' <- y ; z' <- z ; return (f x y z) in liftM3 (,,) [0,1,2] [0,1] [0,1]
17:53:52<lambdabot> [([0,1,2],[0,1],[0,1]),([0,1,2],[0,1],[0,1]),([0,1,2],[0,1],[0,1]),([0,1,2]...
17:54:00<subconscious>haha
17:54:05<Deewiant>not quite ;-P
17:54:05<subconscious>> let liftM3 f x y z = do x' <- x ; y' <- y ; z' <- z ; return (f x' y' z') in liftM3 (,,) [0,1,2] [0,1] [0,1]
17:54:06<lambdabot> [(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1),(2,0,0),(2...
17:54:49<subconscious>@let liftM3 f x y z = do x' <- x ; y' <- y ; z' <- z ; return (f x' y' z')
17:54:51<Deewiant>subconscious: not satisfactory, I don't want to compute lengths
17:54:52<lambdabot> Defined.
17:55:04<Deewiant>> liftM3 (,,) [0..] [0..] [0..]
17:55:06<lambdabot> Ambiguous occurrence `liftM3'
17:55:06<lambdabot> It could refer to either `L.liftM3',...
17:55:09<Deewiant>> L.liftM3 (,,) [0..] [0..] [0..]
17:55:11<lambdabot> [(0,0,0),(0,0,1),(0,0,2),(0,0,3),(0,0,4),(0,0,5),(0,0,6),(0,0,7),(0,0,8),(0...
17:55:14<Deewiant>that doesn't work :-)
17:58:08<hackage>Uploaded to hackage: xml 1.3.2
17:59:18<arjanb>maybe i just need to used to them but now view patterns look only useful for obfuscation
17:59:44<mm_freak>> [ (a,b,c) | a <- [0,1,2], b <- [0,1,2], c <- [0,1,2] ]
17:59:46<lambdabot> [(0,0,0),(0,0,1),(0,0,2),(0,1,0),(0,1,1),(0,1,2),(0,2,0),(0,2,1),(0,2,2),(1...
18:00:59<subconscious>arjanb,
18:01:15<subconscious>mergeSort [] = []
18:01:18<subconscious>mergeSort [e] = [e]
18:01:19<subconscious>mergeSort (halve -> (left , right)) = (merge`on`mergeSort) left right
18:01:21<subconscious>actualy I would write
18:01:24<subconscious>mergeSort (halve -> left right)
18:01:30<subconscious>but it's not implemented or something
18:04:54<EvilTerran>> concat.concat . zipWith (zipWith zip) [[[(x,y,z) | x <- [1..]] | y <- [1..]] | z <- [1..]] $ [["foo","bar","baz"],["alpha","beta","gamma"]]
18:04:55<lambdabot> [((1,1,1),'f'),((2,1,1),'o'),((3,1,1),'o'),((1,2,1),'b'),((2,2,1),'a'),((3,...
18:05:19<EvilTerran>er, those should be [0..], but that aside from that
18:06:54<subconscious>I would really use a kind of 'caseM'
18:07:06<subconscious>do x <- a
18:07:09<subconscious> case x of ...
18:07:11<subconscious>is happening a lot
18:07:54<inimino>what's that bit about (halve -> (left, right))?
18:08:08<inimino>I don't see what you're doing there
18:08:14<EvilTerran>that's view patterns
18:08:22<EvilTerran>we've just been talking about em
18:08:28<inimino>oh
18:08:42<inimino>it's an extension?
18:08:45<BMeph>Is there a fusion rule for maps and concatMaps?
18:08:48<Feuerbach>Why in this code hGetContents is blocked even after the child exited? http://hpaste.org/10707
18:08:57<inimino>ACTION scrolls up
18:15:07<inimino>wow, cool feature
18:17:22<Deewiant>EvilTerran: that almost looks good, except for everything up to the list comprehension :-P
18:17:49<EvilTerran>the important bit, then :P
18:17:54<Deewiant>?ty \x y -> concat.concat . zipWith (zipWith zip) x $ y
18:17:55<lambdabot>forall a b. [[[a]]] -> [[[b]]] -> [(a, b)]
18:18:13<Deewiant>see, that type signature's not at all obvious to me ;-)
18:18:23<EvilTerran>?type zipWith (zipWith zip)
18:18:24<lambdabot>forall a b. [[[a]]] -> [[[b]]] -> [[[(a, b)]]]
18:18:32<EvilTerran>?type concat.concat
18:18:34<lambdabot>forall a. [[[a]]] -> [a]
18:18:36<EvilTerran>easy :)
18:18:38<Deewiant>:-)
18:19:55<Deewiant>> concat . zipWith zip [[(x,y) | x <- [0..]] | y <- [0..]] $ ["foo","bar"]
18:19:56<lambdabot> [((0,0),'f'),((1,0),'o'),((2,0),'o'),((0,1),'b'),((1,1),'a'),((2,1),'r')]
18:20:39<dons>http://www.reddit.com/r/programming/comments/73r99/live_from_cufp_using_haskell_in_biotechnology/
18:20:41<lambdabot>Title: Live from CUFP: Using Haskell in Biotechnology : programming, http://tinyurl.com/42sn97
18:20:42<dons>there you go guys,
18:20:50<dons>incase you didn't know the commercial FP users workshop is on today.
18:20:54<dons>lots of great haskell talks
18:23:47<pfo>still no papers from cufp?
18:24:28<dons>pfo: videos.
18:24:35<dons>commercial users don't have time to write papers.
18:24:36<pfo>dons: where?!
18:24:44<dons>they'll be online in the next few days.
18:24:48<dons>last years one are online
18:24:50<pfo>woot
18:24:50<pfo>thx!
18:25:22<Spark>icfp contest results out yet?
18:25:35<Spark>ah yes
18:26:15<Heffalump>does hackage have an RSS feed?
18:26:26<pfo>Spark: only perliminary stuff
18:26:37<dons>Heffalump: yeah
18:26:44<dons>there's a link on hackage.haskell.org
18:27:17<Heffalump>oh. So there is.
18:27:21<Spark>i'd like to see a breakdown of progrmaming languages and score
18:27:27<Heffalump>I looked for it before asking stupid questions, honest :-)
18:28:50<dons>:)
18:32:19<Feuerbach>Why in this code hGetContents is blocked even after the child exited? http://hpaste.org/10707
18:35:09<subconscious>so would a Freezable typeclass be good to have with a unifier library?
18:37:41<Xenoblitz>Guys, I needs me a graphics library :) Care to suggest? :)
18:37:55<Feuerbach>Xenoblitz: hopengl?
18:38:07<Feuerbach>(bindings to OpenGL)
18:38:29<Xenoblitz>Feuerbach: I'll give it a look, thanks :)
18:38:36<mc__>or hsdl
18:38:53<mc__>which is probably simpler (but much less powerfull)
18:39:08<Xenoblitz>http://www.haskell.org/haskellwiki/Applications_and_libraries/Graphics#Libraries
18:39:10<lambdabot>Title: Applications and libraries/Graphics - HaskellWiki, http://tinyurl.com/4hjxmb
18:39:16<Xenoblitz>i guess these are the ones avaible
18:39:21<Xenoblitz>*available
18:40:01<Xenoblitz>anyone ever used HGL?
18:40:17<jeffz>Xenoblitz: yes, if you're looking for OpenGL examples, download the GLUT package from hackage, it includes a bunch
18:40:57<Xenoblitz>mc__: thanks :)
18:41:01<Xenoblitz>jeffz: thanks as well
18:41:02<subconscious>Is there any way to freeze a structure with STRefs in it simpler than using a gensym/supply monad?
18:50:45<subconscious>ugh there is no IdentityT :/
18:51:32<EvilTerran>MonadLib has IdT
18:54:46<subconscious>if I have, type Unify s a = ErrorT String (ST s) a
18:55:08<subconscious>but I want to parameterize it on some transformer t, type Unify t s a = t (ErrorT String (ST s) a)
18:55:34<subconscious>how do you write the new runUnifier ?
18:55:55<EvilTerran>you can't without a class constraint on t in the type of runUnifier
18:58:59<BMeph>IdentiT? ;)
18:59:03<Saizan_>it's type Unify t s a = t (ErrorT String (ST s)) a, btw
19:03:29<mml>any HTTP client library recommendations? i was going to start staring at the curl bindings.
19:08:03<subconscious>Araneidae, if you haven't got bored of me yet, I've improved the code a bit -- I could paste if you are still want to look
19:12:54<subconscious>If you had two functions
19:12:58<subconscious>freezeT' :: T s -> ErrorT String (GHC.ST.ST s) (F (Variable s (T s)))
19:13:26<subconscious>and freezeT :: (Monad m, Eq t) => F t -> m (F String)
19:13:47<dons>mml: libdownload ?
19:13:56<dons>mml: i'd try the download or download-curl libs first.
19:14:01<subconscious>you can't merge them without using a transformer?
19:14:04<dons>then either HTTP or the curl library
19:14:29<subconscious>ACTION has to write them as two separate recursive functions
19:14:31<EvilTerran>ACTION tends to use HTTP
19:15:03<mml>dons: download looks like it makes simple things simple
19:15:40<EvilTerran>sometimes with HTTP-Simple
19:16:10<dons>mml: i based it on the hpricot ruby library
19:16:29<dons>download-curl is a bit more general, it supports lazy bytestrings
19:18:37<dcoutts>Deutsche Bank is using HAppS for an internal trading system
19:18:40<chr1s>dons: do you read whytheluckystiff's blog?
19:18:49<dons>no, actually. should i?
19:18:51<dons>probably should.
19:18:53<chr1s>yes
19:19:11<dons>ok :)
19:19:20<chr1s>there's redhanded, which contains lots of interesting stuff but is discontinued: http://redhanded.hobix.com/
19:19:23<lambdabot>Title: RedHanded » sneaking Ruby through the system
19:19:44<chr1s>and now he's doing awesome things on hackety: http://hackety.org/
19:19:45<lambdabot>Title: hackety org
19:19:45<subconscious>dons, so I wrote out a unification class and some examples based on that paper typed logic vars, it seems to work (I can typecheck a page of code in some mini haskell language with it) so I guess it is hackage worthy? but I'd like to get some other peoples comments and someone to upload it if it is ..
19:19:55<chr1s>e.g. http://shoooes.net/
19:19:56<dons>yes.
19:20:00<lambdabot>Title: Shoes • Colorful programs for Mac OS X, Linux and Windows
19:20:00<dons>subconscious: you should upload it :)
19:20:13<subconscious>mrf . . I have no hackage account still
19:21:28<newsham>I want to print the output of "reify" (TH). how do I accomplish that?
19:22:34<RayNbow>oh man... sigfpe is awesome... http://sigfpe.blogspot.com/2008/09/on-writing-python-one-liners.html
19:22:36<lambdabot>Title: A Neighborhood of Infinity: On writing Python one-liners., http://tinyurl.com/4jlm43
19:22:55<newsham>proving that even in python, lambda calculus is turing complete
19:25:30<mml>dons: this look familiar? <interactive>: /home/mml/.cabal/lib/download-0.3/ghc-6.8.2/HSdownload-0.3.o: unknown symbol `stat64'
19:25:50<dons>mml: try download-curl
19:26:15<subconscious>byorgey: hey, how are you proving it ?
19:26:32<subconscious>like it would be cool to see the finished thing I guess
19:26:39<jethr0>good evening, haskell
19:26:47<subconscious>hi
19:26:57<mml>dons++ whee!
19:27:20<dons>mml: i think the C library, libdownload, that 'download' uses isn't widely portable
19:27:27<dons>while download-curl is
19:29:59<newsham>anyone here good with TH?
19:30:36<jethr0>newsham: i'd be lying if i said i was
19:30:59<newsham>do you know how to print the output of reify?
19:33:53<newsham>main = putStrLn $(reify ''MyData >>= lift . show)
19:33:54<newsham>yay
19:35:30<[R]ayne>Hm, I can't find the .emacs file in the home directory to install haskell mode for it. O_o
19:35:40<subconscious>it may not exist
19:35:43<mrd>creat one
19:37:47<jethr0>newsham: have you had a look at my tutorial? http://web.archive.org/web/20061011050035/http://www.haskell.org/hawiki/TemplateHaskellTutorial
19:37:49<lambdabot>Title: TemplateHaskellTutorial - The Haskell Wiki, http://tinyurl.com/4avffu
19:38:13<jethr0>it's been ages since i've used TH, but i think i used reify in the tutorial
19:42:15<newsham>jethr0: i just came across it
19:43:03<jethr0>it took me ages to write, only to find out afterwards that scrap-your-boilerplate solves many of the mentioned problems in a MUUCH better and cleaner fashion ;)
19:44:20<subconscious>I think I dont' understand scrap-your-boilerplate
19:45:08<jethr0>subconscious: not that i fare much better, but what don't you understand?
19:45:17<Botje>subconscious: i suggest you try uniplate first
19:45:18<subconscious>I just use functions :L
19:45:26<Botje>uniplate is much much easier to learn, imo
19:46:00<Botje>once you've read how uniplate works, you'll understand SYB
19:46:29<subconscious>ok
19:47:23<mml>lately i type 'somethingMonadic >>= return . pureFunction' a lot
19:47:50<subconscious>I think you can use liftM instead
19:47:50<sjanssen>mml: fmap pureFunction somethingMonadic
19:47:51<mml>is there a function that means the same thing as 'return .'? it's short enough, but somehow i feel like this is a pattern
19:48:07<subconscious>:t liftM ?pureFunction ?somethingMonadic
19:48:09<lambdabot>forall a1 r (m :: * -> *). (Monad m, ?somethingMonadic::m a1, ?pureFunction::a1 -> r) => m r
19:48:17<subconscious>no I got it wrong
19:48:25<subconscious>oh wait no it _is_ right
19:48:48<dblazakis>fmap, liftM, or <$>
19:49:05<mml>:t <$>
19:49:07<lambdabot>parse error on input `<$>'
19:49:11<dblazakis>as in pureFunc <$> sthMonadic
19:49:17<mml>:t (<$>)
19:49:18<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
19:49:47<sjanssen>mml: (<$>) is just an alias for fmap, and liftM is equivalent to fmap except it only works on Monads
19:50:40<sjanssen>and since liftM is an abomination, fmap is preferred
19:50:56<mml>sjanssen: thanks. fmap works, but where is <$> defined?
19:51:09<subconscious>what is bad about liftM?
19:51:15<skorpan>it only works on monads
19:51:21<subconscious>that's fine
19:51:31<subconscious>I use monads sometimes ..
19:51:33<skorpan>no, that's an abomination, which is why fmap is preferred
19:51:33<sjanssen>mml: Control.Applicative
19:51:43<sjanssen>subconscious: all Monads should be Functors
19:52:07<sjanssen>liftM really only exists because of an oversight in Haskell '98
19:52:24<ddarius>sjanssen: It definitely wasn't an "oversight"
19:52:29<mml>sjanssen++. <$> is easy to read
19:52:50<sjanssen>s/oversight/mistake
19:53:19<Beelsebob>strangely, I find <$> easy to read precicely where I'm using <*> too
19:53:38<Botje>mmm
19:53:39<ddarius>A deliberate mistake, yes.
19:53:44<Botje>i always use liftM if i'm working with monads
19:53:50<Botje>fmap just doesn't feel right :]
19:54:07<Beelsebob>Botje: I always use liftA in that situation
19:54:08<subconscious>I like liftM because it's part of liftM liftM2 liftM3 ...
19:54:27<ddarius>liftM2 f x y = f <$> x <*> y
19:54:34<jethr0>aahh
19:54:34<ddarius>liftM3 f x y z = f <$> x <*> y <*> z
19:54:35<Beelsebob>ddarius: that too
19:54:36<Beelsebob>that's very nice
19:54:42<sjanssen>why would anyone ever use liftA?
19:54:45<jethr0>let's all use `ap`
19:54:57<Beelsebob>ACTION starts using ddarius's idiom
19:54:57<Botje>ap is dead.
19:55:04<Botje><*> is the new ap
19:55:06<Beelsebob>ap is dead, long live <*>
19:55:11<jethr0>that's what i thought
19:55:23<subconscious>idioms!
19:55:34<skorpan>OT: what is this "j love" that rappers sometimes randomly put in their lyrics?
19:55:41<subconscious>?wiki idiom brackets
19:55:42<lambdabot>http://www.haskell.org/haskellwiki/idiom_brackets
19:57:52<newsham>why not liftM0 ?
19:57:58<subconscious>:t liftM2
19:57:59<lambdabot>forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
19:58:00<subconscious>:t liftM
19:58:01<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
19:58:06<subconscious>:t return
19:58:07<lambdabot>forall a (m :: * -> *). (Monad m) => a -> m a
19:58:09<hackage>Uploaded to hackage: GraphSCC 1.0.2
19:58:09<hackage>Uploaded to hackage: GraphSCC 1.0.1
19:58:10<ddarius>liftM0 = return
19:58:23<ddarius>liftA0 = pure
19:58:28<newsham>and liftM3 f x y z = f <$> x <*> y <*> z
19:58:38<newsham>so... why no liftM0?
19:58:54<dibblego>liftM2 f x y = f <$> x <*> y
19:59:06<dibblego>liftM1 f x = f <$>
19:59:09<subconscious>so anyone want to code review? :P
19:59:18<subconscious>ACTION has a (short) page of code
19:59:21<dibblego>liftM0 f = pure f
19:59:44<dibblego>liftM1 f x = f <$> x -- oops
19:59:52<newsham>liftA0 = pure; liftA1 f x = pure f <*> x; liftA2 f x y = pure f <*> x <*> y; liftA3 f x y z = pure f <*> x <*> y <*> z
19:59:55<jethr0>@paste
19:59:55<lambdabot>Haskell pastebin: http://hpaste.org/new
20:00:42<jethr0>so, was that type hackery issue resolved that was mentioned in "@wiki idiom brackets"?
20:00:43<newsham>liftA0 f = pure f; liftA1 f x = pure f <*> x; liftA2 f x y = pure f <*> x <*> y; liftA3 f x y z = pure f <*> x <*> y <*> z
20:01:22<jethr0>> (+) <$> (Just 4) <*> (Just 3)
20:01:24<lambdabot> Just 7
20:01:29<jethr0>cool
20:01:41<jethr0>not sure i like the look of the code, but it's definitely neat
20:02:19<jethr0>> let if' a b c = if a then b else c
20:02:20<lambdabot> mueval: Prelude.read: no parse
20:02:30<Beelsebob>I like that *much* better than do x <- Just 4; y <- Just 3; return x + y
20:02:32<jethr0>@let if' a b c = if a then b else c
20:02:35<lambdabot> Defined.
20:02:37<subconscious>@let bool true false True = true ; bool true false False = false
20:02:40<lambdabot> Defined.
20:02:43<subconscious>jethr0: ^ this is the one I like
20:03:04<jethr0>> if' <$> (Just True) <*> (Just 4) <*> (Just 5)
20:03:05<lambdabot> Just 4
20:03:20<Beelsebob>@let ifA c t e = if' <$> c <*> t <*> e
20:03:22<lambdabot> Defined.
20:03:30<subconscious>:t ifA
20:03:32<lambdabot>forall (f :: * -> *) a. (Applicative f) => f Bool -> f a -> f a -> f a
20:03:33<subconscious>:t liftM2 bool
20:03:34<lambdabot>forall a1 (m :: * -> *). (Monad m) => m a1 -> m a1 -> m (Bool -> a1)
20:03:37<Beelsebob>> ifA (Just True) (Just 4) (Just 5)
20:03:39<lambdabot> Just 4
20:03:42<subconscious>:t liftM3 bool
20:03:43<lambdabot> Ambiguous occurrence `liftM3'
20:03:43<lambdabot> It could refer to either `L.liftM3', defined at <local>:16:0
20:03:43<lambdabot> or `Control.Monad.Logic.liftM3', imported from Control.Monad.Logic
20:03:44<subconscious>:t liftA3 bool
20:03:45<lambdabot>forall a (f :: * -> *). (Applicative f) => f a -> f a -> f Bool -> f a
20:03:59<jethr0>subconscious: don't you mean "bool True a _ = a; bool False _ b = b"?
20:04:02<subconscious>:t msplit
20:04:03<lambdabot>forall (m :: * -> *) a. (MonadLogic m) => m a -> m (Maybe (a, m a))
20:04:05<subconscious>jethr0: no I do not mean that
20:04:12<Beelsebob>> ifA (==5) (*2) (+6) 5
20:04:14<lambdabot> 10
20:04:17<Beelsebob>:)
20:04:17<subconscious>@instances MonadLogic
20:04:18<lambdabot>Couldn't find class `MonadLogic'. Try @instances-importing
20:04:26<subconscious>@instances-importing Control.Monad.MonadLogic MonadLogic
20:04:27<lambdabot>Couldn't find class `MonadLogic'. Try @instances-importing
20:04:29<jethr0>subconscious: ;)
20:04:35<sjanssen>@type L.liftM3
20:04:36<lambdabot>forall t1 t2 t3 t4 (t :: * -> *). (Monad t) => (t1 -> t2 -> t3 -> t4) -> t t1 -> t t2 -> t t3 -> t t4
20:04:40<FunctorSalad>Beelsebob: yesterday lambda didn't know about ifA
20:04:41<sjanssen>@type Control.Monad.Logic.liftM3
20:04:42<lambdabot>forall a1 a2 a3 r (m :: * -> *). (Monad m) => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
20:04:43<subconscious>:t observe
20:04:44<lambdabot>forall a. Logic a -> a
20:04:54<Beelsebob>FunctorSalad: now it does though :)
20:04:55<sjanssen>hmm, why wouldn't those be the same?
20:04:58<subconscious>> observe [1,2,3]
20:05:00<lambdabot> Couldn't match expected type `Logic a' against inferred type `[a1]'
20:05:00<FunctorSalad>@t ifA
20:05:00<jethr0>Beelsebob: i have not idea why that just worked ;)
20:05:00<lambdabot>Maybe you meant: tell thank you thanks thx ticker time tiny-url todo todo-add todo-delete topic-cons topic-init topic-null topic-snoc topic-tail topic-tell type . ? @ ft v
20:05:04<FunctorSalad>@type ifA
20:05:05<lambdabot>forall (f :: * -> *) a. (Applicative f) => f Bool -> f a -> f a -> f a
20:05:07<Beelsebob>jethr0: becaues I defined it
20:05:10<subconscious>> observe (msum . map return [1,2,3])
20:05:11<lambdabot> Couldn't match expected type `a -> [m a1]'
20:05:14<subconscious>> observe (msum . map return $ [1,2,3])
20:05:15<lambdabot> mueval: Prelude.read: no parse
20:05:25<Beelsebob>[22:03] Beelsebob: @let ifA c t e = if' <$> c <*> t <*> e
20:05:26<FunctorSalad>Beelsebob: I was thinking of the one for arrows, not applicatives
20:06:15<FunctorSalad>and why isn't there a liftMAnything yet? ;-)
20:06:26<idnar>liftEverything
20:06:30<jethr0>Beelsebob: i wasn't referring to the @let, but rather why the argument "5" was used by more than one function. i'll have to have another look at that code. is it in the (->) monad?
20:06:53<Beelsebob>jethr0: it's the (-> a) applicative
20:06:54<jethr0>FunctorSalad: what type would that function have?
20:06:54<pfo>what exactly are the .hi files that ghc --make generates?
20:06:59<jethr0>k
20:07:04<subconscious>:(
20:07:20<Beelsebob>@src Applicative ((->) a)
20:07:21<dibblego>it's the S combinator
20:07:21<lambdabot>Source not found. My mind is going. I can feel it.
20:07:26<FunctorSalad>jethr0: the usual typeclass trick, "class IsLiftM a b where liftM :: a -> b", then you define it inductively
20:07:30<Beelsebob>@instance Applicative ((->) a)
20:07:30<lambdabot>Maybe you meant: instances instances-importing
20:07:32<jethr0>subconscious: where are you expecting "observe" to come from
20:07:33<Beelsebob>bah
20:07:44<dibblego>(t -> a -> b) -> (t -> a) -> t -> b
20:07:54<subconscious>jethr0: what do you mean?
20:08:05<FunctorSalad>instance IsLiftM (a -> b) (m a -> mb) where ... and so on
20:08:05<Beelsebob>@src ((->) a) <$>
20:08:06<lambdabot>Source not found. I am sorry.
20:08:10<pfo>.hi files are what?
20:08:13<Beelsebob>@src ((->) a) (<$>)
20:08:14<lambdabot>Source not found. Sorry.
20:08:25<FunctorSalad>I haven't thought about whether there will be ambiguities though
20:08:37<jethr0>i thought you were displeased with your "observe [1,2,3]" not working
20:10:25<FunctorSalad>instance (Monad m, isLiftM m x y) => isLiftM m (a -> x) (m a -> y) -- forgot the m parameter in isLiftM at first
20:11:08<FunctorSalad>also it needs to be capitalized
20:11:26<subconscious>I've seen |>f<|^3 in papers to denote liftM3 f
20:13:19<Cale>subconscious: Really? Whose paper?
20:14:01<subconscious>this one http://strictlypositive.org/unify.ps.gz
20:14:30<subconscious>It's a really cool proof actually :)
20:23:45<prongla>can i hoogle from ghci in emacs?
20:24:57<pfo>I'm trying some SOE examples - but on the first one i get this error: http://hpaste.org/10710
20:25:24<subconscious>pfo: I think it's just an indentation problem
20:25:37<subconscious>pfo: You seem to have typed tabs instead of spaces
20:25:54<subconscious>instead of
20:25:55<subconscious> = do k <- getKey w
20:25:55<subconscious> if k == ' '
20:25:57<subconscious>it should be like
20:26:07<subconscious>= do k <- getKey w
20:26:07<subconscious> if k == ' '
20:26:19<subconscious>hm infact they are spaces but too many of them
20:26:58<subconscious>(and you may also have to indent the 'then' and 'else' parts slightly?)
20:27:13<RayNbow>@faq Can Haskell comfort me for having lost the gaming skills required to beat Megaman 9?
20:27:14<lambdabot>The answer is: Yes! Haskell can do that.
20:27:47<RayNbow>ACTION feels better now... :)
20:28:23<prongla>anyone tried fsharp? opinions?
20:28:37<jethr0>@faq does lambdabot answer any question posed to it in the affirmative?
20:28:37<lambdabot>The answer is: Yes! Haskell can do that.
20:30:43<pfo>subconscious: thx!
20:31:12<Botje>@faw can haskell comfort me when i watch a scary movie?
20:31:13<lambdabot>The answer is: Yes! Haskell can do that.
20:31:57<_zenon_>Botje, are you watching a scary movie right now?
20:32:05<Botje>just started silent hill
20:32:18<tusho>Botje: you said scary movie
20:32:20<tusho>:|
20:32:45<Botje>any suggestions?
20:33:19<_zenon_>:D
20:34:59<jethr0>Botje: just stop after the first 30 minutes. it's scarier that way...
20:35:27<Botje>i rather like the parts with all the barbed wire :]
20:35:33<Botje>and the pyramid man is cool too
20:35:44<_zenon_>Botje, This is scary: http://www.youtube.com/watch?v=wvsboPUjrGc
20:35:45<lambdabot>Title: YouTube - Steve Ballmer going crazy
20:35:54<jethr0>Botje: suggestions for what? scary movies?
20:36:32<tusho>hmm
20:36:37<tusho>lambdabot is the Final Solution to rickrolls
20:36:38<tusho>:|
20:36:53<tusho>http://www.youtube.com/watch?v=eBGIQ7ZuuiU
20:36:54<lambdabot>Title: YouTube - Rick Roll
20:37:38<jethr0>in a way "event horizon" is quite scary
20:37:42<subconscious>ugh can we go to #haskell-blah for a bit?
20:38:13<jethr0>@quote off-topic
20:38:16<lambdabot>dmwit says: Incidentally, I'm happy that xmonad has enough followers now for the discussions to wander off-topic.
20:38:26<jethr0>@quote off-topic
20:38:29<lambdabot>dmwit says: Incidentally, I'm happy that xmonad has enough followers now for the discussions to wander off-topic.
20:38:34<jethr0>grr
20:38:39<_zenon_>;)
20:40:18<inimino>the good news is that my n^2 algorithm ran in only 8 minutes, the bad news is that was only over 1/34 of the data
20:41:04<roconnor>> 8*34^2/60/24
20:41:06<lambdabot> 6.422222222222222
20:41:15<inimino>yeah
20:41:21<roconnor>inimino: only 1 week to do it all
20:41:28<inimino>yeah
20:41:48<SamB_XP>so ...
20:41:50<roconnor>you can start it running and you have a week to improve your algorithm
20:42:02<SamB_XP>oh, I see
20:42:03<inimino>that's true ;-)
20:42:20<SamB_XP>that's the amount of time it would take ... not the time it needs to happen in ..
20:42:34<SamB_XP>ACTION was about to do roughly the same calculation ;-)
20:42:50<inimino>hehe
20:43:18<roconnor>inimino: better than the time I wrote an algorithm to sum a list of 2^308 elements
20:43:24<roconnor>stupid exponential algorithms
20:43:32<inimino>hehe
20:43:34<Botje>2^308? O_o
20:43:48<roconnor>308 seemed so small
20:43:53<jethr0>roconnor: wouldn't that take kinda long, even with a mighty language as haskell?
20:43:53<inimino>haha
20:44:20<roconnor>jethr0: I stopped it after a running for a few minutes
20:47:32<jethr0>i was looking for the ascii string "hello world" in PI, but soon figured out that i'd have to search quite a few places to ever find it
20:48:38<lament>jethr0: fortunately there's a website to do that for you
20:49:00<lament>http://www.angio.net/pi/piquery
20:49:05<lambdabot>Title: The Pi-Search Page
20:49:20<jethr0>i used the website, but it only has 400 million places. there is a university site that let's you download 4 billion places, but even that much is probably not enough for "hello world"
20:49:52<inimino>run the Bible Code algorithm over it ;-)
20:49:56<_zenon_>jethr0, do I dare wonder why?
20:50:03<lament>of course this site only allows you to search base 10
20:50:05<vinicius_>The string 1337 occurs at position 4,813 counting from the first digit after the decimal point.
20:50:23<_zenon_>inimino, the bible code algorithm will find "Leet haxxor" on your cereal packages :P
20:50:51<jethr0>_zenon_: the pi search site show the probability of finding a string of length 10 as very low even with many million places to search.
20:51:43<_zenon_>jethr0, okay, I thought you had some kind of weird PI-fetish.
20:51:54<_zenon_>but then, who hasnt? ;)
20:51:58<vinicius_>> (1.0/10.0)**10
20:51:59<lambdabot> 1.0000000000000006e-10
20:52:31<jethr0>_zenon_: not really. i just found the idea of encoding any string as a start location in pi interesting. but seeing how low the probabilities are, i won't be hiding my next novel in Pi anytime soon
20:52:52<inimino>interesting idea
20:53:05<Cale>jethr0: Yeah, it's a terrible compression algorithm ;)
20:53:08<jethr0>vinicius_: that's not taking into account how many digits you're looking in
20:53:39<vinicius_>jethr0: of course not, I don't have the math/stats machinery to do it =p
20:53:50<jethr0>i first got onto these kinds of ideas with the CSS encoding competitions. really cool in what media it is possible to convey information / data / programs
20:53:53<Cale>It's not even clear that every sequence of digits occurs.
20:54:05<inimino>isn't it?
20:54:06<jethr0>Cale: yes, that's another problem
20:54:18<vinicius_>yeah, my calc assumes random distribution
20:54:42<vinicius_>which is way off, since pi has a low kolgomorv complexity
20:54:47<Cale>In fact, we know so little about the structure of the decimal expansion of pi that at some point it could become nothing but some arrangement of 3's and 7's.
20:54:56<lament>nobody seriously suggests that it would be non-random, we just can't prove anything
20:55:06<inimino>true
20:55:11<Cale>In fact, I think it would be really cool if it did ;)
20:55:15<inimino>heh
20:55:23<jethr0>lament: don't go there. randomness is a tricky thing to reason about ;)
20:55:33<lament>Cale: yes, nine nine nine nine nine nine and so on
20:55:36<inimino>that would definitely be cool
20:55:38<jethr0>nah, my bet is on it going 000000000000
20:55:49<inimino>but it seems highly improbable ;)
20:55:55<lament>jethr0: that part was disproved a while back :)
20:55:56<Cale>Of course, it can't end in an infinite string of any one digit.
20:56:14<jethr0>i'd say it just stops at some point, but that would go against my admittedly spotty math education
20:56:20<Cale>(because that would make it rational)
20:56:35<Cale>Moreover, it can't end in any repeating string.
20:57:15<jethr0>true, so even if it ends in an arrangement of 3's and 7's that would still need to have no structure and then you should be able to encode anything into those 3's and 7's, i guess
20:57:31<inimino>doesn't that prove that it contains every possible sequence?
20:57:32<Cale>It still would have some structure. Just not periodic structure.
20:57:46<subconscious>inimino: No I don't think so
20:57:48<lament>inimino: no
20:57:52<vinicius_>no
20:57:53<jethr0>but as i said, my math is sorely lacking and this is a few orders of magnitude beyond my number theory inklings
20:57:59<inimino>hm
20:58:01<Cale>In fact, it could end in a unary encoding of the primes, like 37737773777773....
20:58:26<Cale>(well, probably could rule that specific one out somehow :)
20:58:32<inimino>that's true
20:59:08<vinicius_>anyway
20:59:18<inimino>yes, I suppose on further thought there are infinitely many infinitely long sequences that don't contain any given sequence
20:59:23<vinicius_>encoding anything as a pi sequence could make the number large
20:59:50<vinicius_>I mean, too large.
21:00:04<lament>pi is just a theory, anyway.
21:00:19<inimino>a theory?
21:00:26<sw17ch>ACTION wonders if there's a practicle application for knowing Pi past a given specific precision
21:00:33<vinicius_>in logic programming it probably is :)
21:00:39<dmhouse>Depends on the precision.
21:00:40<pastorn_>is there some datatype _ = N | S | E | W predefined in GHC somewhere?
21:00:52<pastorn_>(so that i might avoid defining it mysef...
21:01:00<inimino>pastorn_: I don't think so
21:01:04<lament>pastorn_: unlikely.
21:01:18<ddarius>Maybe Ordering
21:01:23<lament>pastorn_: what about U | D | SW | SSW ?
21:01:31<sw17ch>ACTION wanders home...
21:01:36<pastorn_>lament: huh?
21:01:36<ddarius>Either Bool Bool
21:01:48<inimino>peace symbol?
21:01:56<inimino>no, nevermind
21:02:09<dmhouse>Hmm, Maybe is like type-level succ. That's quite nice.
21:02:14<pastorn_>nah... i just wanted to avoid implementing turn operation
21:03:57<ddarius>pastorn: turnRight direction = toEnum ((1 + fromEnum direction) `mod` 4)
21:04:36<BMeph>dmhouse: Except Maybe (Maybe a) doesn't quite do what you'd like... ;)
21:04:56<inimino>well, not with N | S | E | W ...
21:05:12<inimino>but N | E | S | W
21:05:23<roconnor>> 64-28
21:05:25<lambdabot> 36
21:05:26<dmhouse>BMeph: why not? Maybe (Maybe ()) has elements Just (Just ()), Just Nothing and Nothing, as expected.
21:05:27<pastorn_>turnR, turnL :: Direction -> Direction
21:05:27<pastorn_>turnL = turnR . turnR . turnR
21:05:38<subconscious>Mu Maybe = Nat
21:05:43<pastorn_>ACTION is lazy as you wouldn't believe
21:05:45<inimino>heh
21:06:02<inimino>eh, the compiler's smart
21:06:38<Cale>It's interesting that almost all real numbers (in the sense of measure) have the property that the average frequency of every digit in base b tends to 1/b, but it's very hard to show that even one particular number actually has this property. :)
21:07:38<inimino>one particular number?
21:07:51<inimino>why would that be harder than just counting them?
21:07:59<lucca>...what does "almost all" of an infinite set mean?
21:08:20<dmhouse>The remainder have measure zero, in this case.
21:08:35<ddarius>An unusual location but http://www.dspguide.com/ch34.htm
21:08:41<lambdabot>Title: Explaining Benford's Law
21:08:45<Cale>That is, to construct an example of a number such that for every base b, the average frequency of the occurrences of each digit tends to 1/b.
21:08:54<dmhouse>Measure is a precise formulation which is approximated by the intuitive notion of "area" (in 2 dimensions).
21:08:59<inimino>ah
21:09:04<dmhouse>http://en.wikipedia.org/wiki/Measure_theory
21:09:05<lambdabot>Title: Measure (mathematics) - Wikipedia, the free encyclopedia
21:09:42<dblazakis>could come up with a way to count those that don't have the 1/b distribution of digits... err to prove they are countably infinite
21:09:42<ddarius>Measure theory == probability theory with probabilities that are allow to be outside of [0..1]
21:09:46<Cale>(and specifically, the measure in question here is the Lebesgue measure on R)
21:10:52<dblazakis>ack, nevermind i suppose they aren't countable
21:10:57<lucca>weeeird
21:13:21<Cale>lucca: Basically, it means that the set of points which don't have the property can be covered by a countable collection of intervals where the sum of their lengths is arbitrarily small.
21:13:58<BMeph>ACTION thinks that "a precise formulation which is approximated" may not be aas precise as advertized... ;p
21:14:13<Cale>BMeph: hm?
21:14:31<inimino>it is precise, it's the intuitive idea that is vague ;-)
21:14:54<pastorn_>@hoogle Enum
21:14:54<lambdabot>Prelude class Enum a
21:14:55<lambdabot>Prelude enumFrom :: Enum a => a -> [a]
21:14:55<lambdabot>Prelude enumFromThen :: Enum a => a -> a -> [a]
21:15:26<BMeph>inimino: Ah, the old "I'm not evil, I'm misunderstood" defense? ;)
21:15:42<inimino>heh
21:18:19<BMeph>ddarius: Thanks - maybe that book can help me with one (of many) side project of mine.
21:20:13<Cale>Btw, for anyone interested in picking up measure theory: http://www.indiana.edu/~mathwz/PRbook.pdf
21:20:15<lambdabot>Title: Modern Real Analysis William P. Ziemer
21:20:23<quicksilver>ACTION notes in passing that using fromEnum/toEnum to implement pastorn's turn violates the fourth wall.
21:20:37<quicksilver>(well actually, it's deriving Enum that does that)
21:20:47<_zenon_>ACTION should go to bed now
21:21:06<inimino>lambdabot picks up titles from PDFs, huh, cool
21:21:57<inimino>quicksilver: which fourth wall is that?
21:22:23<olsner>the one between reality and fiction?
21:22:45<quicksilver>well, yes, the metaphor comes from the stage
21:22:51<BMeph>ACTION has a cousin that went to IU...some 15+years ago. :)
21:22:54<inimino>that's what I thought...
21:23:00<quicksilver>but the point is that GHC's lightweight metaprogramming (derivign Show, Enum and so on)
21:23:01<inimino>then I don't see the connection...
21:23:12<quicksilver>violate common laws of program transformation
21:23:21<quicksilver>programs aren't supposed to be able to see the names of their own variables
21:23:31<quicksilver>(alpha conversion says you can rename them)
21:23:40<inimino>oh
21:23:44<quicksilver>similarly, names of constructors, order of constructors in a data declaration.
21:23:58<quicksilver>all these things are conceptually safe to change/renumber/rename
21:24:07<quicksilver>but if you use deriving Enum/Show, they aren't any more :)
21:24:20<quicksilver>it's a bit like the fourth wall.
21:24:35<quicksilver>variables just "are", they don't know they have names
21:24:38<quicksilver>like characters in a play don't know they are actually actors.
21:24:39<inimino>well, if you look at Enums as names of subsequent small integers, then it's not a problem anymore
21:25:02<inimino>yeah, interesting analogy
21:25:07<quicksilver>sure, but that's not the haskell view
21:25:29<quicksilver>naively we want to think data A | B and data B | A are equivalent.
21:25:46<quicksilver>(it's not like C,C++ enum which really is defined in terms of numbers)
21:25:48<inimino>it's not the lambda calculus view
21:26:19<inimino>but yeah, anybody that sees "deriving Enum" is going to think of C
21:27:22<inimino>unless they don't, of course
21:31:07<Cale>quicksilver: The order in which the terms of the type are listed in the data declaration is also used for Ord instances.
21:31:26<Cale>(the derived ones)
21:32:24<subconscious>say you have some term like
21:32:36<subconscious>Foo (Bar X Y (Bar X))
21:32:46<subconscious>and a function that can substitute :: Term -> Term -> Term
21:33:05<subconscious>the you can partial apply (substitute <term> X) to have \z -> Foo (Bar z Y (Bar z))
21:33:32<subconscious>are there any other ways to get that (\z -> ...)?
21:33:57<Cale>(`substitute` X)?
21:34:10<subconscious>I mean other than a substitution function
21:34:11<Cale>But I think your type signature for substitute can't be right...
21:34:16<opqdonut_>order of the arguments is perverse anyway
21:34:25<subconscious>oh yeah thanks
21:34:29<subconscious>substitute :: Term -> Term -> Term -> Term
21:34:41<dibblego>is there a flip fmap somewhere?
21:34:41<quicksilver>Cale: yes, that's right
21:34:54<quicksilver>Cale: most of the deriving stuff violates this one way or another.
21:35:01<quicksilver>Cale: after all it's metaprogramming.
21:35:19<opqdonut_>subconscious: i'm not quite sure what you're after, but i'd say the only way is substitution
21:35:23<subconscious>so I actually start with, \z -> Foo (Bar z Y (Bar z))
21:35:24<quicksilver>I'm not particularly claiming it's a problem.
21:35:34<Cale>quicksilver: Right. It's too bad that we don't have a more general way to define ways to derive classes from the structure of a type.
21:35:39<quicksilver>but it's somsething to be aware of, if you're thinking about equational reasons and automatic refactorings.
21:35:40<subconscious>and I have to shove in some 'X' (that X comes from a supply/gensym monad)
21:35:40<jethr0>dibblego: mapM?
21:35:51<jethr0>sorry, forM
21:35:51<subconscious>then I do some monadic operation on the inside of the lambda, and abstract it out again
21:36:11<subconscious>what I'd really like is to do all that without a gensym
21:36:29<dibblego>forM is not flip fmap
21:36:34<subconscious>..except I haven't figured out a way, so has anyone seen this or any ideas?
21:36:37<inimino>what's a gensym?
21:36:46<inimino>symbol generator?
21:36:53<subconscious>inimino: I should get a totally unique symbol each time
21:37:07<Heffalump>so each z should be different?
21:37:08<subconscious>so basically a state monad with ["a","b",..] in it
21:37:18<subconscious>no each z should be the same objcet
21:37:18<inimino>ok, cool
21:37:39<subconscious>it's just that I have to gensym some 'X' apply it, operate on the inside of the lambda, and the abstract that 'X' out again
21:37:42<sjanssen>subconscious: what is wrong with using a substitution function? Seems like the right solution
21:37:51<subconscious>sjanssen: yes it does work
21:37:55<Heffalump>subconscious: sorry, I don't understand what you mean
21:37:58<opqdonut_>me neither
21:38:33<subconscious>actually,
21:38:53<opqdonut_>whats wrong with "fmap (\z -> Foo (Bar z Y (Bar z)))"
21:38:56<subconscious>in this code, http://moonpatio.com:8080/fastcgi/hpaste.fcgi/view?id=26#a42
21:39:11<subconscious>um not that one, oops
21:39:24<jethr0>dibblego: i am aware of that, hence the question mark. i was wondering if forM would be usefull to you, anyways
21:39:38<dibblego>jethr0, ah right thanks, but no :)
21:39:43<subconscious>in something like: foo (Lambda m) = \x -> foo (m x)
21:39:49<subconscious>since foo is pure that method works fine
21:39:50<jethr0>:t flip fmap
21:39:52<lambdabot>forall a b (f :: * -> *). (Functor f) => f a -> (a -> b) -> f b
21:39:56<jethr0>:t forM
21:39:57<lambdabot>forall a (m :: * -> *) b. (Monad m) => [a] -> (a -> m b) -> m [b]
21:39:59<subconscious>but if foo was monadic, how do you do this?
21:40:33<subconscious>like fooM (Lambda m) = do g' <- gensym ; m' <- fooM (m g') ; return (substitute m' g')
21:40:40<subconscious>that's the sort of thing I was describing earlier
21:40:48<subconscious>(as a monadic version, which is pretty hairy)
21:41:02<opqdonut_>what's wrong with that version?
21:41:25<subconscious>opqdonut_: Specifically, It would be great if this could be done without using gensym
21:41:39<opqdonut_>errr you mean generically?
21:42:04<Heffalump>have you looked at Applicative?
21:42:05<subconscious>I'm sure anything that works in this case would work for every case
21:42:50<pjdelport>wooh, Applicative
21:45:13<subconscious>would I write an Applicative instance for Term?
21:46:43<subconscious>I need a way to sort of run monadic actions out from under a lambda
21:47:03<subconscious>which is impossible? :)
21:47:31<binrapt>What does Lisp have over Haskell? What advantages does Haskell have over Lisp?
21:47:45<dons>?faq
21:47:45<lambdabot>The answer is: Yes! Haskell can do that.
21:48:15<SubStack>haskellicious
21:48:59<sm>lisp has macros and a conceptually simple non-lazy execution model and lack of types
21:49:59<sm>haskell has laziness, purity, conciseness and a well-organized, effective community
21:50:05<subconscious>did what I ask actually make any sense? :S
21:50:16<jethr0>haskell has a powerful type system
21:50:48<sm>damn, forgot that
21:50:55<opqdonut_>subconscious: no, not really
21:51:01<qwr>sm: lisp has types. at runtime.
21:51:21<sm>I know. Trying to answer briefly
21:51:36<jethr0>some lisps do for optimization reasons. is that a requirement to be a lisp?
21:53:09<Peaker>How about: Haskell has a complex system to detect type mismatches at compile time, and Lisp doesn't?
21:53:16<qwr>ACTION thinks lisp is some combination of sexp, dynamic types, function values and macros
21:53:24<jethr0>lisp systems tend to be very good at allowing code changes during runtime, leading to a very fluid development process, but lacking in static type safety compared to haskell
21:53:28<dmead>lisp is a really simple language
21:53:50<dmead>and who would set the requirements to "be a lisp"?
21:53:52<opqdonut_>dmead: you can't really be saying that
21:54:03<dmead>the syntax is very simple
21:54:05<dmead>is what i mean
21:54:05<ddarius>dmead: CL is certainly not simplye.
21:54:06<Cale>I would tend to be glib about it and say that Haskell is typed, while (common) lisp is untyped, but perhaps I have a different version of what it means to be typed than many people.
21:54:16<opqdonut_>yeah CL is extremely baroque
21:54:22<opqdonut_>even scheme isn't that simple
21:54:22<kyagrd>Hello
21:54:24<jethr0>john mccarthy
21:54:31<Cale>kyagrd: Hello!
21:54:46<dmead>Cale, my proff used to say that "it's essential untyped"
21:54:51<dmead>*essentially
21:54:54<kyagrd>I'm now in CUFP and while I am sitting down I was trying out Yi
21:54:56<opqdonut_>err, that "that" isn't really referring to the previous sentence
21:54:56<Cale>yeah.
21:55:11<dmead>CUFP?
21:55:12<kyagrd>But it still doesn't work for me.
21:55:20<subconscious>opqdonut_: well consider:
21:55:23<dmead>haskellers
21:55:24<subconscious>data T = App T T | Lam (T -> T)
21:55:24<subconscious>foo (App m n) = App (foo m) (foo n)
21:55:24<subconscious>foo (Lam m) = \x -> foo (m x)
21:55:27<jethr0>like many things, lisp and scheme are extremely simple at their core. the devil lies in the detail (like with gensyms, sane macros, byte code compiling, optimization, ...)
21:55:29<dmead>watch the debates tonight
21:55:33<kyagrd>CUFP = comercial users of functional programing
21:55:34<dmead>if you can vote in the electiojns
21:55:36<dmead>ah
21:55:56<subconscious>opqdonut_: What I want to do is write a fooM that's something like T -> m T
21:56:06<kyagrd>Has anyone succeeded installing yi using cabal in linux (especially in debian)?
21:56:20<dmead>whats yi?
21:56:24<dmead>the text editor right?
21:56:27<Cale>ACTION will try
21:56:32<jethr0>subconscious: i'm sorry i missed the first part of your discussion. but could you quickly recap what it is you're trying to do?
21:56:36<opqdonut_>subconscious: fooM (App m n) = liftM2 App (foo m) (foo n)
21:56:39<Cale>I'm pretty sure that I've gotten it to work that way in the past.
21:56:46<kyagrd>Editor written in Haskell it was demonstrated in Haskell workshop
21:56:49<Cale>I'll cabal update and try installing it.
21:57:00<opqdonut_>err, those foo's should be fooM's
21:57:00<dmead>ah
21:57:02<subconscious>jethr0: everything should be in the logs
21:57:04<kyagrd>I did it from scratch several times and updated as well
21:57:09<jethr0>hehe
21:57:16<Cale>kyagrd: How far does it get?
21:57:32<subconscious>opqdonut_: yeah that works for the App case
21:57:34<kyagrd>It compiles and installs all OK, the problem is
21:57:47<dons>kyagrd: a bunch of people.
21:57:58<dons>but i know the gtk frontend doesn't work on 64 bit (gtk bug)
21:58:01<opqdonut_>and fooM (Lam m) = fooM . m = \x -> fooM (m x)
21:58:03<dons>so you'll need the vty frontend.
21:58:06<opqdonut_>what's the problem?
21:58:07<kyagrd>As soon as it gets started it stucks with the error message Custom yi ("/home/kyagrd/.yi/yi-i386-linux") could not be launched!
21:58:18<kyagrd>It is a vtk frontend
21:58:25<subconscious>opqdonut_: that doesn't work though
21:58:29<jethr0>subconscious: you should really have a look at the scrap your boilerplate stuff. that seems to me to solve many of your problems (which i'm too lazy to look up in more detail in the logs ;)
21:58:30<kyagrd>frontend itself runs but it just gets stuck and only q (exit) works :(
21:58:37<opqdonut_>subconscious: oh?
21:58:42<subconscious>jethr0: no it doesn't relate to this
21:59:16<bd_>you need to be careful with SYB though - using it incorrectly can lead to a lot of excess allocation (at least it did when I overused it)
21:59:21<kyagrd>yi-i386-linux does not exist in my system but Yi just trys to launch it
21:59:48<subconscious>so basically I am trying to find a way to write this in haskell such that it types and stuff
21:59:53<kyagrd>I also tried the dev version from darcs still the same problem
22:00:27<opqdonut_>subconscious: also, there's the problem that the original foo doesn't seem to type
22:00:36<subconscious>it should be foo (Lam m) = Lam (\x -> foo (m x))
22:00:43<opqdonut_>yeah :)
22:00:53<bos>http://www.reddit.com/r/programming/comments/73smc/some_notes_on_the_future_of_haskell_and_fp/
22:00:54<lambdabot>Title: Some notes on the future of Haskell and FP : programming, http://tinyurl.com/4fo7wn
22:01:57<opqdonut_>subconscious: ah, now i guess i see the problem
22:02:10<dons>future of haskell, read and vote up :)
22:03:14<opqdonut_>subconscious: fooM (Lam m) = fmap Lam (fooM . m) ?
22:03:27<subconscious>opqdonut_: does that work?
22:03:37<opqdonut_>subconscious: checking it
22:03:53<BMeph>Is that legit, Reddit'ing your own blog entry? I'm suspicious... ;p
22:04:05<jethr0>subconscious: sorry, i'd love to help, but looking at the logs didn't really tell me in what context you're trying to accomplish what. maybe some of the other guys understand what you're really trying to do
22:04:11<jethr0>example code would always help
22:07:31<opqdonut_>subconscious: no, yeah, it can't work
22:07:41<opqdonut_>since the transformation inside Lam has to bue pure
22:07:44<opqdonut_>*be pure
22:07:59<opqdonut_>or hmm
22:08:09<subconscious>I wonder if there isn't some continuation passing way to write it
22:08:43<bos>BMeph: no, it's pretty normal.
22:09:54<ddarius>Isn't that encouraged?
22:10:36<Cale>bos: By the way, I just had one small criticism regarding your other talk (at least I think it was yours...). I feel that we should generally try to avoid telling people that typeclasses are ad-hoc polymorphism. (Because there are really significant differences, even though they can be used to simulate it.) I suppose for some audiences though, that might be the quickest way to get the idea across.
22:10:50<opqdonut_>hmm
22:11:09<opqdonut_>if I remember my theory right, there's no way to go from T -> m T to m (T->T)
22:11:13<opqdonut_>which is what this would need
22:11:23<bos>Cale: yeah
22:12:04<Cale>I didn't actually hear that talk though, I just saw some slides :)
22:12:13<Heffalump>how do they differ from ad-hoc polymorphism (with pre-declared overloadable things)
22:12:16<Heffalump>?
22:13:10<Cale>Heffalump: use of typeclass-polymorphic things can result in further typeclass-polymorphic things.
22:13:29<opqdonut_>subconscious: the obvious solution of course is to parametrise T over a (possibly applicative) functor f
22:13:30<Cale>Heffalump: That is, you don't have to pick an instantiation as soon as you use something.
22:13:49<subconscious>opqdonut_: That's not obvious to me, how does that look?
22:14:30<opqdonut_>data T f = App T T | Lam (T -> f T) -- one way
22:14:40<ddarius>Heffalump: They have more structure.
22:14:40<subconscious>and what happens with it?
22:14:59<opqdonut_>well then writing fooM becomes trivial :)
22:15:07<subconscious>how?
22:17:00<opqdonut_>fooM (Lam m) = Lam (m >=> fooM) -- for fooM :: Monad m => T m -> T m
22:17:17<Peaker>Cale: if types didn't have contexts (except for class methods themselves), would that mean that typeclasses only provide ad-hoc polymorphism?
22:17:37<opqdonut_>but sorry, gtg now
22:17:40<Cale>Peaker: Well, they would still have a bit more refined structure, but it would be closer.
22:18:15<dolio>@type Data.Traversable.sequence :: Monad m => (a -> m b) -> m (a -> b)
22:18:16<lambdabot> Could not deduce (Data.Traversable.Traversable ((->) a))
22:18:17<lambdabot> from the context (Monad m)
22:18:17<lambdabot> arising from a use of `Data.Traversable.sequence'
22:18:26<Cale>Peaker: If you had to pick a monomorphic instantiation wherever you applied a class member, then I would say it would be fine to call it ad-hoc polymorphism.
22:20:07<Peaker>Cale: I'm not sure what that means - class member is a method?
22:20:14<Cale>er, yes
22:20:20<Cale>class method, sorry
22:20:33<Peaker>well, you'd have to, because otherwise your function would need to include the class as a context?
22:20:37<Cale>right
22:20:59<Peaker>so without contexts, you have to pick monomorphic instantiations, no?
22:21:15<Cale>I think you would yes,
22:21:21<Cale>we're saying the same thing :)
22:21:33<Cale>You'd still have something over traditional systems of ad-hoc polymorphism though, since the class provides a structure for instances to fill in.
22:21:38<subconscious>opqdonut_: hm that has not got a valid kind
22:21:38<Peaker>yeah, I thought you said there was a difference and that I was misunderstanding something ;)
22:22:00<Cale>So you'd still know something about the type of a class method, wherever it occurred, without having to look at the instances or the surrounding context.
22:22:45<Cale>Usually systems for ad-hoc polymorphism allow you to overload things at any type at all.
22:23:21<Peaker>example?
22:23:40<Cale>Say you have...
22:23:46<Cale>class Ord t where
22:23:50<Cale> (<) :: t -> t -> Bool
22:24:21<Cale>Then you know wherever (<) occurs that its parameters have the same type, and that it's producing a Bool, and that it's actually a function ;)
22:24:33<tristes_tigres>Hello
22:24:43<Peaker>Cale: how is it possible to have a system where you don't know those things?
22:25:05<Cale>Peaker: You could have a system which just allowed you to define (<) many times at any type you wanted.
22:25:05<Peaker>s/how/why :)
22:25:05<subconscious>ACTION gives up
22:25:34<Cale>Peaker: and then differentiate between the definitions by making the type explicit in whatever way necessary.
22:25:51<Cale>(at the location where you're calling it)
22:26:16<Cale>Rather like:
22:26:19<Cale>class Ord t where
22:26:20<Peaker>but the args to (<) would still be of the same type?
22:26:23<Cale> (<) :: a
22:26:24<Cale> (<) :: t
22:26:26<Cale>rather ;)
22:26:48<subconscious>why is there no explanation about what == does in there http://www.haskell.org/ghc/docs/6.8.3/html/libraries/base/Data-STRef.html ?
22:26:50<lambdabot>Title: Data.STRef, http://tinyurl.com/4azvmk
22:27:05<Cale>subconscious: Because it's obvious?
22:27:11<Peaker>so when using (<) you specify that it is a function of 2 args of same type, and only then the instance that has that type is used?
22:27:14<Cale>subconscious: There's only one thing that it could possibly do.
22:27:17<subconscious>It's not obvious to me
22:27:28<Cale>subconscious: It tests if two STRefs are the same STRef.
22:28:10<Cale>subconscious: It can't possibly check if they have the same value, because the result of (==) is not in the ST monad.
22:28:43<Cale>Peaker: yeah.
22:28:58<Cale>Peaker: So classes let you enforce something about the structure of the various overloadings.
22:29:27<Cale>Peaker: Even when you don't use the fact that they let callers 'inherit polymorphism'.
22:30:22<Peaker>Then ad-hoc polymorphism sounds kind of like adding types into the name, so we can re-use cool names
22:30:51<Peaker>(Re-use (<) for other purposes, if they have type signatures other than a->a->Bool)
22:31:03<Cale>Peaker: yes, it's very much like that
22:31:15<Cale>Peaker: and so it's not nearly as powerful as typeclasses are.
22:31:24<Cale>You can't do quickcheck with ad-hoc polymorphism.
22:31:55<subconscious>> do (x@Just y) <- return 1 ; return (x,y)
22:31:56<lambdabot> mueval: Prelude.read: no parse
22:32:00<subconscious>this is mad
22:32:04<subconscious>you can't use @ in a monad
22:32:08<subconscious>do syntaxx
22:32:20<Peaker>One of the things most attractive about Haskell to me was the fact that names identified specific things, not different things in different "classes" (coming from an OO background)
22:36:46<Cale>Oh, another thing which you certainly can't do with ad-hoc polymorphism, though it's a special case of what we've already talked about, is things like instance Ord a => Ord [a] where ...
22:36:59<Cale>Where you define infinitely many overloadings with a single definition.
22:37:32<Peaker>Cale: that's definitely a cool property
22:38:05<subconscious>I guess I am just really bad at haskell
22:38:17<Cale>subconscious: What's wrong?
22:38:17<subconscious>I think I can't program what I wanted to without unconstrained mutation
22:38:29<Cale>What are you trying to write?
22:38:36<subconscious>this stuff with lambda
22:39:00<subconscious>I was writing a typechecker using the unification monad and HOAS
22:39:10<subconscious>so I have got a data type with STRefs throughout it
22:39:20<Peaker>> do { x@(Just y) <- (return (return 1)) ; return (x,y) }
22:39:21<subconscious>that just doesn't work together
22:39:21<lambdabot> No instance for (Show (t1 (Maybe t, t)))
22:39:21<lambdabot> arising from a use of `...
22:39:41<Peaker>funny, my ghci is ok with that
22:39:48<dmwit>defaulting
22:40:03<dmwit>Give it a specific monad to print from.
22:40:14<Cale>> do { x@(Just y) <- (return (return 1)) ; return (x,y) } :: Maybe (Maybe Integer, Integer)
22:40:15<lambdabot> Just (Just 1,1)
22:40:53<Peaker>subconscious: it appears you just need x@(spaced pat) and not (x@spaced pat)
22:41:19<dmwit>Peaker: ghci probably defaulted to IO (Maybe Integer, Integer).
22:41:28<Peaker>dmwit: Yeah, I just realized that too, thanks
22:41:40<Peaker>(everything in ghci seems to be evaluated in IO by default)
22:42:06<ddarius>@src Data.Set Monoid
22:42:07<lambdabot>Source not found. You untyped fool!
22:42:27<mattam>subconscious: STRefs and HOAS don't work together?
22:42:35<Cale>If things don't have a type which is compatible with being an IO action, then print is applied to them, and if they do, then they're executed in the IO monad.
22:42:39<subconscious>At least I can't make them useful together
22:42:56<Cale>Also, these days, it seems that print is applied to the result in the latter case, but that's really annoying.
22:43:51<mm_freak>no prolog channel =/
22:44:07<inimino>there's a setting that turns that off
22:44:27<Cale>Yeah, but it seems only to apply to some cases.
22:45:26<ddarius>:t Data.Set.toList
22:45:27<lambdabot>forall a. S.Set a -> [a]
22:48:08<Heffalump>subconscious: I think you'd have to overload the HOAS result type over a monad.
22:48:12<Heffalump>(or bake in ST)
22:48:30<Heffalump>hmm, perhaps that's not right.
22:48:35<subconscious>well I am trying thing with data T m = App (T m) (T m) | Lam (T m -> m (T m)) at the moment
22:48:44<subconscious>is that the right sort of idea?
22:49:10<Heffalump>perhaps - though actually you want the embedded functions to be pure, presumably?
22:49:15<Heffalump>Actually, why do you need STRefs?
22:49:23<subconscious>my unification algorithm uses them
22:49:38<Heffalump>why is doing unification on HOAS worthwhile?
22:49:58<Heffalump>(I ask as someone who is writing a library that uses HOAS all the way down and realising it's not necessarily a very good idea)
22:50:27<subconscious>Well I am starting the think I cannot do what I want with HOAS :)
22:50:34<subconscious>but I was hoping to use it the whole way
22:51:00<Heffalump>hmm, so why not pass in the STRefs as the parameters?
22:51:18<Heffalump>i.e. make the STRef only appear in the Var constructors
22:51:34<subconscious>data T s = TVar (Variable s (T s))
22:51:35<subconscious> | T s :-->: T s
22:51:36<subconscious>like this?
22:51:51<subconscious>(Variable means STRef)
22:52:03<Heffalump>I guess, yeah.
22:52:28<Heffalump>I would overload somehow so I could get pure terms too, though I'm not quite sure how to deal with s when doing that.
22:52:29<subconscious>I suppose I could recursive over the whole structure to create a map from STRef -> Term
22:52:37<subconscious>that would give a me a pure version of readST
22:52:38<Heffalump>perhaps just data T s = TVar (s (T s)) | ...
22:53:02<Heffalump>I'm not sure what you mean by that.
22:56:07<subconscious>what library is it you are writing by the way?
22:56:30<Heffalump>squiggle, an embedding of SQL
22:56:33<subconscious>oh cool
22:56:38<Heffalump>it doesn't need to do unification :-)
22:56:39<subconscious>and has HOAS caused any awkwardness?
22:56:46<Heffalump>yes, it can be really inefficient
22:56:54<subconscious>hm ok
22:56:57<Heffalump>suppose you have f :: Sql e -> Sql e
22:56:58<subconscious>I am really stumped
22:57:02<Heffalump>and optSE :: Sql e -> Sql e
22:57:15<Heffalump>i.e. f is the HOAS function and optSE is a syntax tree optimiser
22:57:26<Heffalump>then optSE . f is the obvious way to make an optimised f
22:57:33<Heffalump>but then optSE gets rerun each time you apply f
22:57:39<Heffalump>IM the optimised f
22:57:49<subconscious>ah yeah
22:57:58<subconscious>I think this is exactly the same problem I'm having
22:58:09<subconscious>if you consider evaluation as effect, it can't happen under a lambda
22:58:09<hackage>Uploaded to hackage: simple-sessions 0.1
22:58:09<hackage>Uploaded to hackage: ixdopp 0.1
22:58:09<hackage>Uploaded to hackage: preprocessor-tools 0.1
22:58:23<Heffalump>yeah, that's kind of similar
22:58:26<Heffalump>well, related.
22:58:37<Heffalump>I did play some nasty games to rebuild HOAS functions.
22:58:38<pfo> is there a quick way to lookup the implementation of Prelude functions (in emacs, or ghci) ?
22:58:40<Peaker>in L-Calculus, does \x->x x have a name?
22:58:46<subconscious>Peaker: U
22:58:54<Peaker>thanks
22:59:00<Heffalump>http://code.haskell.org/squiggle/ has my code
22:59:01<lambdabot>Title: Index of /squiggle
22:59:20<subconscious>cool, thank you
22:59:20<jethr0>@source lookup
22:59:20<lambdabot>lookup not available
22:59:28<jethr0>@source scanl
22:59:28<lambdabot>scanl not available
22:59:40<subconscious>Peaker: (U U) is called omega
23:00:22<Peaker>subconscious: is that useful?
23:02:33<dmwit>Peaker: Omega is usually the name for things that don't reduce.
23:02:40<dmwit>(Not sure about the context here, though.)
23:02:46<dmwit>i.e. an infinite loop
23:02:56<Peaker>oh
23:03:05<FunctorSalad_>well this omega here reduces to itself
23:03:30<subconscious>oh well
23:03:37<subconscious>since lambda prolog is broke
23:03:48<subconscious>I think I will just use a first order reperesentation of syntax in haskell
23:04:43<subconscious>that sucks :(
23:06:24<FunctorSalad_>subconscious: what is broke?
23:06:37<subconscious>teyjus
23:08:30<dmwit>FunctorSalad_: That's what I meant.
23:09:48<subconscious>I think I'm just really awful at programming in haskell and I just haven't realized it yet
23:10:03<Heffalump>programming with HOAS is not easy.
23:10:21<dmwit>?go HOAS
23:10:22<Heffalump>at least, I consider myself an expert Haskell programmer, and I found it hard.
23:10:24<lambdabot>http://www.hoas.fi/webV2/ase_inetV2.nsf/Frameset?OpenForm&01
23:10:24<lambdabot>Title: HOAS - Kotisivu
23:10:24<FunctorSalad_>subconscious: I struggled with something that sounds similar recently and felt dumb too :)
23:10:36<Heffalump>dmwit: Higher Order Abstract Syntax
23:10:45<subconscious>writing an evaluator on HOAS is fine, and type inference for STLC (as HOAS) with first order types is really simple
23:10:53<dmwit>Heffalump: Okay, I'll stay away. =)
23:10:53<subconscious>I just think this is a fundamental problem with HOAS
23:11:03<subconscious>like you can't have effects under a binding
23:11:35<Heffalump>it doesn't really make sense to have effects under a binding.
23:11:35<FunctorSalad_>effects under a binding?
23:11:42<Heffalump>I don't quite understand what you really need.
23:11:47<Heffalump>but I hope it's not that.
23:12:28<Heffalump>the effects are meta-language effects, but the binding is an object-language binding (or intended to become one)
23:12:42<subconscious>ACTION *nod*
23:12:59<subconscious>I think that is the root of the problem
23:13:15<Heffalump>actually, I have a function in squiggle that does something like that. Let me look for it.
23:13:28<subconscious>hi conal :)
23:13:37<conal>subconscious: hi
23:13:52<Heffalump>rebuildFuncM.
23:16:43<subconscious>so the rebuildE function sort traverses the syntax, abstracting out variables that need to be represented as abstractions?
23:16:49<subconscious>or am I misunderstanding that one+
23:17:08<subconscious>sort of traverses*
23:18:00<Heffalump>subconscious: it traverses the syntax rebuilding the expression from scratch.
23:18:29<subconscious>ah, and it does this in order to evaluate things that had been applied to it so far?
23:18:34<Heffalump>yep
23:18:54<Heffalump>it's important both for speed (after an optSE) and for correctness of the dead code elimination pass
23:23:01<subconscious>ACTION should perhaps write a version of the unifier that uses functions for substitutions instead of ST
23:23:45<Heffalump>I think if you want raw speed you shouldn't use HOAS anyway.
23:23:57<sm>how do I specify the package name in haddock ?
23:24:00<subconscious>I just didn't want to have to think about alpha conversion
23:24:06<Heffalump>though I don't know for sure that it's necessarily less efficient
23:24:11<Heffalump>yeah, that was my motivation too
23:24:17<Heffalump>also it fits better with GADTs
23:24:36<Heffalump>since the types of specific names match up for free
23:26:08<FunctorSalad_>precomposition with functions looks like the natural choice for substitutions
23:26:17<FunctorSalad_>not that I have much experience with this
23:26:39<subconscious>FunctorSalad_: yeah it works out really concise
23:27:43<FunctorSalad_>seems like one can't avoid plugging in symbols for Eq though?
23:27:57<FunctorSalad_>or Show
23:29:05<subconscious>Eq does simplify it but I don't think is essential
23:29:13<subconscious>I have: (i --> t) σ = \e -> if e == Var i then t else σ e
23:30:04<FunctorSalad_>I mean for deriving Eq for the whole data structure
23:30:51<subconscious>ah, so it's only applicable to first order data
23:31:11<dibblego>?index getArgs
23:31:11<lambdabot>System.Environment
23:32:35<Heffalump>FunctorSalad_: you just plug in the symbols when you want them, yeah
23:32:57<FunctorSalad_>OTOH maybe you can capsule the problem away by deriving Eq for the function types that appear in your binders?
23:33:10<FunctorSalad_>(with symbols, there)
23:33:57<steven_ashley>Hi everyone. I just had a thought regarding case statements and would be keen to hear your thoughts. It is probably best shown using an example. "getState >>= case of { Nothing -> setState (Just 10) ; Just _ -> return () }". The expression in the case statement is removed and instead the case expression acts as a function.
23:34:16<FunctorSalad_>hmm nevermind, I don't think this saves you from passing around the "fresh-index" counter
23:34:40<Heffalump>I presume that deriving Eq doesn't work for function types. I've never actually tried to do it.
23:34:57<FunctorSalad_>Heffalump: for function types Term -> Term
23:35:09<shrughes>steven_ashley: others have had that thought too
23:35:20<FunctorSalad_>you could check syntactic equality by plugging in symbols
23:35:26<dancor>can lbot tell me e.g. that Monoid takes one var
23:35:28<Heffalump>FunctorSalad_: yes, I know.
23:35:34<Heffalump>But I doubt deriving Eq would work.
23:35:44<steven_ashley>shrughes: I thought as much
23:35:50<dancor>i want like :k Monoid === ? -> *
23:35:55<FunctorSalad_>maybe its my misuse of the word "deriving", I mean "instantiate" ;-)
23:36:04<Heffalump>fair enough
23:36:12<Heffalump>I do that
23:36:17<dancor>@src Monoid
23:36:17<lambdabot>class Monoid a where
23:36:17<lambdabot> mempty :: a
23:36:17<lambdabot> mappend :: a -> a -> a
23:36:17<lambdabot> mconcat :: [a] -> a
23:36:25<dancor>i guess that's strictly cooler
23:36:47<shrughes>steven_ashley: http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase
23:36:48<dolio>steven_ashley: http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase
23:36:51<lambdabot>Title: LambdaCase - Haskell Prime - Trac
23:36:51<lambdabot>Title: LambdaCase - Haskell Prime - Trac
23:36:54<dolio>Heh.
23:36:59<subconscious>ACTION rewrites everything as de bruijn
23:37:05<steven_ashley>ahh, thanks :)
23:37:05<FunctorSalad_>@kind Monoid
23:37:07<lambdabot>Class `Monoid' used as a type
23:37:29<FunctorSalad_>oh, right ;-)
23:40:34<dons>btw, peoples, http://www.reddit.com/r/programming/comments/73smc/some_notes_on_the_future_of_haskell_and_fp/
23:40:36<lambdabot>Title: Some notes on the future of Haskell and FP : programming, http://tinyurl.com/4fo7wn
23:40:42<sm>it would be nice to be able to trigger ghci debugger from the code, like pdb.set_trace()
23:40:43<dons>make sure you're up to date on the state of haskell
23:40:52<subconscious>?
23:41:05<subconscious>or what?
23:41:13<shrughes>you'll get kicked out of the channel, that's what.
23:41:14<sm>thx dons!
23:41:23<dons>damn straight.
23:41:27<dons>no, its FYI.
23:41:37<subconscious>what's new
23:41:48<dons> * per-thread GC collection coming
23:41:48<dons> * data parallel Haskell is in preview
23:41:48<dons> * new native code generator
23:41:48<dons> * haskell platform: batteries included on its way
23:41:48<dons> * Haskell Prime is going open source
23:46:13<chadz>anyone play with Language.C much?
23:46:23<chadz>i'm guessing analyseFunDef hasn't really been implememted yet, since it's type is:
23:46:26<chadz>analyseFunDef :: MonadTrav m => CFunDef -> m ()
23:46:30<chadz>or, am I just assuming wrong?
23:49:29<FunctorSalad_>erm, why do I have "instance DC y y y2 y2" but get a "No instance for (DC (T Prop) (T x) Prop x)" error?
23:49:37<FunctorSalad_>some relative of the DMR? ;-)
23:51:28<subconscious>FunctorSalad_: forall x y, x doesn't necessarily equal y
23:51:40<subconscious>FunctorSalad_: so I think it's scared of unifying Prop with x for that reason
23:52:07<subconscious>(I am obviously guessing and don't actually _know_ though)
23:52:30<int-e>chadz: it does something to the accompanying DefTable. But I haven't really played with it, so I don't know what exactly is happening there.
23:54:25<FunctorSalad_>subconscious: ah, it doesn't want to restrict x to Prop?
23:54:44<FunctorSalad_>I just looked at it from the "find any match" perspective ;-)
23:56:00<Trinithis>@pl \f x y g -> f (g x) (g y)
23:56:00<lambdabot>flip flip (flip id) . (((.) . ap) .) . (. flip id) . (.)
23:56:25<Trinithis>@pl \f g x y -> f (g x) (g y)
23:56:25<lambdabot>join . ((flip . ((.) .)) .) . (.)
23:56:30<Trinithis>@pl \g f x y -> f (g x) (g y)
23:56:31<lambdabot>flip =<< ((flip . ((.) .)) .) . flip (.)
23:56:43<Trinithis>@pl \x y f g -> f (g x) (g y)
23:56:43<lambdabot>(. flip id) . flip . (ap .) . flip (.) . flip id
23:56:55<Trinithis>what's that ap trick with functions?
23:57:04<subconscious>:t ap
23:57:06<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
23:57:08<chadz>int-e: well, without actually trying to learn how the entire api works i started writing a little callgraph generator. i've managed to get a list the functions [FunDef], now I just need to figure out how to go from (FunDef -> CFunDef)
23:57:10<subconscious>:t ap (==)
23:57:11<lambdabot>forall a. (Eq a) => (a -> a) -> a -> Bool
23:57:15<subconscious>:t ap (==) (+1)
23:57:16<lambdabot>forall a. (Num a) => a -> Bool
23:57:21<subconscious>:t const False
23:57:22<lambdabot>forall b. b -> Bool
23:57:53<Botje>f `ap` g = \x -> f x (g x)
23:57:56<Trinithis>> ((+) `ap` (*2) ) 3
23:57:57<lambdabot> 9
23:58:03<Trinithis>ah now I remember

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