Experimental IRC log haskell-2007-10-15

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

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

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

00:00:03<dons>to abstract out the parameter passing
00:00:14<dons>?go Random Supply site:haskell.org
00:00:17<lambdabot>http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-Random.html
00:00:28<dons>hmm, there's a wiki page showing a few of the possible designs
00:00:31<ToxicFrog>I would just rather not have to hand around the list and/or generator, as it makes my signatures way nastier and, in the end, probably removes any clarity of ease-of-dev benefit from using Haskell in the first place.
00:00:48<dons>would you like example code? its really rather clean
00:00:59<ToxicFrog>I would greatly appreciate that, yes.
00:01:05<dons>i'm not quite sure what you're envisaging the code as
00:01:14<yitz>No, it's not all that bad. But yes, using a State monad makes this nice in my opinion.
00:01:15<dons>so perhaps an example, using explicit parameters, and then State
00:01:21<dons>yeah
00:01:57<dibblego>?src Either return
00:01:58<lambdabot>return = Right
00:04:12<dmwit>?src Either fail
00:04:13<lambdabot>fail msg = Left (strMsg msg)
00:04:22<dmwit>:t strMsg
00:04:25<lambdabot>forall a. (Error a) => String -> a
00:06:53<omnId>@instances Error
00:06:55<lambdabot>IOError, [Char]
00:09:38<hpaste> dons pasted "a State threading a list of randoms" at http://hpaste.org/3293
00:09:45<dibblego>?check \f x -> Left (x :: Int) >>= (f :: Int -> Either Int Int) == Left x
00:09:46<lambdabot> Couldn't match expected type `Int -> Either Int Int'
00:10:22<dons>ToxicFrog: so if you look at that hpaste, you see the 'main', in io, getting a new seed. then mapMaybe applies a function to a list, depending on a random Bool value threaded in the State
00:10:31<dons>we run it a few times to see the randoms change
00:11:05<dons>so all your code for manipulating stuff based on randoms is pure, everything past the zipWith
00:11:30<omnId>more n = State (splitAt n)
00:12:01<dons>yeah, refactor as you wish. you can compress it a fair bit more if needed
00:12:14<ricky_clarkson>Would the digits of PI be an adequate random number generator?
00:12:32<omnId>ricky_clarkson: they're always the same :)
00:12:41<dons>so you'd need a random offset into the digits
00:12:50<ricky_clarkson>omnId: What isn't?
00:12:53<monochrom>I think it's an open question.
00:13:24<ricky_clarkson>Well, if you find that they're not adequate, you're probably about to become famous.
00:13:47<dons>ToxicFrog: so, any questions?
00:13:57<monochrom>The actual open question is: lim n->oo (# of occurences of d in the first n digits)/n = 1/10?
00:14:31<ToxicFrog>dons: lots, starting with what evalState and zipWith do, but I think I can hit the docs for those
00:14:41<nornagon>dons: you couldn't really do that in a nice way, because finding the nth digit of pi is not an O(1) operation
00:14:45<ToxicFrog>and mapMaybe can be called from pure code?
00:15:01<nornagon>:t mapMaybe
00:15:04<lambdabot>forall a b. (a -> Maybe b) -> [a] -> [b]
00:15:06<dons>its not that one. sorry
00:15:16<dons>but we could use it
00:15:37<dons>ToxicFrog: so evalState threads the randoms through your code
00:16:38<omnId>*Main> :t mapMaybe
00:16:38<omnId>mapMaybe :: (MonadState [Bool] t) => (a -> a) -> [a] -> t [a]
00:17:58<_achilles_>is it possible to add two items in a list comprehension, without doing tuples?
00:18:26<ddarius>> [x + y | x <- [1..10], y <- [10..14]]
00:18:26<mauke>huh?
00:18:28<lambdabot> [11,12,13,14,15,12,13,14,15,16,13,14,15,16,17,14,15,16,17,18,15,16,17,18,19,...
00:18:56<dons>> zipWith (+) [1..10] [10..20] -- zipwith strikes again
00:18:58<lambdabot> [11,13,15,17,19,21,23,25,27,29]
00:19:24<dons>you can use parallel list comprehensions too, though they're newish
00:19:33<_achilles_>[x : y | x <- [1..5], y <- [1..10]]
00:19:33<omnId>the first does all combinations
00:19:46<omnId>y would have to have type [Int]
00:19:46<mauke>_achilles_: type error
00:19:51<_achilles_>right
00:19:52<chessguy>what are parallel list comprehensions?
00:19:57<_achilles_>I'm asking if it's possible
00:19:58<mauke>No instance for Num [Integer]
00:20:04<Tac-Tics>> [[x, y] | x <- [1..5], y <- [1..10]]
00:20:07<lambdabot> [[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,1],[2,2],[2...
00:20:16<_achilles_>hmmm
00:20:24<omnId>> [x+y | x <- [1..3] | y <- [4..6]] -- chessguy
00:20:25<lambdabot> Parse error
00:20:39<omnId>not the right syntax? Never used 'em.
00:21:05<chessguy>maybe they're in HEAD
00:21:09<mauke>lambdabot doesn't parse the syntax
00:21:21<_achilles_>I'm looking for a more...consise way to do it
00:21:22<dons>that's the syntax, but its not h98
00:21:33<dons>_achilles_: zipwith is the best i can think of
00:21:33<omnId>parallel would give: [5,7,9] vs ordinary: [5,6,7,6,7,8,7,8,9]
00:21:34<_achilles_>I want the lists concated
00:21:44<mauke>> [1..5] ++ [1..10]
00:21:46<lambdabot> [1,2,3,4,5,1,2,3,4,5,6,7,8,9,10]
00:22:00<dons>`add two items in a list comprehension' ?
00:22:04<_achilles_>yeah, granted my example is more complicated than that
00:22:11<_achilles_>hah
00:22:17<_achilles_>now I get why you're confused
00:22:26<_achilles_>apped two items in a list comprehension
00:22:30<ricky_clarkson>Example input, example output.
00:22:30<_achilles_>append***
00:22:41<nornagon>:t (***)
00:22:43<lambdabot>forall (a :: * -> * -> *) b c b' c'. (Arrow a) => a b c -> a b' c' -> a (b, b') (c, c')
00:22:49<omnId>[ x : xs | x <- heads, xs <- tails] ?
00:22:49<nornagon>:t append
00:22:52<lambdabot>Not in scope: `append'
00:23:03<nornagon>rats.
00:23:13<chessguy>@type heads
00:23:15<lambdabot>Not in scope: `heads'
00:23:21<_achilles_>[x : x ^ 2 | x <- [1..4]]
00:23:24<_achilles_>output
00:23:24<nornagon>heads is equal to 'the list'
00:23:43<_achilles_>[1,1,2,4,3,8,4,16]
00:23:49<nornagon>@let heads l = l :: forall a. [a] -> [a]
00:23:50<lambdabot> Parse error
00:23:50<omnId>> concatMap (\x -> [x, x^2]) [1..4]
00:23:52<lambdabot> [1,1,2,4,3,9,4,16]
00:24:01<mauke>_achilles_: stop misusing :
00:24:02<_achilles_>ahhhhh
00:24:04<_achilles_>damnit!
00:24:13<_achilles_>I knew I could do it with concatMap
00:24:20<_achilles_>my brain's dead tonight
00:24:22<_achilles_>thanks!
00:24:22<omnId>> concat [[x, x^2] | x <- [1..4]]
00:24:23<lambdabot> [1,1,2,4,3,9,4,16]
00:24:36<mauke>> [ y | x <- [1 .. 4], y <- [x, x ^ 2] ]
00:24:37<_achilles_>ooo...beuty omnld
00:24:38<lambdabot> [1,1,2,4,3,9,4,16]
00:24:41<mauke>surprise!
00:24:46<omnId>oh, silly me
00:24:53<_achilles_>beauty*
00:24:53<Pseudonym>> foldr (.) [] [ (x:) . (x^2:) | x <- [1..4] ]
00:24:54<lambdabot> Couldn't match expected type `a -> c' against inferred type `[a1]'
00:25:17<ricky_clarkson>> foldl (++) [] $ map (\x -> x : x^2) [1..4]
00:25:18<lambdabot> Occurs check: cannot construct the infinite type: a = [a]
00:25:18<lambdabot> Expected...
00:25:34<omnId>Pseudonym: s/[]/id/ then add [] to the end?
00:25:48<Pseudonym>Yeah, that's what I just did.
00:25:49<_achilles_>slick. thanks!
00:25:55<Pseudonym>But I don't like it.
00:26:24<mauke>> do x <- [1 .. 4]; y <- [x, x ^ 2]; return y
00:26:26<lambdabot> [1,1,2,4,3,9,4,16]
00:26:28<ricky_clarkson>> foldl (++) [] $ map (\x -> [x,x^2]) [1..4]
00:26:30<lambdabot> [1,1,2,4,3,9,4,16]
00:26:33<shachaf>ricky_clarkson: You mean (x : [x^2]) (or just [x,x^2]).
00:26:39<Pseudonym>> [1..4] >>= \x -> [x,x^2]
00:26:41<lambdabot> [1,1,2,4,3,9,4,16]
00:26:52<shachaf>Why foldl (++) []?
00:27:03<omnId>foldr'd be much better
00:27:07<Pseudonym>> concatMap (\x _> [x,x^2]) [1..4]
00:27:07<lambdabot> Parse error
00:27:13<Pseudonym>> concatMap (\x -> [x,x^2]) [1..4]
00:27:13<omnId>and anyway concat is already defined :)
00:27:14<lambdabot> [1,1,2,4,3,9,4,16]
00:27:22<mauke>> [1 .. 4] >>= id &&& (^2)
00:27:23<mauke>wait, no
00:27:23<lambdabot> Couldn't match expected type `[]' against inferred type `(,) t'
00:27:28<ricky_clarkson>shachaf: What else?
00:27:37<shachaf>ricky_clarkson: foldr (or concat).
00:27:40<omnId>ricky_clarkson: foldr!
00:27:50<mauke>> [1 .. 4] >>= sequence [id, (^2)]
00:27:52<lambdabot> [1,1,2,4,3,9,4,16]
00:28:02<omnId>(xs ++ ys) ++ zs walks over xs twice vs. xs ++ (ys ++ zs)
00:28:24<ricky_clarkson>shachaf: Same line, but s/foldl/foldr/ ?
00:28:29<shachaf>@src concat
00:28:29<lambdabot>concat = foldr (++) []
00:28:35<shachaf>ricky_clarkson: But yes, otherwise.
00:28:45<shachaf>ricky_clarkson: Since lists are lazy enough, foldr is better.
00:29:11<shachaf>ricky_clarkson: http://haskell.org/haskellwiki/Stack_overflow
00:29:12<lambdabot>Title: Stack overflow - HaskellWiki
00:29:24<ricky_clarkson>Gotcha.
00:30:21<shachaf>ricky_clarkson: If you were using foldl, you'd probably want foldl', anyway. Not that it really matters with lambdabot.
00:31:36<monochrom>Yeah, lambdabot cuts your job short anyway. :)
00:32:38<ricky_clarkson>I'm guessing concatMap is the same as concat map, but I'm struggling to actually see that.
00:32:53<lambdabot>Don't tell them that. I'm gonna be asked so many homework questions. Sign.
00:33:00<lambdabot>Sigh.
00:33:04<shachaf>Wouldn't -O2 optimize it in this case?
00:33:18<ddarius>@src concatMap
00:33:18<lambdabot>concatMap f = foldr ((++) . f) []
00:33:22<shachaf>ricky_clarkson: concatMap f xs = concat (map f xs)
00:33:27<Pseudonym>>/msg lambdabot ?help check
00:33:36<Pseudonym>D'oh.
00:33:55<Pseudonym>?check \f xs -> concatMap f xs == concat (map f xs)
00:33:56<lambdabot> Add a type signature
00:33:59<ddarius>concatMap f = concat . map f
00:34:14<Pseudonym>?check \f xs -> concatMap (f::Integer->Integer) xs == concat (map f xs)
00:34:15<lambdabot> Couldn't match expected type `[b]' against inferred type `Integer'
00:34:26<Pseudonym>?check \f xs -> concatMap (f::Integer->Integer) (xs::Integer) == concat (map f xs)
00:34:27<lambdabot> Couldn't match expected type `[b]' against inferred type `Integer'
00:34:31<shachaf>concatMap = (concat .) . map
00:34:35<Pseudonym>?check \f xs -> concatMap (f::Integer->Integer) (xs::[Integer]) == concat (map f xs)
00:34:36<lambdabot> Couldn't match expected type `[b]' against inferred type `Integer'
00:34:40<Pseudonym>Grrr.
00:34:42<ddarius>:t concatMap
00:34:44<lambdabot>forall a b. (a -> [b]) -> [a] -> [b]
00:34:52<yitz>@pl concatMap
00:34:52<lambdabot>(=<<)
00:35:04<ddarius>shachaf: Indeed, but I think the concat . map f is perhaps the clearest form
00:35:04<wolverian>heh
00:35:13<shachaf>ddarius: Yes.
00:35:15<Pseudonym>?check (\f xs -> concatMap f xs == concat (map f xs)) :: (Int -> Int) -> [Int] -> Bool
00:35:16<lambdabot> Couldn't match expected type `[b]' against inferred type `Int'
00:35:25<shachaf>ddarius: Or the concatMap f xs = ... version.
00:35:32<Pseudonym>Oh.
00:35:42<Pseudonym>?check (\f xs -> concatMap f xs == concat (map f xs)) :: (Int -> [Int]) -> [Int] -> Bool
00:35:47<lambdabot>Terminated
00:35:50<ddarius>If we expand concat into foldr (++) [], we get foldr (++) [] . map f which by foldr/map is foldr ((++) . f) []
00:35:51<Pseudonym>Hrm.
00:35:54<ddarius>@src concatMap
00:35:54<lambdabot>concatMap f = foldr ((++) . f) []
00:37:58<ddarius>That is what "point-free" style is supposed to look like.
00:38:19<Pseudonym>?pl \f -> foldr ((++).f) []
00:38:19<lambdabot>flip foldr [] . ((++) .)
00:40:14<LoganCapaldo>this is madness
00:40:22<LoganCapaldo>this is blaspemy
00:40:31<LoganCapaldo>this is POINTFREE!
00:40:50<mauke>SPARTA CALCULUS
00:40:52<ricky_clarkson>I love it.
00:41:12<LoganCapaldo>I have yet to wear that out for myself
00:41:26<LoganCapaldo>which is pretty impressive I think, since its so very formulaic
00:42:26<monochrom>Sparta?
00:46:39<Beelsebob>gyah
00:46:47<Beelsebob>need a good example of patern matching, without recursion
00:47:15<LoganCapaldo>@src isJust
00:47:15<lambdabot>isJust Nothing = False
00:47:15<lambdabot>isJust _ = True
00:47:28<LoganCapaldo>that's not recursive
00:47:43<Beelsebob>hmm, could work
00:47:47<LoganCapaldo>@src head
00:47:47<lambdabot>head (x:_) = x
00:47:47<lambdabot>head [] = undefined
00:47:53<LoganCapaldo>@src tail
00:47:53<lambdabot>tail (_:xs) = xs
00:47:53<lambdabot>tail [] = undefined
00:48:05<LoganCapaldo>@src maybe
00:48:05<lambdabot>maybe n _ Nothing = n
00:48:05<lambdabot>maybe _ f (Just x) = f x
00:48:58<LoganCapaldo>@src either
00:48:58<lambdabot>either f _ (Left x) = f x
00:48:58<lambdabot>either _ g (Right y) = g y
00:49:09<Beelsebob>yeh, that works
00:49:14<Beelsebob>thanks
00:49:14<LoganCapaldo>etc. etc.
00:49:22<Beelsebob>don't know why my brain couldn't come up with any of them
00:49:34<Beelsebob>I was coming up with contrived examples involving witches and ducks
00:49:41<LoganCapaldo>LOL
00:49:48<LoganCapaldo>I want to see those examples!
00:49:53<Beelsebob>hehe
00:50:07<Beelsebob>I couldn't express it in a purely pattern matching way :(
00:50:08<monochrom>witches I understand. ducks?
00:50:24<Beelsebob>monochrom: watch monty python and the holy grail
00:50:25<LoganCapaldo>if she weighs the same as a duck...
00:50:32<LoganCapaldo>then
00:50:36<LoganCapaldo>She's a witch!
00:50:41<LoganCapaldo>burn her burn her!
00:50:53<Pseudonym>That's the flaw with duck typing.
00:50:55<monochrom>OK, I haven't watched monty python anyway. BTW, I haven't watched python anything either.
00:51:03<Beelsebob>it follows the best piece of un-logic in existance
00:51:12<Pseudonym>If it weighs the same as a duck, it may be a witch.
00:51:17<Beelsebob>how to identify a witch...
00:51:18<yitz>ni
00:51:25<Beelsebob>what do you do with witches? Burn them
00:51:35<Beelsebob>why do witches burn? Because they're made of wood
00:51:37<Pseudonym>Build a bridge out of them?
00:51:38<monochrom>data She = Witch | Duck; f Witch = True; f Duck = false
00:51:59<LoganCapaldo>small stones!
00:52:26<Beelsebob>what else does wood do? Float
00:52:34<Beelsebob>what else floats? Ducks
00:52:46<Beelsebob>so if something weighs the same as a duck, it must be a witch
00:52:47<Beelsebob>:)
00:52:55<yitz>favoriteColor = const Red
00:53:18<monochrom>If something has the same density as a Duck, then it's a Float?
00:53:52<monochrom>@type isIEEE
00:53:54<lambdabot>forall a. (RealFloat a) => a -> Bool
00:54:02<monochrom>And so it's also a RealFloat?
00:54:06<Sgeo>const? Sorry, it's been a while since I've worked with Haskell
00:54:17<Sgeo>@type const
00:54:19<lambdabot>forall a b. a -> b -> a
00:54:27<mrd>@djinn a -> b -> a
00:54:27<lambdabot>f a _ = a
00:54:30<Sgeo>oh
00:54:31<ddarius>@. djinn type const
00:54:33<lambdabot>f a _ = a
00:56:28<LoganCapaldo>I like constantly
00:56:37<LoganCapaldo>constantly True
00:56:45<LoganCapaldo>but that's a lot of typing
00:56:47<mauke>forevermore
00:56:52<LoganCapaldo>oooo
00:56:55<LoganCapaldo>pretty
00:57:04<ddarius>@quote λ
00:57:04<lambdabot>No quotes match. I've seen penguins that can type better than that.
00:57:19<LoganCapaldo>and that's impressive
00:57:23<LoganCapaldo>because penguins lack fingers
00:57:33<LoganCapaldo>not to mention opposable thumbs
00:57:34<Beelsebob>@quote+ λx x
00:57:34<lambdabot>No quotes for this person. Just what do you think you're doing Dave?
00:57:38<ToxicFrog>Argh.
00:57:47<Beelsebob>bah
00:57:50<mauke>@quote
00:57:51<lambdabot>xahlee says: The Haskell Logo is the perfection of logos
00:57:52<Beelsebob>how do you add a quote
00:58:07<shachaf> @remember
00:58:07<Beelsebob>and can we make the quote system into a complete term rewriter :D
00:58:09<Sgeo>@quote Sgeo
00:58:10<lambdabot>No quotes match. I've seen penguins that can type better than that.
00:58:12<ToxicFrog>I keep getting "cannot construct the infinite type a -> [a]"
00:58:12<LoganCapaldo>@remember Beelsebob how do you add a quote
00:58:12<lambdabot>Done.
00:58:14<Sgeo>@quote goldilocks
00:58:15<lambdabot>No quotes match. Are you on drugs?
00:58:23<ddarius>There's no consistency in lambdabot's user interface
00:58:32<Beelsebob>indeed
00:58:33<LoganCapaldo>@ is pretty consistent
00:58:42<ddarius>?bot
00:58:43<lambdabot>:)
00:58:43<mauke>?vixen is it?
00:58:44<Beelsebob>> no "it's not"
00:58:44<lambdabot>yeah, it is
00:58:45<lambdabot> Not in scope: `no'
00:58:45<LoganCapaldo>except you can use ? instead
00:58:56<Pseudonym>Oooh, another Monty Python reference.
00:58:56<LoganCapaldo>and theres > which is short for @run
00:59:10<Pseudonym>"What's that on the IRC channel?" "Looks like a penguin!"
00:59:34<mauke>@eval (\x -> x x) (\x -> x x)
00:59:45<Pseudonym>:t \x -> x x
00:59:47<lambdabot> Occurs check: cannot construct the infinite type: t = t -> t1
00:59:47<lambdabot> Probable cause: `x' is applied to too many arguments
01:00:03<ddarius>:t \(x :: forall a.a -> a) -> x x
01:00:05<lambdabot>forall a. (forall a1. a1 -> a1) -> a -> a
01:00:12<ToxicFrog>dons: still around?
01:00:34<Pseudonym>:t let f = \(x :: forall a. a -> a) -> x x in f f
01:00:36<lambdabot> Couldn't match expected type `a' (a rigid variable)
01:00:37<lambdabot> against inferred type `forall a1. a1 -> a1'
01:01:50<ToxicFrog>Hrm. At first I thought the problem was recursion, but even with a non-recursive function it blows up
01:08:06<ToxicFrog>...and if I give it an explicit signature, I get "cannot match expected type State s t against inferred type [Integer]" in the caller, and "cannot match expected type Integer against inferred type [Integer]" in the definition.
01:08:18<mauke>you're doing it wrong
01:08:44<vonBergmann>i'd like to fold the min function over every second element of a list of tuples and return that tuple
01:08:47<vonBergmann>foldr1 min [(8,2),(3,4),(5,6)]
01:09:00<ToxicFrog>mauke: I noticed.
01:09:01<vonBergmann>is pretty close but it's folding min over the first element and not the second
01:09:09<mauke>> minimumBy snd [(8,2),(3,4),(5,6)]
01:09:10<lambdabot> Occurs check: cannot construct the infinite type:
01:09:10<lambdabot> b = (a, b) -> Or...
01:09:14<mauke>argh, right
01:09:27<mauke>> minimumBy (comparing snd) [(8,2),(3,4),(5,6)]
01:09:29<lambdabot> (8,2)
01:09:44<vonBergmann>actually i lied, i'd actually like to fold over triples
01:09:47<vonBergmann>over the third element
01:10:16<vonBergmann>can i access that third element without pattern matching?
01:10:19<mauke>> minimumBy (comparing (\(_,_,x) -> x)) [(8,2,"foo"),(3,4,"bar"),(5,6,"baz")]
01:10:21<lambdabot> (3,4,"bar")
01:10:57<ToxicFrog>It works fine as long as monads aren't involved, but that breaks the randomness. Aaaaaaaagh
01:11:30<vonBergmann>ok not quite sure i understand the example but i study and work through it for a bit, thanks mauke
01:12:01<mauke>:t minimumBy
01:12:05<lambdabot>forall a. (a -> a -> Ordering) -> [a] -> a
01:12:13<vonBergmann>:t comparing
01:12:15<lambdabot>forall b a. (Ord a) => (b -> a) -> b -> b -> Ordering
01:14:32<ToxicFrog>...ok, what the fuck?
01:14:45<ToxicFrog>If I take the code that works without a signature...
01:15:01<ToxicFrog>Ask ghci for the type (which is 'mutate :: (Ord t, MonadState [t] t1, Num a, Fractional t) => [a] -> t1 [a]')...
01:15:05<ToxicFrog>...and add that to the source...
01:15:07<newsham>ddarius: falseElim np2false = orElim exclMiddle (\p -> p) (\np -> absurd (np2false np))
01:15:16<ToxicFrog>It says it's an illegal type declaration.
01:15:16<vonBergmann>i've never used minimumBy before and looking it up at sites like: http://www.zvon.org/other/haskell/Outputglobal/index.html isn't very helpful because the documentation is incomplete.... what are some better sources?
01:15:18<lambdabot>Title: Haskell
01:15:22<conal>does anyone have a pretty printer for haskell code that handles precedence (paren insertion)?
01:17:05<mauke>@source Data.List
01:17:05<lambdabot>http://darcs.haskell.org/packages/base/Data/List.hs
01:17:10<mauke>@docs Data.List
01:17:11<lambdabot>http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html
01:20:47<vonBergmann>sorry another dumb question, so is the best source for all the documentation at haskell.org? how does looking up haskell documentation compare to something like the java api?
01:21:18<vonBergmann>is minimumby not available at zvon because it is relatively new?
01:21:23<mauke>I don't know about java but I usually start at http://www.haskell.org/ghc/docs/latest/html/libraries/
01:30:18<newsham>http://www.thenewsh.com/%7Enewsham/formal/curryhoward/Theorems3.hs
01:30:21<lambdabot>http://tinyurl.com/2zhgbh
01:32:11<ToxicFrog>Maybe I should just give up on this and return to Haskell later, for a project that doesn't need random numbers.
01:32:17<monochrom>I have never heard of zvon.
01:32:20<Philippa>ACTION wishes she could get away with writing lhs `infix' p` rhs as a parser :-(
01:32:49<Philippa>(where p would be dropped, lhs and rhs are arbitrary parsers - the problem is that you can only do `<identifier>`)
01:32:57<Philippa>and it'd be cute
01:33:11<shachaf>Philippa: There was that trick with... -: and :-, I think?
01:33:32<Philippa>yeah, that's getting obscure enough not to be worth it in terms of readability though
01:36:33<newsham>i wish you could put bars/superscripts/hats over operators to do something like that.
01:36:45<newsham>ie. +^ = liftM 2 (+)
01:37:20<shachaf>newsham: That's a slippery slope that leads to J-land.
01:37:52<newsham>I dont know J, but I've been looking at funmath (notation, not computer language) and i like it
01:38:23<newsham>they have symbols above binops for lifting into (->) in various ways
01:38:38<newsham>(lift binary, lift just left section, lift right section)
01:39:59<FMota>hey guys / gals
01:40:26<FMota>is there a way to cut off from a list when a certain condition is met?
01:40:42<newsham>takeWhile / dropWhile?
01:40:43<mauke>takeWhile
01:40:46<FMota>I mean, a way to extract the first x values of the list, that depends on the values
01:40:48<FMota>ah, ty
01:41:09<mauke>> takeWhile even [ 2 .. 20 ]
01:41:11<lambdabot> [2]
01:41:16<newsham>> dropWhile (<10) [1..30]
01:41:17<lambdabot> [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]
01:41:53<FMota>ACTION is doing the euler project :)
01:47:03<SamB>ACTION wonders how he came to be a latex user
01:47:06<FMota>...and what about a function to see if an item is in a list?
01:47:34<LoganCapaldo>@type find
01:47:37<lambdabot>forall a. (a -> Bool) -> [a] -> Maybe a
01:47:40<LoganCapaldo>@type filter
01:47:43<lambdabot>forall a. (a -> Bool) -> [a] -> [a]
01:47:44<idnar>:t elem
01:47:47<lambdabot>forall a. (Eq a) => a -> [a] -> Bool
01:47:49<FMota>aha
01:47:50<LoganCapaldo>@type any
01:47:52<FMota>thank you!
01:47:52<lambdabot>forall a. (a -> Bool) -> [a] -> Bool
01:47:54<FMota>elem :)
01:48:36<idnar>> let l = [1..10] in (elem 5 l, elem 15 l)
01:48:41<newsham>?docs Data.List
01:48:41<lambdabot>http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html
01:48:42<lambdabot> (True,False)
01:49:09<LoganCapaldo>I wonder if elem is written with any or elemIndex?
01:49:14<LoganCapaldo>@src elem
01:49:14<lambdabot>elem x = any (== x)
01:50:15<chessguy>@type elemIndex
01:50:17<lambdabot>forall a. (Eq a) => a -> [a] -> Maybe Int
01:50:30<chessguy>@src elemIndex
01:50:30<lambdabot>elemIndex x = findIndex (x==)
01:50:41<chessguy>@src findIndex
01:50:42<lambdabot>findIndex p = listToMaybe . findIndices p
01:51:04<chessguy>quite a few levels of abstraction
01:51:12<chessguy>@src findIndices
01:51:12<lambdabot>findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
01:51:50<chessguy>@src listToMaybe
01:51:50<lambdabot>listToMaybe [] = Nothing
01:51:51<lambdabot>listToMaybe (a:_) = Just a
01:53:50<mudge>hey chessguy, hey LoganCapaldo
01:54:12<chessguy>'evening, sir
01:54:31<LoganCapaldo>hola
01:56:41<ToxicFrog>Argh. Bollocks to this, I don't have time to sort it out, I'll come back to Haskell for the next project.
01:57:09<chessguy>what sort of project are you working on, ToxicFrog ?
01:57:41<LoganCapaldo>a frog antitoxin?
01:57:46<ToxicFrog>Genetic algorithms.
01:57:51<ToxicFrog>For which I need random numbers.
01:57:54<ToxicFrog>Which are made of pain.
01:58:00<chessguy>lol
01:58:15<chessguy>i've done some working on genetic programming in haskell
01:58:22<Pseudonym>Oh, we have a mechanism for pain in Haskell.
01:58:23<chessguy>never did find a way to do it that satisfied me
01:58:26<ToxicFrog>The whole thing is pretty clean and elegant in Haskell until I get to the random numbers.
01:58:29<Pseudonym>http://andrew.bromage.org/unsafe.jpeg
01:58:31<chessguy>@quote pain
01:58:31<lambdabot><basti_> says: Snow doeth lay upon the lands. Even with cunning newtype; deriving the newtype is recursive. Great leaders brings less pain.
01:58:32<LoganCapaldo>unsafePerformTorture
01:59:12<LoganCapaldo>the # is the perfect touch
01:59:17<Pseudonym>Yeah.
01:59:20<ToxicFrog>Then I feel sorrow.
01:59:23<ToxicFrog>So much sorrow./
01:59:49<Pseudonym>I did some genetic programming, but my mutation/breeding/whatever stuff was pretty simple.
01:59:57<Pseudonym>I thought it was pretty elegant.
02:00:04<Pseudonym>Probably because of the simplicity.
02:00:08<ToxicFrog>So's mine, but it needs randoms.
02:00:12<chessguy>Pseudonym, i'd like to see that sometime
02:00:14<LoganCapaldo>What about the Random monad? does thtat ease the pain?
02:00:28<ToxicFrog>The Random monad is the source of the pain
02:01:01<ToxicFrog>If I use non-monadic mkStdGen it works fine, but it's also not usefully random.
02:01:21<LoganCapaldo>you could use newStdGen
02:01:33<LoganCapaldo>but then you're stuck in IO instead of Random
02:01:36<Pseudonym>IIRC, I just put everything in the IO monad.
02:01:43<Pseudonym>Or some transformer on top of IO.
02:01:51<ToxicFrog>If I use newStdGen, it works great until I try actually writing non-trivial code that uses it.
02:02:02<ToxicFrog>At which point the type-inference engine develops a hunger for human flesh.
02:02:19<Pseudonym>unsafeTypeChecker
02:02:23<chessguy>oh, that's what unsafeWoodenStake is for
02:02:42<Pseudonym>?type Braanes!
02:02:44<lambdabot>parse error (possibly incorrect indentation)
02:03:25<dibblego>why is there no instance for Maybe?
02:03:26<chessguy>braanes?
02:03:29<dibblego>of Arbitrary
02:03:35<ToxicFrog>I mean, ok, I have a function pmap :: Float -> (a -> b) -> [a] -> [b], which is a probabilistic version of map
02:03:41<mrd>oh no, the monad has tasted human blood!
02:04:02<ToxicFrog>I have a function mutate, called from main as ( do a <- mutate [0,0,0,0,0,0,0,0]; return a )
02:04:13<monochrom>I advocate infinite lists. I don't just mean use an infinite list of random numbers. Much much more than that. Your whole algorithm your whole program, is structured around infinite lists. The fact that random numbers are found in an infinite list is just a small corollary of that. It will be beauitful and stateless. It is also a total paradigm shift.
02:04:16<ToxicFrog>mutate li = pmap 0.5 (+1) li -- this works
02:04:34<FMota>:t take
02:04:36<lambdabot>forall a. Int -> [a] -> [a]
02:04:37<FMota>:t drop
02:04:39<lambdabot>forall a. Int -> [a] -> [a]
02:05:05<ToxicFrog>mutate li = if (head li) == 1 then li else pmap 0.5 (+1) li -- this causes a "cannot construct the infinite type a -> [a]" error
02:05:16<monochrom>IOW use infinite lists for everything else in your program. That's what I advocate.
02:05:27<ToxicFrog>Note that as long as random isn't involved, the above declaration of mutate works fine
02:06:27<chessguy>out of curiosity, what's the 0.5 there?
02:07:13<ToxicFrog>Probability of application to each list element.
02:07:27<shachaf>ToxicFrog: What is mutate's type supposed to be?
02:07:34<ToxicFrog>pmap prob func list is the same as map func list, except that func only has a prob chance of being applied.
02:07:56<ToxicFrog>...which I suppose means that the signature is actually Float -> (a -> a) -> [a] -> [a], but that's fine
02:08:03<shachaf>ToxicFrog: That looks like it should work, can you give more context?
02:08:09<chessguy>@type mutate li@(1:xs) = li; mutate li = ?pmap 0.5 (+1) li
02:08:11<lambdabot>parse error on input `='
02:08:29<ToxicFrog>Hang on, I'll pastebin it.
02:08:38<mauke>@type \li -> if head li == 1 then li else ?pmap 0.5 (+1) li
02:08:40<lambdabot>forall a t a1. (Num a, ?pmap::t -> (a1 -> a1) -> [a] -> [a], Fractional t, Num a1) => [a] -> [a]
02:08:45<monochrom>Gosh! ContT r m a ≅ Cont (m r) a. I never noticed it, but it's now staring at me.
02:08:49<LoganCapaldo> I was gonna say shouldn't the type be like Float -> (a -> b) -> [a] -> [Either a b]
02:09:44<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/3294
02:10:12<ToxicFrog>The first three functions are based on http://hpaste.org/3293 , kindly provided by dons
02:11:06<shachaf>ToxicFrog: pmap's type is the problem.
02:11:22<shachaf>ToxicFrog: What you have is pmap :: (Ord a1, MonadState [a1] t) => a1 -> (a -> a) -> [a] -> t [a]
02:11:35<shachaf>You aren't runState-ing it.
02:11:43<chessguy>ToxicFrog, type annotations are your friends
02:11:53<shachaf>ToxicFrog: And what chessguy said.
02:12:30<chessguy>stop fighting the type system
02:12:37<hpaste> omnId annotated "(no title)" with "typechecks." at http://hpaste.org/3294#a1
02:12:45<shachaf>@wiki New monads/MonadSupply
02:12:45<lambdabot>http://www.haskell.org/haskellwiki/New_monads/MonadSupply
02:12:50<shachaf>Maybe that's relevant?
02:12:50<omnId>diff: http://hpaste.org/3294/diff?old=0&new=1
02:13:54<shachaf>Yes, return li is better, of course.
02:14:03<shachaf>Since mutate is also in State.
02:14:20<chessguy>glguy!
02:14:26<omnId>pmap results in a State action, but mutate resulted in either a list, or a list in a State action, you have to return the first case into State.
02:14:43<glguy>\o/
02:15:11<chessguy>how's things in galois-land?
02:15:19<glguy>green
02:15:30<chessguy>umm
02:15:33<glguy>Why do you ask? looking for interviews? ;)
02:15:34<ToxicFrog>...it would probably help here if I understood (1) monads in general (2) State in specific
02:15:35<chessguy>i guess that's a good thing..
02:15:40<chessguy>.lol
02:15:47<chessguy>i wouldn't waste their time or mine :)
02:15:53<chessguy>not yet anyway. maybe someday
02:15:57<omnId>ToxicFrog: the thing to understand is that [a] /= State [Bool] [a]
02:16:05<glguy>well, at least you're considerate then!
02:16:24<omnId>s/Bool/Double/
02:16:32<chessguy>besides, i think my fiancee would kill me if i told her i was moving again :)
02:16:35<omnId>return puts your [a] into the State [Double] monad
02:17:28<omnId>in the expression: (if (head li) == 1 then li else pmap 0.5 (+1) li), the 'then' case, "li" has type [a], but the 'else' case "pmap 0.5 (+1) li" has type State [Double] [a]
02:17:32<omnId>they don't match
02:17:34<glguy>Yeah, I'm definitely not an Oregonian :)
02:17:36<ToxicFrog>Ok. And State [Double] [a] is a monad representing something with a persistent state of type [Double], and a return value from some state-specific computation of type [a]?
02:17:44<shachaf>ToxicFrog: Try reimplementing State yourself -- it's helpful in understanding it.
02:18:14<chessguy>ToxicFrog, no, State is a monad. State [Double] [a] is not
02:18:24<omnId>ToxicFrog: yep, though the word "monad" specifically refers the the unapplied type State [Double], the State [Double] [a] is called an action.
02:18:27<shachaf>chessguy: State [Double] is a monad.
02:18:30<chessguy>err, right
02:18:38<chessguy>ACTION goes back to feeling dumb
02:18:43<omnId>:)
02:18:55<LoganCapaldo>State is walking down the road towards being a monad :)
02:19:06<LoganCapaldo>it hasn't met it's body s yet :)
02:19:12<LoganCapaldo>s/body/buddy/
02:19:14<chessguy>a curried monad? :)
02:19:25<shachaf>Yum.
02:19:56<ToxicFrog>Aah. Ok.
02:20:18<ToxicFrog>So State [Double] [a] is an action that, when...executed? updates its internal [Double] and returns an [a]?
02:20:28<omnId>exactly!
02:20:55<chessguy>well, of course, it may or may not have an effect on its state
02:21:00<LoganCapaldo>(might update the [Double])
02:21:09<omnId>the do block hooks together the actions and they are executed when the top level does a runState and passes in the initial state value.
02:21:44<omnId>@src State (>>=)
02:21:45<lambdabot>Source not found. My pet ferret can type better than you!
02:21:58<mauke>@src State >>=
02:21:59<lambdabot>Source not found. Just what do you think you're doing Dave?
02:21:59<shachaf>ToxicFrog: State [Double] [a] is a function :: [Double] -> ([a],[Double]), wrapped up in a State type.
02:22:18<ToxicFrog>Ok.
02:22:29<omnId>m >>= k = State (\s -> let (a, s') = runState m in runState (k a) s')
02:22:32<shachaf>newtype State s a = State (s -> (a,s))
02:22:37<dons>?unmtl State [Double] [a]
02:22:38<lambdabot>[Double] -> ([a], [Double])
02:22:38<omnId>(I hope I didn't make any errors.
02:22:53<ToxicFrog>And pmap has this type? So when pmap is evaluated, it generates not an [a], but an action which must be executed to produce an [a]?
02:22:55<shachaf>runState (State x) = x
02:23:03<omnId>ToxicFrog: yes
02:23:04<shachaf>ToxicFrog: Yes.
02:23:06<shachaf>ToxicFrog: Just like IO.
02:23:21<ToxicFrog>I haven't used IO, I've never needed it.
02:23:22<shachaf>ToxicFrog: (Or any monad.)
02:23:27<ToxicFrog>But ok, this is starting to make sense.
02:23:42<shachaf>ToxicFrog: Your main is :: IO ().
02:23:42<LoganCapaldo>heh never needed IO. Impressive :)
02:23:51<ToxicFrog>Ok, never explicitly used IO.
02:23:56<ToxicFrog>Apart from that print.
02:23:57<omnId>ToxicFrog: though in actuality, the return type is even more general: MonadState [Double] m => m [a], meaning that the monad type itself can be State [Double], or something else that behaves the same.
02:23:58<Tela>ToxicFrog: You implicitly use IO in every program. Your main function is IO () and it's "executed" when the program runs.
02:24:07<shachaf>And newStdgen, and print.
02:24:25<ToxicFrog>So...could I, in theory, wrap pmap in a function that executes the action returned by pmap, and returns the result of that action?
02:24:38<shachaf>ToxicFrog: Yes.
02:24:53<shachaf>ToxicFrog: But that wouldn't have much point, possibly.
02:24:57<ToxicFrog>...why not
02:24:58<ToxicFrog>?
02:25:03<omnId>pmap' p f xs ds = runState (pmap p f xs) ds
02:25:06<Tela>ToxicFrog, but then realize that you'll have to give it a random seed in order to execute your state
02:25:06<shachaf>ToxicFrog: Since there's no point in returning the [Double] if you don't use that.
02:25:12<FMota>question: how can I se large integers in Haskell?
02:25:16<FMota>*I use
02:25:19<shachaf>FMota: Integer.
02:25:21<FMota>do I need some import?
02:25:25<mauke>just do it
02:25:26<mauke>no
02:25:26<ToxicFrog>shachaf: I would return the result, not the updated state
02:25:28<LoganCapaldo>> 348345884537573857387575843758347857385782378123787258578345 :: Integer
02:25:30<lambdabot> 348345884537573857387575843758347857385782378123787258578345
02:25:39<FMota>mk
02:25:43<mauke>ToxicFrog: if you drop the updated state, why use State at all?
02:25:45<chessguy>> maxBound :: Int
02:25:46<omnId>pmap' p f xs ds = evalState (pmap p f xs) ds -- evalState ignores the final state value
02:25:46<lambdabot> 2147483647
02:25:50<LoganCapaldo>> 348345884537573857387575843758347857385782378123787258578345588846 -- no type annotation necessary
02:25:51<lambdabot> 348345884537573857387575843758347857385782378123787258578345588846
02:25:54<ToxicFrog>mauke: I thought State updated it!
02:26:00<FMota>> succ (12123412312414324234 :: Integer)
02:26:01<shachaf>ToxicFrog: So there's no point in writing pmap in terms of State.
02:26:01<lambdabot> 12123412312414324235
02:26:08<mauke>ToxicFrog: yes, and when you use runState, it gives you the result
02:26:12<mauke>there is no magic here
02:26:13<ToxicFrog>...but...that doesn't make any sense, from what you said earlier...
02:26:16<shachaf>LoganCapaldo: That's just because of defaulting.
02:26:24<SamB>heh. now that's overkill - TeX uses units smaller than the wavelengths of visible light
02:26:27<LoganCapaldo>But that's the default default though right?
02:26:43<Pseudonym>SamB: But I want to use TeX for nanolithography!
02:26:45<omnId>ToxicFrog: I think he's saying that you *don't* want to drop the state value, since then it would be incorrect.
02:26:48<shachaf>ToxicFrog: It doesn't *really* update it.
02:26:49<chessguy>@quote magic
02:26:49<lambdabot>malig says: I have to admit I'm still stunned when "tying the knot" actually works. it's like I just performed the kind of magic that normally requires a lot more goat's blood
02:27:05<omnId>ToxicFrog: the State monads take care of the passing around for you.
02:27:12<SamB>Pseudonym: well, there's always magnification anyway
02:27:18<Pseudonym>I guess.
02:27:23<Pseudonym>ACTION grumbles... not the same...
02:27:44<LoganCapaldo>State is sort of like composing all your functions together instead of executing them and at the very end you run the giant function with some intial state
02:28:00<chessguy>@index modify
02:28:00<lambdabot>Control.Monad.State, Control.Monad.RWS
02:28:04<omnId>s/sort of like/like/
02:28:05<shachaf>LoganCapaldo: Again, just like IO.
02:28:33<chessguy>err, why isn't modify listed on http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State-Lazy.html ?
02:28:35<lambdabot>http://tinyurl.com/2dn8t6
02:28:37<LoganCapaldo>yeah but maybe if it gets said enough different ways one of them will click for ToxicFrog :)
02:29:00<omnId>@index modify
02:29:00<lambdabot>Control.Monad.State, Control.Monad.RWS
02:29:07<omnId>chessguy: 'twould seem not to be there
02:29:11<chessguy>hm, i actually rather like LoganCapaldo's way of saying it
02:29:32<shachaf>chessguy: Maybe it's in Control.Monad.State.Class?
02:29:32<chessguy>omnId, but it's not at http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State.html
02:29:34<chessguy>either
02:29:34<lambdabot>http://tinyurl.com/yx2t8w
02:29:38<shachaf>If such a thing exists?
02:29:45<ToxicFrog>...all I want is a probabilistic map function that I can call from pure code...
02:29:47<ToxicFrog>ACTION weeps
02:29:55<mauke>ToxicFrog: no such thing
02:29:55<chessguy>oh, there it is
02:29:57<chessguy>weird
02:30:11<omnId>chessguy: -Class?
02:30:15<mauke>rand() isn't pure
02:30:18<Tela>ToxicFrog: That's just the point. Code purity ensures that such a thing can't exist.
02:30:22<chessguy>ToxicFrog, random numbers are inherently impure
02:30:47<chessguy>omnId, it's at http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State-Class.html
02:30:48<lambdabot>http://tinyurl.com/37tgec
02:31:00<Pseudonym>I wonder if this would be better expressed as an Arrow.
02:31:13<Pseudonym>Which is close enough to a "function".
02:31:14<ToxicFrog>...so, wait.
02:31:17<Tela>ToxicFrog: the neat part is that once you /do/ refactor this problem into something that works with Haskell, you'll very clearly be able to see exactly what parts of your problem are pure.
02:31:32<mauke>reading existentials is hard. let's go shopping!
02:31:41<ToxicFrog>If I need random numbers at a low level, everything above that becomes impure?
02:31:52<chessguy>@remember mauke reading existentials is hard. let's go shopping!
02:31:52<lambdabot>Done.
02:32:04<mauke>depends
02:32:16<Tela>ToxicFrog: As long as your random parts don't preserve referential transparency
02:32:26<mauke>"random" numbers need state. you can do explicit state passing.
02:32:31<omnId>ToxicFrog: usually people do the impure stuff once on top and generate what they need, then they pass it all to pure code that works on pure values.
02:32:31<chessguy>couldn't ToxicFrog just get a random list of numbers in main and pass it into the rest of the program?
02:32:43<omnId>chessguy: yes
02:32:54<FMota>:t take
02:32:56<lambdabot>forall a. Int -> [a] -> [a]
02:32:58<omnId>chessguy: though State makes the passing part less tedious.
02:33:02<FMota>:/
02:33:02<ToxicFrog>I mean, I have an iteration function, which is defined in terms of a transition function, which is defined in terms of a mutation function, which is defined in terms of pmap, which needs random numbers.
02:33:14<FMota>is there a way to do take with Integers instead of with Ints ?
02:33:18<ToxicFrog>And it needs different random numbers each time, as otherwise the mutation function is not useful.
02:33:19<FMota>or do I have to make my own? :/
02:33:20<omnId>FMota: genericTake
02:33:21<sorear>:t genericTake
02:33:21<mauke>ToxicFrog: you'll have to pass some sort of state through all of that
02:33:23<lambdabot>forall i a. (Integral i) => i -> [a] -> [a]
02:33:25<FMota>ty
02:34:09<ToxicFrog>mauke: so, basically, I'm in function signature hell, as I have to pass and return the remainder of the list of random numbers through way too many layers of evaluation for comfort.
02:34:30<FMota>ugh
02:34:30<mauke>ToxicFrog: yes
02:34:35<Tela>You're thinking that just one part of your program requires inpurity, but really the entire algorithm you just described is impure. In some sense, the core of your program is impure, but you'll likely be able to extract a lot of pure pieces.
02:34:36<FMota>genericTake not in scope
02:34:36<mauke>or you could hide it behind State
02:34:57<mauke>you'll still have to tag your State-using functions with State
02:35:05<mauke>@index genericTake
02:35:06<lambdabot>Data.List
02:35:12<FMota>ty
02:35:23<omnId>ToxicFrog: if your algorithm needs a source of random numbers, they have to come from somewhere. You can think of most imperative languages as always recieving the state of the real world as an argument, so they can interact with it, then always returning an updated real world.
02:35:28<ToxicFrog>Tela: well, yes, in that only two operations in the entire program (breed and mutate) need randomness, but the entire program is defined in terms of those operations.
02:35:49<FMota>well, now the program doesn't stop, but at least it runs ;)
02:36:21<Tela>ToxicFrog Yeah, so your entire program needs to maintain state else it'll repeat itself.
02:36:22<ToxicFrog>mauke: see, that's what dons was trying to help me with earlier. However, while I now have a better understanding of what State is thanks to your-plural efforts, I don't fully grasp how to use it.
02:36:32<ToxicFrog>Nor how passing State around is better than passing [Double] around.
02:36:47<mauke>ToxicFrog: less typing
02:37:07<mauke>instead of a -> b -> c -> [Double] -> ([Double], z) you can write a -> b -> c -> State [Double] z
02:37:09<omnId>ToxicFrog: try passing the [Double]s around yourself and making sure you thread everything right first. It's tedious, but possible.
02:37:46<ToxicFrog>omnId: see, this is the point where, as mentioned earlier, I switch to an imperative language and come back to Haskell when I have a project that doesn't require state.
02:38:04<omnId>ToxicFrog: if your functions make State actions instead, then those actions can be hooked together with the standard bind that passes for you.
02:38:21<ToxicFrog>"the standard bind"?
02:38:35<omnId>Monad's (>>=), which is inserted with do notation.
02:38:48<dons>huh, andrew coppin really did unsubscribe from -cafe@
02:39:05<Pseudonym>I say we Cc him on everything.
02:39:12<dons>heh
02:39:21<omnId>> runState (get >>= \x -> return (x + 1)) 3
02:39:23<lambdabot> (4,3)
02:39:35<omnId>> runState (do x <- get ; return (x + 1)) 3
02:39:36<lambdabot> (4,3)
02:39:45<mauke>ToxicFrog: er. then what are you going to use Haskell for?
02:40:06<mauke>state is pretty common
02:40:23<chessguy>ToxicFrog, what are you breeding, anyway?
02:40:49<ToxicFrog>mauke: I don't know! Genetic algorithms and ant colony optimization both need an entropy pool. Something will present itself eventually. Perhaps.
02:40:53<omnId>> runState (State (\s -> (s,s)) >>= \x -> State (\s -> (x + 1, s))) 3
02:40:55<ToxicFrog>chessguy: solutions to a function.
02:40:55<lambdabot> (4,3)
02:41:15<FMota>wha, it's complaining about fractional integers now
02:41:26<omnId>FMota: fromIntegral might help
02:41:26<mauke>FMota: are you using / somewhere?
02:41:32<FMota>is there anyway to just do simple integer division?
02:41:35<iank>div
02:41:35<omnId>div
02:41:37<mauke>`div`
02:41:39<shachaf>> runState (State (\s -> (s + 1, s))) 3 -- As long as you're expanding it, there's no need to use get
02:41:40<FMota>oh, ok
02:41:40<lambdabot> (4,3)
02:41:40<Tac-Tics>> 5 `div` 2
02:41:41<FMota>ty
02:41:42<lambdabot> 2
02:41:59<omnId>shachaf: one step at a time :)
02:42:13<omnId>> (\s -> (s + 1, s)) 3
02:42:14<lambdabot> (4,3)
02:42:21<Pseudonym>BTW, is it a rite of passage for a community to get its first "I'm leaving in a huff"?
02:42:38<shachaf>> runState (State ((+1) &&& id)) 3
02:42:39<ToxicFrog>Ok. runState takes an action and an initial state? And the action can use get and put to manipulate said state?
02:42:39<lambdabot> (4,3)
02:42:48<omnId>yep
02:42:53<mauke>ToxicFrog: yes
02:42:54<omnId>@src State get
02:42:54<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
02:43:01<ToxicFrog>And returns a tuple containing the return value, followed by the state?
02:43:02<shachaf>ToxicFrog: Now try to reimplement State.
02:43:06<omnId>get = State (\s -> (s, s))
02:43:17<omnId>put x = State (\s -> ((), x))
02:43:19<mauke>> runState (do modify (+1); modify (*2); modify (+1); return "Thursday") 42
02:43:21<lambdabot> ("Thursday",87)
02:43:21<shachaf>newtype State s a = State (s -> (a,s)); runstate (State x) = x -- Start with that.
02:43:22<omnId>@type get
02:43:24<omnId>@type put
02:43:24<lambdabot>forall (m :: * -> *) s. (MonadState s m) => m s
02:43:26<lambdabot>forall s (m :: * -> *). (MonadState s m) => s -> m ()
02:44:11<omnId>runState (State f) x = f x -- if the eta reduced version is too hard to read.
02:44:45<omnId>the key is (>>=) which threads the state around rather smartly
02:45:04<chessguy>smartly?
02:45:10<dons>jerzy's got some interesting reminiscenes, re. Gofer: " At that time we knew that
02:45:11<ToxicFrog>...but f only returns an r, whereas runState returns (r,s)
02:45:13<dons>Haskell was for the brave, not for people making money... Almost everybody
02:45:15<dons>was a newbie"
02:45:31<omnId>ToxicFrog: "f"?
02:45:55<omnId>@type State -- the State constructor requires that it's argument function returns a pair.
02:45:57<lambdabot>forall s a. (s -> (a, s)) -> State s a
02:46:08<ToxicFrog>runState (State f) x = f x -- I read that as "runState (State f) x is equivalent to applying the function the State is wrapped around to x"
02:46:21<omnId>yes
02:46:23<ToxicFrog>But in that case you'd only get one return, rather than the (return,state) tuple
02:46:28<mauke>ToxicFrog: no, f returns (r,s)
02:46:30<omnId>and f :: s -> (a, s)
02:46:44<ToxicFrog>But f says it returns r!
02:46:53<ToxicFrog>It returns (r,s) only implicitly!
02:47:04<omnId>if it's wrapped in the State constructor, it must have type s -> (a, s)
02:47:20<mauke>f :: State r where State x = s -> (x, s)
02:47:57<ToxicFrog>(do x <- get ; return (x + 1)) -- this looks like it returns x+1, not (x+1,x), even though the latter is what actually falls out when you run it
02:47:59<omnId>@type State -- look at the constructor's type again
02:48:01<lambdabot>forall s a. (s -> (a, s)) -> State s a
02:48:33<omnId>ToxicFrog: maybe you're confused about the "return" function?
02:48:43<omnId>return x = State (\s -> (x, s))
02:48:52<ToxicFrog>...oh.
02:48:53<ToxicFrog>Oops.
02:48:56<ToxicFrog>Ok, now it makes sense.
02:49:31<omnId>you think you're ready for (>>=) now?
02:49:39<mauke>> runState (do return 1; return 2; return "butter"; return "Thursday") 42
02:49:40<ToxicFrog>Probably not!
02:49:40<lambdabot> ("Thursday",42)
02:50:19<omnId>action >>= k = State (\s -> let (result, new_s) = runState action s in runState (k result) new_s)
02:50:28<omnId>read through that slowly
02:51:36<omnId>it makes a new function that hooks together 'action' and 'k' and passes each value to the correct place.
02:51:41<JohnnyL>How can one write a compose function for a list of functions with varied arguments (in amount)?
02:51:57<mauke>@where oleg
02:51:58<lambdabot>http://okmij.org/ftp/
02:51:59<FMota>yay, euler #3 finally down... :o
02:52:15<dons>JohnnyL: well, hmm. how would you use this thing?
02:52:33<JohnnyL>dons, combing mathematical functions.
02:52:36<mauke>http://okmij.org/ftp/Haskell/types.html#polyvar-comp
02:52:37<lambdabot>Title: Haskell Programming: Types
02:52:53<dons>and (.) doesn't work?
02:53:00<dons>with appropirate lambdas/
02:53:12<FMota>> rev "abc"
02:53:13<lambdabot> Not in scope: `rev'
02:53:18<JohnnyL>i am new. it's a dynamtic list of functions.
02:53:18<FMota>> reverse "abc"
02:53:19<lambdabot> "cba"
02:53:24<ToxicFrog>augh, my brain
02:53:47<sclv>JohnnyL: maybe you could make up and operator that in imaginaryland did what you wanted, then write some pseudocode with the operator, so you could then show us what you wanted to do .
02:53:58<omnId>it hooks together: (action >>= \result_from_action -> new_action)
02:54:56<JohnnyL>sclv a list of sins and coses or printing sins and cos.
02:55:09<omnId>it gets the (result, new_s) pair by running action, then passes result to k to get a new_action.
02:55:44<omnId>new_s is passed to the new_action, and the whole thing results in new_action's return value.
02:56:08<ToxicFrog>So, hang on
02:56:31<sclv>JohnnyL so you want to have [Sin 12, Cos 22, Sin 17], for example, and then pass it to a function that either evals it or prints it?
02:56:31<ToxicFrog>Where does it get the old s from?
02:56:41<ToxicFrog>I mean, I see it's the argument to that lambda, but what's the lambda called with?
02:56:45<omnId>ToxicFrog: action >>= k = State (\s -> ...)
02:56:50<omnId>runState!
02:56:55<ToxicFrog>Ok.
02:57:05<omnId>(>>=) just hooks together actions into a bigger actions!
02:57:17<omnId>The whole thing is subsequently run with runState!
02:57:21<ToxicFrog>So if I did runState theAction theInitialState, then s in that scope is initialState?
02:57:22<JohnnyL>svlv, yeah but the list size is not definite.
02:57:25<omnId>excalmation point!
02:57:30<ToxicFrog>Er, theInitialState?
02:57:34<omnId>yes!!!
02:57:59<omnId>(though most actions are built up from raw lambdas and the State constructor)
02:58:10<sclv>JohnnyL, define, e.g., Data Expr = Sin Float | Cos Float and the rest follows...
02:58:13<omnId>(usually you use get, put, return, modify to do it for you)
02:58:47<omnId>s/are/aren't/
02:59:08<omnId>most actions *aren't* built up from raw lambdas the the constructor
02:59:19<omnId>ACTION types types quickly
02:59:25<ToxicFrog>Ok. And then, having done that, it takes the new state and return value it got from (action s), and stuffs that through k as runState (k retval) newstate?
02:59:37<omnId>yep
02:59:52<sclv>JohnnyL: like, then you can have eval :: Expr -> Float where eval x = case x of Sin a -> sin a; Sin b -> sin b; and then you can just map eval over yr. list
03:00:18<omnId>(>>=), effectively, is fancy function composition in the State monads.
03:00:23<ToxicFrog>So in effect, action >>= k (is an action that?) runs action, updates state based on that, and feeds the result and new state to k, and returns the result of k and the new new state?
03:00:36<omnId>yes, yes, yes!
03:00:44<dfranke_>is there any way to match case-insensitive patterns in Alex?
03:00:52<omnId>:D
03:01:11<Tela>Although, this is done lazily, so that computation wont actually occur until you demand it with run/eval/execState
03:01:19<ToxicFrog>Alright. And get and put are actions that manipulate the state, which is how the given implementation of more works?
03:01:44<ToxicFrog>Ie, it gets the state, yanks a bunch of stuff off the front, puts what's left back into the state, and returns the stuff it pulled off?
03:01:48<sclv>anyway, my silly question for the community is this: is there a standard function like succ but that "wraps around" on bounded values?
03:02:08<omnId>ToxicFrog: I can't stop saying yes!
03:02:45<omnId>(incidentally, more can also be written: more n = State (splitAt n), can you see why?)
03:02:59<monochrom>I can say no. Unfortunately that's for sclv's question. :)
03:03:08<ToxicFrog>ACTION examines that
03:03:54<omnId>State (\s -> let (result, new_s) = splitAt n s in (result, new_s)) -- maybe with more explicitness :)
03:04:28<omnId>splitAt just happens to return the correct type of pair :)
03:04:59<ToxicFrog>Aaah. So there's no magic going on there, it's a fortuitious interaction of signatures.
03:05:10<omnId>nicely said!
03:05:31<ToxicFrog>So the partial application of splitAt is turned into an action, which is given the state, and returns two lists that happen to be the correct values for the return value and the new state.
03:06:02<chessguy>ACTION hasn't been paying attention. what does splitAt have to do with State?
03:06:04<omnId>@vixen will you say "Yes" for me? My "yes" box is getting worn out.
03:06:05<lambdabot>i'll hafta plead the fifth on that one.
03:06:17<omnId>:)
03:06:48<Tac-Tics>:t splitAt 5
03:06:51<lambdabot>forall a. [a] -> ([a], [a])
03:06:56<Tac-Tics>:t State
03:06:58<lambdabot>forall s a. (s -> (a, s)) -> State s a
03:07:18<Tac-Tics>splitAt sounds very lending to State
03:07:29<omnId>as do many of the random functions
03:07:31<omnId>@type random
03:07:33<lambdabot>forall g a. (Random a, RandomGen g) => g -> (a, g)
03:07:39<Tac-Tics>:t \n -> State (splitAt n)
03:07:41<lambdabot>forall a. Int -> State [a] [a]
03:07:41<chessguy>well, assuming the state is a list, sure
03:07:59<Tac-Tics>a list is a nice kind of state
03:08:19<Tac-Tics>it allows you to pretend you're working with many states at once
03:09:03<omnId>ToxicFrog: so you see, in the end, the list is passed around everywhere, but you don't have to much about with it yourself.
03:09:16<omnId>muck*
03:09:25<ToxicFrog>Right.
03:10:26<omnId>also incidentally, the real definition of runState is as a record selector on the State type: newtype State s a = State { runState :: s -> (a, s) }
03:10:43<omnId>if you don't know much about record selectors, you can happily ignore this :)
03:11:02<FMota>> [1,2,3,4] !! 3
03:11:02<shachaf>You people are still going on about State?
03:11:03<lambdabot> 4
03:11:34<omnId>shachaf: there's learning happening!
03:11:48<shachaf>Learning is good.
03:12:47<omnId>ToxicFrog: things still falling in place? Anything you're fuzzy on?
03:13:13<omnId>You know the translation of do notation into (>>=), yes?
03:13:46<FMota>ACTION 's computer is taking ages to compute the 10001st prime number.
03:13:54<dons>i love these epic weekend learners.
03:14:01<shachaf>FMota: s/computer/algorithm/ ?
03:14:10<dons>ToxicFrog: its great you've stuck with it. you must be in a completely different place to earlier in the day?
03:14:12<FMota>eh
03:14:19<FMota>I'm using a sieve, as per usual
03:14:28<FMota>although I could optimize it.
03:14:30<ToxicFrog>dons: no, not as such. I know much more about State and >>= than I did, though.
03:14:34<FMota>s/could/should
03:14:35<mauke>FMota: dude, just use sockets and download the list
03:14:40<mauke>faster than computing it yourself
03:14:44<FMota>lol.
03:14:58<FMota>that's cheating :/
03:15:09<mauke>OPTIMIZED
03:15:22<sorear>FMota: my system can do it in 0.01s
03:15:53<sorear>although it segfaults in the process
03:16:02<FMota>ACTION is jealous :o
03:16:40<ToxicFrog>omnId: I don't, and I'm trying to look it up, but the index has defeated me
03:16:52<stoic_>heh, that's a projecteuler problem
03:17:17<FMota>yep
03:17:27<mauke>what's the problem id?
03:17:30<ToxicFrog>I'd guess, though, that it's something like a >>= b = do tmp <- a; b tmp;
03:17:36<omnId>do { pat <- expr ; ... } = expr >>= \pat -> do { ... }
03:17:37<FMota>promple # 7
03:17:39<ToxicFrog>Add more tmps as necessary.
03:17:48<ToxicFrog>Aah.
03:18:04<ToxicFrog>That's rather more elegant.
03:18:08<omnId>do { let decls ; ... } = let decls in do { ... }
03:18:32<mauke>FMota: my solution takes 10 seconds
03:18:39<omnId>do { stmt ; ... } = stmt >> do { ... }, which is equivalent to stmt >>= \_ -> do { ... }
03:18:50<omnId>do { stmt } = stmt
03:19:06<stoic_>haha, one of the J solutions to problem 7 in the forums is great: p: 10000 ...0.000953769 seconds
03:19:07<FMota>yay!
03:19:11<Cale>"reddit is currently in read only mode due to a database upgrade. we should be back in a few weeks."
03:19:12<FMota>I got it. Really fast.
03:19:15<FMota>... and it makes no sense~
03:19:32<omnId>Cale: *jawdrop*! *WEEKS?*
03:19:39<FMota>10002 is not a prime number! :/
03:19:39<Cale>I'm kidding :)
03:19:49<omnId>you bastard!
03:19:51<Cale>It's just that it's been a little more than a "few" hours now
03:20:10<FMota>yes Cale, thati s infuritain
03:20:14<FMota>*infuriating
03:20:22<FMota>which is why I'm doing project euler. :/
03:20:23<mauke>primes = 2 : sieve [3, 5 ..]; sieve (p : ns) = p : sieve (filter ((0 /=) . (`mod` p)) ns)
03:20:29<FMota>and failing miserably, I might add.
03:21:39<stoic_>> (nubBy(((>1).).gcd)[2..]) !! 10001
03:21:53<lambdabot>Terminated
03:22:42<ddarius>Take this a a good chance to leave reddit behind.
03:23:30<FMota>mauke: I hate and love you. :)
03:23:52<mauke>what
03:24:06<idnar>primes = 2 : filter isPrime [3, 5..] where isPrime n = all (not . (`divides` n)) (takeWhile (\p -> p * p <= n) primes)
03:24:34<mauke>pfft, you kids and your fancy algorithms
03:25:11<idnar>mauke: my initial implementation was something like yours, but it took too long to find all the primes below 1 million :P
03:25:38<idnar>I'm not sure if a Sieve of Eratosthenes or Atkins is faster than that, though
03:25:59<mauke>is that problem 10?
03:26:02<Tela>The type system is Haskell's parentheses. Hate, then hate, then hate, then divinity.
03:26:23<Tac-Tics>@let divisors n = [x | x <- [1..n], n `mod` x == 0]
03:26:23<FMota>heh, @remember-bait
03:26:28<lambdabot>Defined.
03:26:35<mauke>main = print $ sum $ takeWhile (< 1000000) primes
03:26:39<Tac-Tics>@let prime n = length (divisors n) == 2
03:26:40<lambdabot><local>:19:0: Multiple declarations of `L.prime' Declared at: <local>...
03:26:48<newsham>tela: then agda?
03:26:49<mauke>> prime 42
03:26:51<lambdabot> False
03:26:52<Tela>Not denying it. I like the parallel though. Reminds me way too much of macros
03:27:04<ToxicFrog>'agda'?
03:27:09<idnar>mauke: yeah
03:27:14<shachaf>@where agda
03:27:14<lambdabot>http://www.cs.chalmers.se/~catarina/agda/
03:27:15<newsham>agda has a more powerful type system than haskell
03:27:15<Tac-Tics>> filter prime [1..101]
03:27:17<lambdabot> [1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101]
03:27:28<mauke>> (filter prime [2 ..]) !! 1000
03:27:30<lambdabot> 7927
03:27:30<ToxicFrog>Aah.
03:27:33<mauke>> (filter prime [2 ..]) !! 10000
03:27:35<lambdabot> 104743
03:27:41<shachaf>> prime 1 -- !
03:27:43<lambdabot> True
03:27:45<mauke>wow, this is fast
03:27:49<ToxicFrog>Ok. So I now know how to implicitly pass state along. Now I need to pass it down.
03:28:00<shachaf>ToxicFrog: "down"?
03:28:09<shachaf>ToxicFrog: Did you reimplement State yet, by the way?
03:28:20<newsham>I think http://unit.aist.go.jp/cvs/Agda/ is a newer url than the chalmers one
03:28:21<lambdabot>Title: Agda Official Web Site
03:28:25<idnar>@src prime
03:28:25<lambdabot>Source not found. Are you on drugs?
03:28:44<shachaf>< Tac-Tics> @let prime n = length (divisors n) == 2
03:28:48<ToxicFrog>shachaf: no, I haven't. And by down, I mean I have an action that doesn't directly use the state, but is defined in terms of something else that does.
03:28:59<idnar>shachaf: but < lambdabot> <local>:19:0: Multiple declarations of `L.prime' Declared at: <local>...
03:29:00<shachaf>ToxicFrog: runState?
03:29:03<idnar>shachaf: I thought that meant the @let failed
03:29:08<ToxicFrog>Or rather, is defined in terms of something else which is defined in terms of something else which does.
03:29:13<stoic_>> 2 : (filter prime [3,5..]) !! 20000
03:29:14<lambdabot> Couldn't match expected type `[t]' against inferred type `Integer'
03:29:18<shachaf>Oh.
03:29:20<shachaf>Hmm.
03:29:34<mauke>> (2 : filter prime [3,5..]) !! 20000
03:29:36<lambdabot> 224743
03:30:14<idnar>> sum $ takeWhile (<1000000) (2: filter prime [3, 5...])
03:30:14<lambdabot> Parse error
03:30:25<idnar>> sum $ takeWhile (<1000000) (2 : filter prime [3, 5...])
03:30:25<lambdabot> Parse error
03:30:41<stoic_>extra dot?
03:30:46<idnar>oh, oops
03:30:47<idnar>> sum $ takeWhile (<1000000) (2 : filter prime [3, 5..])
03:30:52<lambdabot>Terminated
03:30:54<idnar>heh
03:31:20<mauke>@let primes = 2 : filter prime [3, 5 ..]
03:31:20<lambdabot><local>:19:0: Multiple declarations of `L.primes' Declared at: <local...
03:31:32<ToxicFrog>shachaf: that is to say, main calls a lambda action (is that the right term? it's a (do ...) block passed directly to runState), which calls mutate, which calls pmap, which calls more, which uses the state.
03:31:33<mauke>> takeWhile (<1000000) primes
03:31:35<lambdabot> [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,...
03:32:27<shachaf>ToxicFrog: It's a bit like IO.
03:32:29<idnar>> length $ takeWhile (<1000000) primes
03:32:33<lambdabot>Terminated
03:32:33<shachaf>ToxicFrog: Except you can run it.
03:32:46<shachaf>ToxicFrog: If something uses the state, it has to be in State.
03:32:59<stoic_>> last primes
03:33:00<Tac-Tics>@let foo n = head $ let primes = filter prime [2..] in do x <- primes; y <- primes; guard (x + y == n)
03:33:03<shachaf>ToxicFrog: Or have an initial state to runState with (which is equivalent).
03:33:09<lambdabot>Defined.
03:33:10<lambdabot>Terminated
03:33:19<Tac-Tics>@let foo2 n = head $ let primes = filter prime [2..] in do x <- primes; y <- primes; guard (x + y == n); return [x, y]
03:33:24<omnId>@. elite run last [1..]
03:33:25<lambdabot>Defined.
03:33:29<lambdabot>tER/\/\iNA73d
03:33:30<Tac-Tics>> foo2 12
03:33:34<lambdabot>Terminated
03:33:54<Tac-Tics>sadness
03:34:02<Tac-Tics>> foo2 4
03:34:04<lambdabot> [2,2]
03:34:23<mauke>> foo2 6
03:34:27<ToxicFrog>shachaf: I do have an initial state.
03:34:27<lambdabot>Terminated
03:34:32<mauke>huhu
03:34:35<Tac-Tics>so much for the naive approach
03:34:45<sclv>it never stops taking from the first primes to take from the 2nd
03:34:57<shachaf>ToxicFrog: So what's the point?
03:35:05<Tac-Tics>yeah
03:35:08<ToxicFrog>main = do { rs <- (...generate initial state...); evalState (do mutate ...);
03:35:13<Tac-Tics>it's looking for 2 + p = 6
03:35:15<Tac-Tics>and there is none
03:35:16<ToxicFrog>Er.
03:35:21<ToxicFrog>evalState (do mutate ...) rs
03:35:23<shachaf>ToxicFrog: You have a state, you call a function that isn't in State, and then you call a function that is in state from that?
03:35:35<shachaf>ToxicFrog: You might as well keep everything in State.
03:35:45<ToxicFrog>That's what I'm trying to do.
03:35:47<idnar>@let foo3 n = head $ let primes = filter prime [2..] in do x <- takeWhile (<n) primes; y <- takeWhile (<n) primes; guard (x + y == n); return [x, y]
03:35:54<lambdabot>Defined.
03:35:59<shachaf>ToxicFrog: Can you @paste, maybe?
03:36:05<mauke>> foo3 6
03:36:07<sclv>I wrote a way to take a useful cartesian product of infinite lists once. then i realized that cartesian products were overkill. hmm.. i might have the code somewhere
03:36:07<lambdabot> [3,3]
03:36:07<idnar>> foo3 6
03:36:08<lambdabot> [3,3]
03:36:14<idnar>> foo3 27
03:36:15<lambdabot> Exception: Prelude.head: empty list
03:36:20<Tac-Tics>@let bar n = head $ let primes = filter prime [2..] in do x <- primes; guard (x <= n); y <- primes; guard (x + y == n); return [x, y]
03:36:28<lambdabot>Defined.
03:36:28<Tac-Tics>> bar 6
03:36:32<lambdabot>Terminated
03:36:33<idnar>> foo3 20
03:36:34<lambdabot> [3,17]
03:36:52<sclv>or yep, that'll do.
03:37:18<mauke>> foo3 100
03:37:18<idnar>the guard isn't enough
03:37:20<lambdabot> [3,97]
03:37:24<mauke>Tac-Tics: guard is filter, not takeWhile
03:37:39<idnar>what he said ;)
03:37:48<ToxicFrog>Hmm. That worked.
03:37:51<ToxicFrog>mutate li = State (\n -> runState (do pmap 0.5 (+1) li) n)
03:38:10<mauke>State/runState? o_O
03:38:21<idnar>if anyone cares, my Project Euler solutions are at http://slipgate.za.net/~mithrandi/darcs/projecteuler/
03:38:23<lambdabot>Title: Index of /~mithrandi/darcs/projecteuler
03:38:25<Tac-Tics>> foo3 23456
03:38:27<lambdabot> [163,23293]
03:38:29<mauke>mutate li = pmap 0.5 (+1) li
03:38:31<shachaf>ToxicFrog: You shouldn't use State yourself.
03:38:44<stoic_>Tac-Tics: are you trying to do prime factors?
03:38:47<idnar>(in most cases I just tried to solve it as quickly as possible, rather than striving for elegant / optimal solutions)
03:38:49<Tac-Tics>no
03:38:54<idnar>(and, obviously, don't look there if you don't want any spoilers :P)
03:39:03<Tac-Tics>It's the goldbach conjecture, I think, right?
03:39:04<sclv>> let bar2 n = head $ let primes = filter prime [2..] in do x <- primes; y <- takeWhile (<x) primes; guard (x + y == n); return [x, y] in bar2 23456
03:39:06<lambdabot> [11779,11677]
03:39:08<omnId>mutate xs = pmap 0.5 (+1) xs
03:39:25<ToxicFrog>omnId: that works too.
03:39:29<ToxicFrog>However...oh, wait, I think I see
03:39:47<omnId>pmap results in your action, mutate just gives defaults to pmap
03:39:58<ToxicFrog>mutate li = if (head li) == 1 then return li else pmap 0.5 (+1) li
03:40:17<omnId>if the first == 1 then don't pmap?
03:40:20<stoic_>idnar: have you done problem 160?
03:40:21<idnar>Tac-Tics: for even n, yes
03:40:22<ToxicFrog>Yep.
03:40:31<omnId>that should work fine
03:40:36<idnar>stoic_: I've only done 1 through 20
03:40:44<kaol>why does "return Nothing >>= return >> return $ Just ()" fail but "return Nothing >>= return >> return (Just ())" doesn't?
03:40:44<ToxicFrog>Not what the final logic looks like (which calls a seperate function to determine whether to pmap or not) but that's the idea.
03:40:45<stoic_>oh :-(
03:40:50<luqui>I installed ghc from a binary tarball; how do I get the runhaskell program?
03:41:02<dons>should be in your path
03:41:02<ToxicFrog>The problem I kept running into earlier was that 'mutate li = if (head li) == 1 then li else pmap 0.5 (+1) li' wouldn't work.
03:41:08<omnId>since the else clause results in an action, the then clause must too, (via return)
03:41:13<sclv>> let primes = filter prime [2..]; bar2 n= head $ do{ x <- primes; y <- takeWhile (<x) primes; guard (x + y == n); return [x, y]} in bar2 23456
03:41:13<mauke>:t (>>= return)
03:41:13<lambdabot> [11779,11677]
03:41:13<lambdabot>forall (m :: * -> *) a. (Monad m) => m a -> m a
03:41:20<ToxicFrog>Because I didn't fully realize that 'pmap 0.5 (+1) li' returns an action, but
03:41:23<ToxicFrog>'li' returns a list.
03:41:34<luqui>kaol, operator precedence
03:41:38<dons>now you're learning to think in types, ToxicFrog :)
03:41:41<dons>be careful: its addicative
03:41:41<omnId>li is a list, but return li is a list in the State [Double] Monad.
03:41:43<kaol>thought it would be something like that
03:41:47<shachaf>ToxicFrog: Do keep in mind that that won't work for the empty list.
03:41:50<luqui>kaol, (return Nothing >>= return >> return) (Just ()) should work fine
03:41:51<dons>you'll be inferring types for everything soon enough
03:41:54<ToxicFrog>shachaf: yes, I know.
03:42:01<ToxicFrog>I'm still putting stuff together.
03:42:17<luqui>kaol, actually... uh, no it shouldn't
03:42:20<Tac-Tics>dons: it's like you don't even need documentation on a function any more... you just see the type and assume you know what it should do
03:42:21<omnId>it takes time, you'll get there :)
03:42:22<luqui>but that's what it means at least
03:42:36<ToxicFrog>dons: well, the issue was that I expected both of them to return lists.
03:42:42<FMota>yay.
03:42:52<omnId>Tac-Tics: /me did exactly that when I futzed around with template haskell :)
03:42:52<shachaf>ToxicFrog: Somebody else had the solution "mutate li@(1:xs) = ...; mutate li = li" or so.
03:42:54<FMota>I used pfactors and it got me the answer in ~10 seconds
03:43:04<omnId>Tac-Tics: which was good since I couldn't find any good docs :D
03:43:09<Tac-Tics>yeah
03:43:10<dons>Tac-Tics: exactly. given purity and an expressive type , the type does in fact tell you everything
03:43:14<dons>?djinn a -> a
03:43:14<lambdabot>f a = a
03:43:18<kaol>> return Nothing >>= return >> return (Just ())
03:43:19<lambdabot> add an instance declaration for (Show (m (Maybe ())))
03:43:27<Tac-Tics>type(f) = type(g) => f = g
03:43:29<dons>only one non-trivial function with that type: the type really is a good, machine checked spec
03:43:29<shachaf>@ty take
03:43:31<lambdabot>forall a. Int -> [a] -> [a]
03:43:32<shachaf>@ty drop
03:43:34<lambdabot>forall a. Int -> [a] -> [a]
03:43:51<ToxicFrog>shachaf: which is cool, but since the final logic will be something like 'if completed li then return get-best li else mutate (pmap 0.5 breed li)'
03:43:54<kaol>> return Nothing >>= return >> return (Just "")
03:43:55<lambdabot> add an instance declaration for (Show (m (Maybe [Char])))
03:44:22<omnId>ToxicFrog: and get-best doesn't rely on any incoming stream of randoms or anything?
03:44:27<ToxicFrog>Nope.
03:44:34<luqui>> return Nothing >>= return >>= return (Just "") -- is this what you meant?
03:44:36<lambdabot> Just ""
03:44:37<chessguy>ToxicFrog, you're searching for a fitness of 1?
03:44:45<ToxicFrog>chessguy: in effect.
03:44:48<shachaf>Hmm... @djinn is implementation inference. :-)
03:45:01<ToxicFrog>While I can't guarantee that's the range fitness is in, get-best just returns the element of the list with the highest fitness value.
03:45:09<luqui>> Nothing >>= return >>= Just "" -- or maybe this?
03:45:10<lambdabot> Couldn't match expected type `a -> Maybe b'
03:45:12<ToxicFrog>The fitness function itself is, of course, pure.
03:45:12<luqui>oops
03:45:16<luqui>> Nothing >>= return >> Just "" -- or maybe this?
03:45:16<FMota>pfactors = pf 2; pf x 1 = []; pf x n | x * x > n = [n]; pf x n | mod n x == 0 = x : pf x (div n x); pf x n = pf (succ x) n
03:45:17<lambdabot> Nothing
03:45:24<omnId>> return Nothing >>= return (Just "")
03:45:26<lambdabot> Just ""
03:45:44<omnId>(>>= return) = id
03:45:55<ToxicFrog>And completed li = fitness (get-best li) >= fitness-requirement
03:46:04<FMota>> let pfactors = pf 2; pf x 1 = []; pf x n | x * x > n = [n]; pf x n | mod n x == 0 = x : pf x (div n x); pf x n = pf (succ x) n in pfactors 1001
03:46:05<lambdabot> [7,11,13]
03:46:10<kaol>the example was a bit trivial, but that was the basic scenario I had
03:46:16<FMota>> product [7, 11, 13]
03:46:17<lambdabot> 1001
03:46:20<FMota>:)
03:46:23<stoic_>FMota: does projecteuler work? I'm getting a mysql error :(
03:46:29<FMota>heh
03:46:35<FMota>I must've broke it! :o
03:46:48<ToxicFrog>And now that I actually have some form of handle on this, I'm going to have dinner.
03:46:48<FMota>Maybe I divided by zero?
03:46:50<ToxicFrog>At midnight.
03:46:53<ToxicFrog>Thank you, all.
03:47:02<omnId>hehe, you're most welcome
03:47:18<Tac-Tics>ah
03:47:20<Tac-Tics>I found it
03:47:25<Tac-Tics>nub (mersennes >>= primeDivisors) == tail primes?
03:47:50<Tac-Tics>that's a neat question I came up with last year in my shitty math research class
03:48:12<omnId>Tac-Tics: maybe a sort there too?
03:48:32<Tac-Tics>it's hard to sort that kind of list
03:48:37<omnId>ACTION doesn't know what a mersenne prime is
03:48:50<Tac-Tics>mersenne n = 2 ^ (n+2) - 1
03:48:50<Tac-Tics>mersennes = map mersenne [1..]
03:48:50<omnId>(>>=) is in []?
03:48:51<shachaf>omnId: 2^n-1
03:48:57<Tac-Tics>they are not necessarily mersenne primes
03:49:00<jql>they're the cool primes
03:49:02<Tac-Tics>they are just mersenne numbers
03:49:14<Tac-Tics>in my question, that is
03:49:21<omnId>oh, duh, or they wouldn't have many primeDivisors :)
03:50:48<Tac-Tics>they'd have themselves as divisors
03:53:13<Tac-Tics>I can get about 23 primes and then sadness
03:55:56<FMota>:[] is still my favorite haskell expression :)
03:56:41<mauke>@quote fmap
03:56:41<lambdabot>mauke says: fmap fix return is the e^(i*pi)+1 of haskell
03:56:46<FMota>> product . map read . map (:[]) . take 5 $ "1234567"
03:56:57<lambdabot> 120
03:57:00<FMota>lol
03:57:04<FMota>that took awhile.
03:57:10<newsham>?type fmap fix return
03:57:12<lambdabot>forall a. a -> a
03:57:16<omnId>= id
03:57:30<omnId>fmap = (.), return = const
03:57:32<mauke>> product `liftM` liftM read `liftM` liftM return `liftM` take 5 $ "1234567"
03:57:34<lambdabot> 120
03:57:44<omnId>fix . const = \x -> fix (const x) = \x -> x
03:58:11<FMota>mauke... maybe you should be in jail?
03:58:15<FMota>:o ;p
03:58:33<FMota>@index ap
03:58:33<lambdabot>Control.Monad, Control.Monad.Reader, Control.Monad.Writer, Control.Monad.State, Control.Monad.RWS, Control.Monad.Identity, Control.Monad.Cont, Control.Monad.Error, Control.Monad.List, Data.Graph.
03:58:33<lambdabot>Inductive.Query.ArtPoint, Data.Graph.Inductive.Query, Data.Graph.Inductive
03:58:50<shachaf>ap = liftM2 id
03:58:53<shachaf>@src ap
03:58:53<lambdabot>ap = liftM2 id
03:59:02<ddarius>@remember mauke product `liftM` liftM read `liftM` liftM return `liftM` take 5 $ "1234567"
03:59:02<lambdabot>Done.
03:59:18<omnId>yuck
03:59:55<mauke>> liftM product (liftM (liftM (liftM read return)) (take 5)) $ "1234567"
03:59:57<lambdabot> 120
04:00:17<mauke>@unpl liftM product (liftM (liftM (liftM read return)) (take 5)) $ "1234567"
04:00:17<lambdabot>(liftM product (liftM (liftM (liftM read return)) (take 5)) "1234567")
04:00:26<mauke>hah
04:00:27<omnId>> let (.) = fmap in product . (read .) . (return .) . take 5 $ "1234567"
04:00:28<lambdabot> Occurs check: cannot construct the infinite type:
04:00:28<lambdabot> f = (->) (f Stri...
04:00:38<shachaf>> product `liftM` (read `liftM` return `liftM`) `liftM` take 5 $ "1234567"
04:00:39<lambdabot> 120
04:01:27<omnId>> let (.) = fmap ; (.)::Functor f=>(a->b)->f a->f b in product . (read .) . (return .) . take 5 $ "1234567" -- mmr?
04:01:29<lambdabot> 120
04:03:06<shachaf>> let (.) x = fmap x in product . (read .) . (return .) . take 5 $ "1234567" -- Simpler?
04:03:07<lambdabot> 120
04:03:40<shachaf>> let (.) x = fmap x in product . (read . return .) . take 5 $ "1234567"
04:03:42<lambdabot> 120
04:04:36<shachaf>@ty liftM(.)fmap
04:04:37<lambdabot>forall a a1 b (f :: * -> *). (Functor f) => (a1 -> b) -> (a -> f a1) -> a -> f b
04:04:49<shachaf>@ty (liftM(.)fmap<$>)
04:04:51<lambdabot>forall a a1 b (f :: * -> *) (f1 :: * -> *). (Functor f, Functor f1) => f1 (a1 -> b) -> f1 ((a -> f a1) -> a -> f b)
04:04:59<omnId>oh gawd
04:05:00<shachaf>@ty (liftM(.)fmap<$>map)
04:05:02<lambdabot>forall a (f :: * -> *) a1 b. (Functor f) => (a1 -> b) -> (a -> f [a1]) -> a -> f [b]
04:05:08<omnId>make it stop!
04:05:16<omnId>that's *five* names
04:05:41<omnId>@ty (liftA(liftM(.)fmap<$>map))
04:05:43<lambdabot>forall a (f :: * -> *) a1 b (f1 :: * -> *). (Functor f, Applicative f1) => f1 (a1 -> b) -> f1 ((a -> f [a1]) -> a -> f [b])
04:06:31<mauke>:t [fmap,liftA,liftM,(.)]
04:06:33<lambdabot>forall a b a1. [(a -> b) -> (a1 -> a) -> a1 -> b]
04:06:59<omnId>forgot (<$>)
04:07:10<mauke>:t [fmap,liftA,liftM,(.),(<$>)]
04:07:12<lambdabot>forall a b a1. [(a -> b) -> (a1 -> a) -> a1 -> b]
04:07:27<omnId>that's a lot of names for function compose.
04:07:36<shachaf>@ty liftA(liftM.fmap<$>map)
04:07:38<lambdabot>forall (m :: * -> *) (f :: * -> *) a b (f1 :: * -> *). (Monad m, Functor f, Applicative f1) => f1 (a -> b) -> f1 (m (f [a]) -> m (f [b]))
04:07:51<omnId>@src liftA
04:07:51<lambdabot>liftA f a = pure f <*> a
04:08:04<omnId>odd, you'd think liftA = fmap, since it does have the Functor context
04:08:17<shachaf>No.
04:08:18<omnId>@src liftA2 -- this, however, would need the <*>
04:08:18<lambdabot>Source not found. I've seen penguins that can type better than that.
04:08:19<shachaf>@ty liftA
04:08:21<lambdabot>forall a b (f :: * -> *). (Applicative f) => (a -> b) -> f a -> f b
04:08:26<omnId>liftA = fmap
04:08:35<ddarius>@src Applicative
04:08:36<lambdabot>class Functor f => Applicative f where
04:08:36<lambdabot> pure :: a -> f a
04:08:36<lambdabot> (<*>) :: f (a -> b) -> f a -> f b
04:08:59<shachaf>(<$>) is Applicative's rename of fmap.
04:09:01<omnId>@src liftA2
04:09:02<lambdabot>liftA2 f a b = f <$> a <*> b
04:09:08<omnId>liftA as well
04:09:46<shachaf>omnId: Yes, but that has an Applicative constraint.
04:09:57<omnId>shachaf: which implies Functor
04:10:00<shachaf>Maybe it's there to test Applicative laws.
04:10:31<omnId>Oh, I see what you mean.
04:10:51<omnId>liftA is a more specific (<$>)
04:10:57<shachaf>Yes.
04:11:37<newsham>is there a good ref on the Applicative module? seems the paper doesnt use the same notation/defs as the module.
04:11:52<omnId>could still define it liftA = fmap, since it has the more specific type
04:13:42<shachaf>@ty second(liftA liftM.fmap<$>map)
04:13:43<lambdabot>forall a1 (m :: * -> *) a b d. (Monad m) => (d, a -> b) -> (d, (a1 -> [a]) -> m a1 -> m [b])
04:13:50<shachaf>> fmap (+1) (2,3)
04:13:55<lambdabot> (2,4)
04:13:56<shachaf>> second (+1) (2,3)
04:13:57<lambdabot> (2,4)
04:13:58<shachaf>:-)
04:14:02<omnId>oh gawd
04:14:14<omnId>@slap shachaf
04:14:14<lambdabot>why on earth would I slap shachaf
04:14:40<omnId>(,) a Functor vs. (->) Arrow
04:14:41<pastorn-rr>@src randomR
04:14:41<lambdabot>Source not found. Sorry about this, I know it's a bit silly.
04:14:47<pastorn-rr>@src System.RandomrandomR
04:14:48<lambdabot>Source not found. My pet ferret can type better than you!
04:14:53<pastorn-rr>@src System.Random.randomR
04:14:53<lambdabot>Source not found. Are you on drugs?
04:15:07<omnId>@source System.Random
04:15:07<lambdabot>http://darcs.haskell.org/packages/base/System/Random.hs
04:15:17<omnId>404!
04:15:57<omnId>http://darcs.haskell.org/packages/random/System/Random.hs
04:15:58<Mr_Awesome>i think someones trying to tell you to give up ;)
04:16:16<pastorn-rr>omnId: thanks :D
04:16:25<Mr_Awesome>bah, you found it
04:16:35<omnId>ACTION does not quit so easily
04:16:55<omnId>seems a random package was split from base
04:16:57<Mr_Awesome>you and your optimism
04:17:23<omnId>ACTION attacks Mr_Awesome with a refreshing beam of happy.
04:17:43<Mr_Awesome>ACTION curls into the fetal position
04:17:49<omnId>not to be confused with Happy
04:18:16<shachaf>@ty \f a -> a >>> arr f -- Hmm...
04:18:18<lambdabot>forall (a :: * -> * -> *) b c d. (Arrow a) => (c -> d) -> a b c -> a b d
04:18:53<omnId>@type WrappedArrow
04:18:53<lambdabot>Not in scope: data constructor `WrappedArrow'
04:19:05<omnId>@type WrapArrow
04:19:06<lambdabot>forall (a :: * -> * -> *) b c. a b c -> WrappedArrow a b c
04:19:10<omnId>that'll give you a monad
04:19:21<Mr_Awesome>@src (->) (>>>)
04:19:21<lambdabot>f >>> g = g . f
04:19:26<Mr_Awesome>@src (->) loop
04:19:27<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
04:19:29<omnId>@src WrappedArrow (>>=)
04:19:29<lambdabot>Source not found. My mind is going. I can feel it.
04:19:34<Mr_Awesome>why not?!
04:19:46<Mr_Awesome>ACTION quits
04:19:49<shachaf>Oh, right, (>>>).
04:19:52<shachaf>ACTION feels silly.
04:20:05<shachaf>@ty second(liftA liftM.fmap<$>map>>>)
04:20:07<lambdabot>forall a1 (m :: * -> *) a b d d1. (Monad m) => (d1, ((a1 -> [a]) -> m a1 -> m [b]) -> d) -> (d1, (a -> b) -> d)
04:20:13<omnId>ACTION cries
04:20:28<omnId>so many names!
04:20:30<shachaf>@ty second(liftA>>>liftM.fmap<$>map)
04:20:32<lambdabot>forall a b (f :: * -> *) (m :: * -> *) (f1 :: * -> *) d. (Applicative f, Monad m, Functor f1) => (d, a -> b) -> (d, m (f1 [f a]) -> m (f1 [f b]))
04:21:14<omnId>(.), map, and second all are different specifications of the others
04:21:50<shachaf>omnId: True enough.
04:22:02<shachaf>omnId: But you *could* set them all to fmap.
04:22:43<shachaf>@ty Data.Traversable.fmapDefault
04:22:44<lambdabot>forall a b (t :: * -> *). (Data.Traversable.Traversable t) => (a -> b) -> t a -> t b
04:23:24<omnId>*sigh* this should be a sport or something, find as many names for fmap as you can!
04:24:15<nornagon>> zip [1..] $ fix (fmap:)
04:24:16<lambdabot> Add a type signature
04:24:26<shachaf>@ty let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map)
04:24:28<lambdabot>forall a (f :: * -> *) (m :: * -> *) a1 b d. (Data.Traversable.Traversable ((->) (a -> [a1])), Applicative f, Monad m) => (d, a1 -> b) -> (d, (a -> [a1]) -> m (f a) -> m (f [b]))
04:24:40<nornagon>O_o
04:25:14<omnId>ACTION wonders what would happen if you provide the correct arguments.
04:25:28<omnId>The world would end abruptly
04:26:31<shachaf>@ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap in second(fmapDefault(liftA>>>liftM).amap(fmap<$>map))
04:26:32<lambdabot>forall (a :: * -> * -> *) i (f :: * -> *) (m :: * -> *) (f1 :: * -> *) a1 b d. (Ix i, Data.Array.Base.IArray a (f1 [a1] -> f1 [b]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable (
04:26:33<lambdabot>a i), Applicative f, Monad m, Functor f1) => (d, a i (a1 -> b)) -> (d, a i (m (f (f1 [a1])) -> m (f (f1 [b]))))
04:26:35<omnId>> (let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map)) ((), id) ((), (:[])) [[()]] [[[()]]]
04:26:36<lambdabot> Couldn't match expected type `t1 -> t2 -> t3 -> t'
04:27:12<omnId>did the type get truncated?
04:27:20<shachaf>No.
04:27:26<shachaf>I don't think so, it got split.
04:27:32<FMota>problem #10 :/
04:28:01<omnId>erm, I guess I gave the wrong type
04:28:29<omnId>> (let fmapDefault = Data.Traversable.fmapDefault in second(fmapDefault(liftA>>>liftM).fmap<$>map)) ((), id) ((), (\_ _ -> [[()]]))
04:28:30<lambdabot> Couldn't match expected type `t1 -> t'
04:28:35<omnId>closer :)
04:29:12<omnId>ACTION attempts to end the world
04:29:27<FMota>hey, how do you force strict evaluation?
04:29:56<shachaf>@ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap; mapP = GHC.PArr.mapP in second`fmap`(fmapDefault(liftA>>>liftM).amap(mapP<$>map))
04:29:59<lambdabot>forall (a :: * -> * -> *) i d (f :: * -> *) (m :: * -> *) a1 b. (Ix i, Data.Array.Base.IArray a ([:[a1]:] -> [:[b]:]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable (a i), Arrow a,
04:29:59<lambdabot> Applicative f, Monad m) => a i (a1 -> b) -> a (d, i) (d, m (f [:[a1]:]) -> m (f [:[b]:]))
04:30:06<ddarius>omnId: Probably too late for you now, but this may help http://qntm.org/destroy
04:30:24<FMota>how do you force strict evaluation? :/
04:30:54<omnId>ddarius: "How to destroy the Earth"? I've read it, good read :)
04:31:28<shachaf>@ty let fmapDefault = Data.Traversable.fmapDefault; amap = Data.Array.IArray.amap; mapP = GHC.PArr.mapP in second`fmap`(fmapDefault(liftA>>>liftM).amap(mapP<$>map)) -- Any ideas from here on?
04:31:31<lambdabot>forall (a :: * -> * -> *) i d (f :: * -> *) (m :: * -> *) a1 b. (Ix i, Data.Array.Base.IArray a ([:[a1]:] -> [:[b]:]), Data.Array.Base.IArray a (a1 -> b), Data.Traversable.Traversable (a i), Arrow a,
04:31:31<lambdabot> Applicative f, Monad m) => a i (a1 -> b) -> a (d, i) (d, m (f [:[a1]:]) -> m (f [:[b]:]))
04:31:44<FMota>> !(1 + 1)
04:31:45<lambdabot> parse error on input `!'
04:31:50<FMota>> (1 + 1)!
04:31:50<lambdabot> parse error on input `}'
04:31:54<FMota>:/
04:32:07<shachaf>FMota: That's only for function arguments/data declarations.
04:32:07<omnId>> length [1..10^10] `seq` "blah!"
04:32:12<lambdabot>Terminated
04:32:13<shachaf>FMota: Try seq.
04:32:20<omnId>> length [1..10^4] `seq` "blah!"
04:32:21<lambdabot> "blah!"
04:32:24<shachaf>FMota: seq a b = force a, return b
04:32:32<shachaf>FMota: (Force only to WHNF.)
04:32:58<FMota>hm
04:33:09<FMota>how does one use seq?
04:33:09<omnId>> let x = 1 + 1 in x `seq` x * x
04:33:11<lambdabot> 4
04:33:20<omnId>@src ($!)
04:33:20<lambdabot>Source not found. Do you think like you type?
04:33:22<FMota>oh
04:33:23<FMota>I see
04:33:37<omnId>f $! x = x `seq` f x
04:34:03<FMota>that works for me :)
04:34:27<FMota>thank yous
04:34:31<omnId>remember, it only forces the outermost constructor, you'll have to depend on more if you want to eval more
04:34:51<omnId>(length xs `seq` ...) forces the spine of xs
04:35:27<FMota>so essentially it tells haskell what order to eval things.
04:35:37<omnId>which is somewhat evil
04:35:56<FMota>:o XD
04:36:22<ddarius>seq is evil. Or at least it is at it's type.
04:36:35<omnId>class Eval?
04:36:43<shachaf>ddarius: At its type?
04:36:45<FMota>class Evil !
04:36:49<geocalc>> sum [1..sum[1..8]]
04:36:49<shachaf>ddarius: What do you
04:36:51<lambdabot> 666
04:36:54<shachaf>mean?
04:36:58<FMota>lol
04:37:04<ddarius>shachaf: It should not be fully polymorphic.
04:37:18<shachaf>Oh.
04:37:22<ddarius>It should be in a class like in the good 'ole days.
04:38:07<luqui>how come?
04:39:54<ddarius>Because it complicates the equational properties of the language. It complicates parametricity.
04:40:23<luqui>hm
04:40:46<ddarius>@free seq
04:40:48<lambdabot>g . seq x = seq (f x) . g
04:41:00<luqui>@help free
04:41:00<lambdabot>free <ident>. Generate theorems for free
04:41:26<ddarius>This theorem is false.
04:41:44<luqui>oh I remember that paper. I read it when I was first learning haskell. I didn't understand it at all (maybe I should go back now)
04:42:06<Pseudonym>ddarius: seq is not realisable in Haskell.
04:42:58<FMota>hmm
04:43:13<FMota>it only took about 10 minutes to calculate the sum of 1 million primes.
04:43:23<luqui>that is quite a long time
04:43:27<Pseudonym>Yes, it is.
04:43:28<ddarius>Pseudonym: Indeed it is not.
04:43:28<kaol>was the result a prime?
04:43:31<Pseudonym>Which million was it?
04:43:37<FMota>I wonder if using seq speeded it up or slowed it down
04:43:40<Pseudonym>:type seq
04:43:45<Pseudonym>:t seq
04:43:47<lambdabot>forall a t. a -> t -> t
04:43:51<Pseudonym>?djinn a -> t -> t
04:43:51<ddarius>sped
04:43:51<lambdabot>f _ a = a
04:44:03<Pseudonym>That function satisfies the free theorem.
04:44:05<FMota>ONE MILLION DOLLARS *snickers, pinkie in mouth*
04:44:19<ddarius>Pseudonym: Indeed it does.
04:44:20<FMota>er, first million primes
04:44:41<shachaf>> let f !a b = b in f undefined 5
04:44:42<lambdabot> Parse error in pattern
04:45:28<kaol>> let f (!a) b = b in f undefined 5
04:45:28<lambdabot> Parse error in pattern
04:46:18<lament>one time, I counted to a billion.
04:47:19<shachaf>@set -XBangPatterns
04:47:19<lambdabot> Parse error
04:47:31<shachaf>Hmm, what does that get corrected to?
04:47:36<omnId>> 10^9 / 86400
04:47:37<shachaf>Oh, @let.
04:47:41<lambdabot> 11574.074074074075
04:47:51<omnId>> 11574 / 365
04:47:53<lambdabot> 31.70958904109589
04:48:02<omnId>if you counted once per second, it'd take 32 years
04:48:50<omnId>@google 1 billion seconds in years
04:48:53<lambdabot>http://en.wikipedia.org/wiki/1_E17_s
04:48:53<lambdabot>Title: 1 E17 s - Wikipedia, the free encyclopedia
04:49:07<omnId>@google 1000000000 seconds in years
04:49:08<lambdabot>1,000,000,000 seconds = 31.6887646 years
04:49:16<Pseudonym>?google pi seconds in nanocenturies
04:49:19<lambdabot>http://ircarchive.info/haskell/2007/2/28/4.html
04:49:19<lambdabot>Title: haskell heh Why get the processor to do it when there's a perfectly good bot in ...
04:49:28<Pseudonym>?google 3.14159 seconds in nanocenturies
04:49:29<lambdabot>No Result Found.
04:49:36<allbery_b>*snerk*
04:49:37<Pseudonym>?google pi seconds in centuries
04:49:38<omnId> ?frink
04:49:39<lambdabot>pi seconds = 9.95531902 x 10^-10 centuries
04:49:45<luqui>counting to a billion as long as you don't specify where to count from...
04:50:10<luqui>> [0,500000000,1000000000]
04:50:12<lambdabot> [0,500000000,1000000000]
04:50:14<luqui>> [0,500000000,..1000000000]
04:50:15<lambdabot> Parse error
04:50:16<shachaf>@go pi furlongs per fortnight in metric inches per century
04:50:17<luqui>> [0,500000000..1000000000]
04:50:18<lambdabot>http://en.wikipedia.org/wiki/List_of_unusual_units_of_measurement
04:50:18<lambdabot>Title: List of unusual units of measurement - Wikipedia, the free encyclopedia
04:50:18<lambdabot> [0,500000000,1000000000]
04:50:20<luqui>there
04:50:22<luqui>finally
04:51:52<omnId>"metric inches"?
04:52:09<shachaf>2.5 centimeters, I think.
04:52:30<omnId>hasn't the ordinary inch been redefined as 2.54 centimeters?
04:52:36<FMota>:t elem
04:52:38<lambdabot>forall a. (Eq a) => a -> [a] -> Bool
04:52:50<shachaf>omnId: Yes, I think so.
04:53:17<lament>inches are so cool
04:53:22<lament>i used to be against the imperial system
04:53:40<lament>but it's really cool that it's still around, it's a living relic of the past!
04:54:06<platypus>Like the appendix.
04:54:22<omnId>we should switch to planck units.
04:54:34<omnId>it's the most logical decision
04:54:42<shachaf>lament: And now you're against the imperative system?
04:54:59<lament>shachaf: badum-ts?
04:55:22<shachaf>lament: ?
04:55:26<FMota>wtf? I got a stack overflow!
04:55:27<FMota>wow.
04:55:53<shachaf>> foldr (+) 0 [1..10000000] -- Not hard
04:55:55<lambdabot> Exception: stack overflow
04:56:12<omnId>"I used to be against the imperial system" "And now you're against the imperial system?" There's been a misunderstanding here.
04:56:21<omnId>imperative!
04:56:30<omnId>ACTION misunderstood
04:56:41<lament>omnId: yes, just as you said :)
04:56:42<ddarius>FMota: You're doing something wrong
04:56:46<FMota>:/
04:57:02<FMota>either that or I'm using too much memory
04:57:18<FMota>but since haskell is lazy, that shouldn't be happening
04:57:23<shachaf>#vim (see? I'm not the only one!): < lumgwada> 5j
04:57:42<platypus>FMota: Do you have a space leak?
04:57:50<FMota>idk
04:57:53<shachaf>FMota: What are you doing that's causing it?
04:58:47<FMota>I'm counting the total number of letters in the english words for 1 to 1000 inclusive
04:58:51<FMota>problem # 17
04:59:33<FMota>oh
04:59:34<FMota>hm
04:59:39<FMota>:/
04:59:41<lament>that should neither run out of memory nor produce stack overflows.
04:59:43<FMota>humbug
05:00:24<FMota>word x | x < 100 = word (x - mod x 10) ++ "-" ++ word (mod x 10)
05:00:31<FMota>ACTION wonders if that is causing it.
05:00:40<FMota>and doubts it, somehow
05:01:05<shachaf>FMota: "NOTE: Do not count spaces or hyphens."
05:01:11<FMota>I know
05:01:17<shachaf>OK.
05:01:25<FMota>but I'm doing the masochistic way of filtering those out afterwards
05:02:42<ddarius>FMota: Actually, it's sadistic. You aren't doing the symbol munging.
05:03:01<FMota>but I am forcing myself to wait, so perhaps it's both
05:04:10<luqui>it doesn't seem like the curry-howard isomorphism works for (a -> a) -> a
05:04:34<shachaf>luqui: Y doesn't type-check.
05:04:43<shachaf>luqui: It has to be provided as primitive, somehow.
05:04:48<luqui>ahh
05:04:52<ddarius>luqui: Y isn't something you want in your logic.
05:04:55<ddarius>:t fix id
05:04:57<lambdabot>forall a. a
05:05:15<ddarius>There's a prood of falsity straight from the most basic axiom and Y.
05:05:23<FMota>you think maybe it was my british spelling of forty? :o
05:05:59<luqui>interesting. that has something to do with the fact that representation of Y is equivalent to undecidability....
05:06:01<luqui>?
05:06:05<luqui>well, more like !
05:06:43<FMota> /lol/
05:06:49<FMota>I found out what it was
05:06:59<ddarius>Recursive let?
05:07:01<FMota>I hadn't specified a "word 8"
05:07:38<FMota>obv, the number is wrong now
05:07:45<FMota>but at least it finishes
05:09:35<FMota>yay, got it right after 3 tries!
05:11:00<FMota>> let fact 0 = 1; fact n = fact $ n - 1 in fact 100
05:11:01<lambdabot> 1
05:11:04<FMota>:o
05:11:11<FMota>oops.
05:11:25<allbery_b>that's not going to work too well :)
05:11:28<ddarius>Count Down To Unity!
05:11:34<FMota>> let fact 0 = 1; fact n = n * (fact (n - 1)) in fact 100
05:11:36<lambdabot> 9332621544394415268169923885626670049071596826438162146859296389521759999322...
05:11:39<FMota>xd
05:13:00<luqui>> product [1..100] + 1
05:13:02<lambdabot> 9332621544394415268169923885626670049071596826438162146859296389521759999322...
05:13:09<luqui>My dad is richer than your dad!
05:13:34<shachaf>> fix (+1)
05:13:35<lambdabot> Exception: <<loop>>
05:13:50<shachaf><<loop>>? Clever of it.
05:13:58<FMota>yummy, I get to use map (:[]) again :)
05:14:20<omnId>@quote \:\[
05:14:20<lambdabot>psykotic says: (:[]) is the happy monkey operator
05:14:29<FMota>XD
05:14:32<luqui>:[]... never thought of that, I always used return
05:14:46<FMota>:[] is a lot nicer :)
05:15:02<omnId>@quote \:\[\{
05:15:03<lambdabot>SamB_XP says: I once saw it eat a comment (:[{- Help! -}])
05:15:12<shachaf>> fix (:[])
05:15:13<lambdabot> Occurs check: cannot construct the infinite type: a = [a]
05:15:13<lambdabot> Expected...
05:15:29<giles_bowkett>@google haskell regex
05:15:32<lambdabot>http://www.dcs.gla.ac.uk/~meurig/regexp/
05:15:32<lambdabot>Title: Regular Expressions in Haskell
05:16:01<dfranke_>I'm trying to write a case-insensitive version of the Parsec combinator 'string'. Here's what I have; is there any better way?
05:16:04<FMota>I love expressions like this:
05:16:05<dfranke_>ciString :: String -> CharParser st String
05:16:07<dfranke_>ciString s = foldr (\a b -> do { a' <- a; b' <- b; return (a' : b')}) (return "") [ oneOf [toLower c, toUpper c] | c <- s ]
05:16:15<FMota>sum . map read . map (:[]) . show $ num
05:16:48<omnId>(\a b -> ...) = (liftM2 (:))
05:16:55<ddarius>dfranke_: What the bloody hell?!
05:17:34<omnId>@src sequence
05:17:34<lambdabot>sequence ms = foldr k (return []) ms
05:17:34<lambdabot> where
05:17:34<lambdabot> k m m' = do { x <- m; xs <- m'; return (x:xs) }
05:17:38<luqui>ddarius, thank you, he was making me feel stupid
05:17:54<omnId>sequence [ ... ]
05:18:13<luqui>thinking to myself, "I hope that's not the best way, because i don't understand that at all..."
05:18:16<ddarius>mapM (\c -> satisfy ((toUpper c ==) . toUpper))
05:18:39<shachaf>ddarius: Not toLower?
05:19:14<luqui>:t satisfy
05:19:16<lambdabot>Not in scope: `satisfy'
05:19:17<dfranke_>ah, right. sequence.
05:19:19<luqui>oh it's a combinator
05:19:32<ddarius>Let's interpret ci as case-invariant, mapM (\c -> satisfy ((toUpper c ==) . toLower))
05:20:48<omnId>@src mapM
05:20:48<lambdabot>mapM f as = sequence (map f as)
05:21:11<omnId>turns a [Char] into a [Parser Char], then sequence into Parser [Char]
05:22:54<luqui>@hoogle Either (a -> b) (c -> d) -> Either a c -> Either b d
05:22:55<lambdabot>No matches, try a more general search
05:24:14<shachaf>luqui: How would you write that?
05:24:52<shachaf>luqui: What if you got an (a -> b) and a c?
05:25:45<luqui>oh right
05:26:04<omnId>@type either
05:26:06<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
05:26:28<luqui>I meant
05:26:31<omnId>@hoogle (a->c) -> (b->d) -> Either a b -> Either c d
05:26:31<lambdabot>No matches, try a more general search
05:26:42<luqui>yes, that omnId
05:27:07<mauke>:t \f g -> either (Left . f) (Right . g)
05:27:09<lambdabot>forall a b a1 b1. (a -> a1) -> (b1 -> b) -> Either a b1 -> Either a1 b
05:27:23<omnId>--@type \f g -> either (Left . f) (Righ... bah
05:27:47<shachaf>@djinn (a->c) -> (b->d) -> Either a b -> Either c d
05:27:47<lambdabot>f a b c =
05:27:47<lambdabot> case c of
05:27:47<lambdabot> Left d -> Left (a d)
05:27:47<lambdabot> Right e -> Right (b e)
05:28:02<omnId>@. pl djinn (a->c) -> (b->d) -> Either a b -> Either c d
05:28:02<lambdabot>(line 3, column 12):
05:28:02<lambdabot>unexpected ">" or "-"
05:28:02<lambdabot>expecting variable, "(", operator or end of input
05:28:04<shachaf>@. pl djinn (a->c) -> (b->d) -> Either a b -> Either c d
05:28:04<lambdabot>(line 3, column 12):
05:28:04<lambdabot>unexpected ">" or "-"
05:28:04<lambdabot>expecting variable, "(", operator or end of input
05:28:16<omnId>@pl \f g -> either (Left . f) (Right . g)
05:28:17<lambdabot>(. (Right .)) . either . (Left .)
05:28:25<luqui>I'll use that one
05:28:29<luqui>it seems to be the clearest ;-)
05:28:37<omnId>riiiiiiiiight
05:29:22<omnId>@type liftM2 either (Left .) (Right .)
05:29:24<lambdabot>forall a a1. (a -> a1) -> Either a a -> Either a1 a1
05:29:31<omnId>nope
05:30:27<FMota>:) I like TextMate. It makes Haskell easy
05:30:50<ddarius>Apparently not easy enough.
05:31:11<shachaf>I like vim. It makes Haskell fun. :-)
05:31:42<FMota>lol
05:31:57<FMota>*easier
05:44:53<Tac-Tics2>what does it mean for something to be "boxed" or "unboxed" in functional programming?
05:45:03<Tac-Tics2>I have a vague idea, but I can't find a good concrete definition
05:46:09<shachaf>?wiki Unboxed type
05:46:10<lambdabot>http://www.haskell.org/haskellwiki/Unboxed_type
05:46:32<Tac-Tics2>kind #?
05:47:44<Tac-Tics2>that's not very explanative of what the term means =-(
05:49:01<Tac-Tics2>it has something to do with strictness, doesn't it?
05:49:10<LeCamarade>Yeah. That wiki page needs some work, it appears.
05:50:20<lokimaf>what's the reverse of read that converts Int to String ?
05:50:33<Tac-Tics2>show
05:50:37<lokimaf>thanks
05:50:37<Tac-Tics2>> show 55
05:50:39<lambdabot> "55"
05:50:44<Tac-Tics2>> read $ show 55 :: Int
05:50:45<lambdabot> 55
05:59:44<FMota>ACTION likes certain points-free definitions
05:59:48<FMota>like this one:
05:59:54<FMota>circular - all prime . rots
06:00:02<FMota>* circular = all prime . rots
06:02:06<lekro>does anyone know the binary extended gcd algorithm by Knuth? I'm struggling with finding the right formula for computing the s, t such that s*a + t*b = gcd(a,b). And unfortunately I don't have a copy of TAOCP here.
06:02:37<sorear>don't need TAOCP
06:02:47<sorear>any book on number theory will suffice
06:03:21<lekro>it's the extended *binary* gcd algorithm
06:04:06<sorear>oh, I thought you meant dyadic
06:04:15<sorear>as opposed to N-adic
06:04:33<lekro>what is dyadic in this context?
06:05:27<lekro>I mean this algorithm: http://en.wikipedia.org/wiki/Binary_GCD_algorithm
06:05:27<lambdabot>Title: Binary GCD algorithm - Wikipedia, the free encyclopedia
06:06:33<lekro>just a hint in the right direction would be enough.
06:09:14<Pseudonym>lekro: Have you seen the slides for Stepanov's talk about this?
06:09:21<lekro>no.
06:09:43<Pseudonym>http://www.stepanovpapers.com/gcd.pdf
06:13:04<lekro>Pseudonym: as far as I can see it only describes the "basic" binary gcd algorithm and not the extended.
06:13:18<Pseudonym>Oh, right.
06:13:28<Pseudonym>It's still a fascinating read. :-)
06:14:11<lekro>sure, I saved it
06:17:08<lekro>it shouldn't be so complicated I guess. I just can't see the right way
06:17:40<Pseudonym>Which case can't you do?
06:17:56<lekro>I don't have an idea how to construct the s and t values
06:18:06<lekro>such that s*a + t*b = gcd(a, b)
06:18:23<lekro>all ideas I tried involved dividing by 2.
06:18:39<Pseudonym>You know how to do it using the Euclidean algorithm?
06:18:45<lekro>yes
06:19:25<lekro>I'm beginning to think that dividing by 2 may be necessary. Then the only problem is to make sure the integer that is divided by 2 is even.
06:19:30<Pseudonym>OK, let's work this out.
06:19:58<Pseudonym>gcd n 0 = n, s = 1, t = 0
06:20:11<Pseudonym>gcd 0 n = n, s = 0, t = 1
06:20:28<Pseudonym>gcd 2n 2m = 2 * gcd m n
06:20:43<Pseudonym>So if s*m + t*n = gcd m n
06:20:49<Pseudonym>Then 2*s*m + 2*t*n = 2*gcd m n
06:21:02<Pseudonym>Following so far?
06:21:02<lekro>this case doesn't affect s and t
06:21:13<Pseudonym>Sure it does. It multiplies them by 2.
06:21:23<lekro>but it multiplies gcd by 2 as well
06:21:29<Pseudonym>Right.
06:21:36<Pseudonym>Let's get more concrete.
06:21:52<Pseudonym>@let steinGcd n 0 = (n, 1, 0)
06:21:58<Pseudonym>@let steinGcd 0 n = (n, 0, 1)
06:22:00<lambdabot>Defined.
06:22:07<lambdabot>Defined.
06:22:43<Pseudonym>@let steinGcd (2*n) (2*m) = let (g,s,t) = gcd n m in (2*g,2*s,2*t)
06:22:43<lambdabot> Parse error in pattern
06:22:57<Pseudonym>Crap, this isn't gofer.
06:23:26<Pseudonym>@let steinGcd n m | even n && even m = let (g,s,t) = gcd (n`div`2) (m `div`2) in (2*g,2*s,2*t)
06:23:26<lambdabot><local>:25:77: Occurs check: cannot construct the infinite type: t = (t, ...
06:23:40<Pseudonym>@let steinGcd n m | even n && even m = let (g,s,t) = gcd (n `div` 2) (m `div` 2) in (2*g,2*s,2*t)
06:23:41<lambdabot><local>:25:80: Occurs check: cannot construct the infinite type: t = (t, ...
06:23:48<Pseudonym>@let steinGcd n m | even n && even m = let (g,s,t) = steinGcd (n `div` 2) (m `div` 2) in (2*g,2*s,2*t)
06:23:56<lambdabot>Defined.
06:23:58<Pseudonym>That's it.
06:24:03<Pseudonym>OK, those are the easy cases.
06:24:31<Pseudonym>Now. gcd 2n (2m+1) = gcd n (2m+1)
06:24:41<lekro>I don't get why s and t are multiplied by 2
06:24:52<Pseudonym>Suppose s*n + t*m = g
06:25:05<Pseudonym>That's what the recursive call gives you.
06:25:07<Pseudonym>Right?
06:25:15<lekro>gcd 2 2 calls gcd 1 1 which should give us something like (1, 1, 0).
06:25:20<Pseudonym>Right.
06:25:27<Pseudonym>Hang on, think abstractly.
06:25:29<lekro>gcd 2 2 should give us (2, 1, 0)
06:25:34<lekro>no change in s.
06:25:36<Pseudonym>The Stein algorithm gives:
06:25:45<Pseudonym>gcd (2n) (2m) = 2 gcd n m
06:25:47<Pseudonym>Right?
06:25:50<lekro>right
06:25:58<Pseudonym>Consider the recursive call.
06:26:17<Pseudonym>That should give us s and t such that s*n + t*m = gcd n m
06:26:19<lekro>this gives me s and t such that s*n + t*m = gcd n m
06:26:22<Pseudonym>Right.
06:26:28<Pseudonym>Oh, right.
06:26:31<Pseudonym>Yeah.
06:26:45<Pseudonym>We want s and t such that s*(2n) + t*(2m) = 2 gcd n m
06:26:51<Pseudonym>?forget
06:26:52<lambdabot>Incorrect arguments to quote
06:27:17<Pseudonym>?undefine
06:27:19<lambdabot>Undefined.
06:27:31<Pseudonym>@let steinGcd n 0 = (n, 1, 0)
06:27:32<lambdabot>Defined.
06:27:48<Pseudonym>@let steinGcd 0 n = (n, 0, 1)
06:27:50<lambdabot>Defined.
06:28:01<Pseudonym>@let steinGcd n m | even n && even m = let (g,s,t) = steinGcd (n `div` 2) (m `div` 2) in (2*g,s,t)
06:28:04<Pseudonym>That's right.
06:28:04<lambdabot>Defined.
06:28:18<Pseudonym>OK, do you follow that?
06:28:26<lekro>yes.
06:28:31<Pseudonym>Now.
06:28:42<Pseudonym>gcd 2n (2m+1) = gcd n (2m+1)
06:28:56<Pseudonym>Suppose you have s and t such that s*n + t*(2m+1) = gcd n (2m+1)
06:29:23<Pseudonym>Then you want s' and t' such that s'*(2n) + t'*(2m+1) = gcd 2n (2m+1)
06:29:45<lekro>and gcd 2n (2m+1) equals gcd n (2m+1)
06:29:51<Pseudonym>Right.
06:30:28<lekro>and this case is where I'm stuck.
06:31:00<lekro>of course I cannot say s' = s `div` 2 because s might be odd
06:32:05<Pseudonym>ACTION does some arithmetic on paper
06:32:09<lekro>either I'm missing something obvious or you need more information at that point.
06:32:22<Pseudonym>If s is even, you're okay.
06:33:26<Pseudonym>If s is odd, then s = 2p+1 for some p.
06:34:00<Pseudonym>ACTION thinks
06:34:10<Pseudonym>You should be able to transfer the extra n over to t'.
06:37:32<FMota>Programming in Haskell is a transformational experience. Who said Haskell was side-effect free?
06:40:20<Pseudonym>Nope, sorry.
06:40:30<Pseudonym>There's some obvious trick here that I'm not getting.
06:40:36<Pseudonym>I _suspect_ you have to deal with mod 4.
06:45:20<lekro>thanks anyway, I'll try to do something with mod 4
06:46:53<lekro>n is a multiple of gcd n (2m+1)
06:47:33<lekro>no, doesn't really help
06:47:59<earthy>FMota: nobody. Haskell *does* make explicit what the side-effects can be and where they can occur though.
06:48:49<FMota>really? then what is the type of haskell?
06:49:03<FMota>Haskell :: Programmer -> Better Programmer ?
06:49:37<FMota>heh, Haskell is the constructor for the Better monad.
06:50:34<FMota>if only "Better" were a monad... the world would be a Better place...
06:51:00<nornagon>someone built a better type system, so haskell built a Better monad.
06:51:06<FMota>lol
06:51:26<Pseudonym>You could make the RealWorld a better place with BetterT IO.
06:52:08<nornagon>heh
06:52:55<nornagon>a >>= b = (Better a) b
06:54:04<FMota>(>>=) :: Better a -> (a -> Better b) -> Better b -- a suddenly becomes altruistic and lets b do his thing
06:54:51<FMota>hmm, I'm equating selfishness with Betterness... probably a cue that I should go to sleep.
06:58:00<swix>I'm trying to convert (sqrt n) for use in [1..x]
06:58:06<swix>I get all sorts of ambigous type issues
06:58:30<Pseudonym>Sorry, could you explain what you're trying to do?
06:58:34<FMota>implement your own sqrt
06:58:35<FMota>;)
06:59:16<swix>I want [1..(sqrt n)]
06:59:19<swix>but that's a float
06:59:26<swix>so I want [1..(truncate (sqrt n))]
06:59:36<Pseudonym>Right.
06:59:38<swix>but I get all sorts of RealFrac, Floating not defined...
06:59:53<Pseudonym>[1 .. truncate (sqrt (fromIntegral n))]
06:59:59<FMota>you know what haskell needs? subtyping.
07:00:06<Pseudonym>However...
07:00:13<Pseudonym>isqrt :: Integer -> Integer
07:00:21<Pseudonym>isqrt = truncate . sqrt . fromIntegral
07:00:24<Pseudonym>Now:
07:00:26<Pseudonym>[1..isqrt n]
07:00:33<FMota>> isqrt 4
07:00:35<lambdabot> Not in scope: `isqrt'
07:00:47<Pseudonym>@let isqrt = truncate . sqrt . fromIntegral
07:00:50<lambdabot>Defined.
07:00:52<Pseudonym>> isqrt 4
07:00:54<lambdabot> 2
07:00:54<FMota>> let isqrt = truncate . sqrt . fromIntegral in 4
07:00:55<lambdabot> 4
07:00:57<Pseudonym>> isqrt 9
07:00:58<FMota>lol
07:00:58<lambdabot> 3
07:01:01<Pseudonym>> isqrt 10
07:01:03<lambdabot> 3
07:01:05<FMota>I always mess things up
07:01:06<Pseudonym>However.
07:01:18<FMota>> isqrt 8
07:01:19<lambdabot> 2
07:01:24<Pseudonym>This will fail if your integers can't be represented exactly in Doubles.
07:01:40<Pseudonym>However, in that case, you probably won't be doing [1..isqrt n].
07:06:41<heanol>join Reddit
07:06:43<heanol>oops
07:08:18<FMota>:index find
07:08:26<FMota>@index find
07:08:26<lambdabot>Data.List
07:08:33<FMota>@index fromJust
07:08:33<lambdabot>Data.Maybe
07:08:52<FMota>:t find
07:08:54<lambdabot>forall a. (a -> Bool) -> [a] -> Maybe a
07:10:36<dfranke_>what's the syntax for a unicode escape?
07:11:24<FMota>sq x = x * x
07:11:41<FMota>isqrt n = pred . fromJust . find (flip (>) n . sq) $ [1..]
07:12:59<FMota>that should work for just about any integer.
07:13:47<lokimaf>Haskell is for uber cool people
07:14:26<allbery_b>dfranke_: '\n' where n is a decimal (*not* octal!) integer
07:14:28<FMota>that's pretty much true of everyone in #haskell. (me excluded, ofc)
07:14:42<lokimaf>I made a Haskell tutorial: http://lokamaf.blogspot.com/2007/10/lokis-tutorial.html
07:14:43<lambdabot>Title: la.ma'aselyTCAna. pela.lokimaf.: Loki's हस&#2381;क&#2375;ल&#2381;ल Tut ...
07:14:44<allbery_b>cool? me?> as if.
07:15:20<lokimaf>tell me what you think at a skim
07:15:23<Pseudonym>When cool people start using Haskell, that's when I jump ship.
07:15:28<FMota>instance HaskellProgrammer p => Cool a
07:15:31<FMota>*Cool p
07:15:37<Pseudonym>ACTION is hipster hacker
07:15:45<allbery_b>ACTION too old to be cool
07:15:55<lokimaf>ACTION has girls chase him around begging to have sex with him
07:15:59<allbery_b>(or awake, given that it's 3am local, but...)
07:17:09<lokimaf>this one girl got to my room took off her clothes and begged me to fuck her, i don't bring random girls to my house anymore...
07:17:18<lokimaf>hmmm maybe should tone down
07:17:21<lokimaf>oh well
07:17:36<lokimaf>anyways, i like Haskell :D
07:17:37<Pseudonym>Yes, you should.
07:17:38<Pseudonym>haskell-blah
07:17:49<Pseudonym>That's what it's for.
07:18:13<lokimaf>yep, i usually just talk functions
07:18:35<FMota>lokimaf, I understand your plight, and you have my sympathy. Next time wear a rainbow shirt -- you'll still have girls flocking around you, but at least they won't get nekid.
07:18:46<FMota>[/blah]
07:19:56<lokimaf>hmm well i have an understanding that it's actually the tarot cards, but that's just like haskell random number generator with some additions
07:20:05<FMota>#haskell :: HaskellProgramm p => Channel p
07:20:10<FMota>*HaskellProgrammer
07:21:02<FMota>#haskell = filter (not . blah) programmers
07:21:10<FMota>w/e
07:21:13<lokimaf>agoode has an ipv6 address that's pretty cool
07:21:21<FMota>it's late, and I'm rambling.
07:21:48<lokimaf>tzal gyd
07:21:56<FMota>but I can't get off because Metric is on. oh well...
07:22:06<swix>how do you get a list less the first 1000 elements?
07:22:24<FMota>you mean without the first 1000 elements?
07:22:28<swix>yes
07:22:29<FMota>drop 1000 list
07:22:32<swix>cool
07:22:35<FMota>np :)
07:22:54<lokimaf>:D
07:23:43<lokimaf>kk well i'll go back to working on my speakable haskell derivative LOGJbang
07:24:25<nornagon>that doesn't look very speakable to me
07:24:28<FMota>:o
07:24:45<nornagon>how do you even pronounce that?!
07:25:30<FMota>Haskell isn't very good for speaking with. Ambiguity is actually quite a nice feature of natural languages.
07:25:54<FMota>and Haskell has very little ambiguity.
07:26:05<nornagon>lojban is not a natural language
07:26:21<nornagon>it's a conlang designed to be unambiguous
07:26:25<FMota>plus, anything without dependent types is not suited for speaking in
07:26:48<FMota>nornagon: right. still, my point stands.
07:27:14<nornagon>ACTION tips it over
07:27:38<FMota>how? points are 0-dimensional objects. They can't be tipped!
07:28:59<nornagon>FMota: they can if you lift them into the 3-dimension monad
07:29:54<FMota>that's bogus
07:30:07<FMota>how can you tip something without length, width, or height?
07:30:23<FMota>Or even duration, for that matter.
07:30:57<nornagon>well, if you have a point in 2-space, then you sweep it through a curve, you have a curve, which is a 2-object
07:31:08<nornagon>then sweep the 2-object to obtain a 3-object
07:31:11<nornagon>then tip it over
07:32:02<FMota>fair enough
07:32:13<FMota>but then it's no longer a point! :o
07:32:55<nornagon>that's because it's been lifted into 3-space :)
07:33:05<FMota>indeed
07:35:07<geocalc>nornagon=<< can you paste an exemple
07:35:18<nornagon>uh, what?
07:35:45<geocalc>3-space point
07:36:37<nornagon>perhaps you missed the irony, i wasn't really being serious :P
07:36:44<FMota>sweepTo3 trajectory2 . sweepTo2 trajectory1 $ point
07:39:57<geocalc>> let evil = sum [1..sum[1..8]]
07:39:57<lambdabot> Parse error
07:41:23<geocalc>@let evil = sum [1..sum[1..8]]
07:41:26<lambdabot>Defined.
07:41:45<geocalc>> evil
07:41:46<lambdabot> 666
07:41:50<LeCamarade>:-o
07:41:54<LeCamarade>ACTION runs away
07:42:06<LeCamarade>+
07:42:09<LeCamarade>+
07:42:12<mauke>> sqrt 666
07:42:13<LeCamarade>+
07:42:14<LeCamarade>+
07:42:14<LeCamarade>+
07:42:14<lambdabot> 25.80697580112788
07:42:19<LeCamarade>+
07:42:28<ibid> /away
07:42:32<ibid>gah
07:42:41<Pseudonym>> sqrt evil == money
07:42:42<lambdabot> Not in scope: `money'
07:42:44<ibid>ACTION is un-away, though :)
07:42:58<sclv>I'm writing a webapp framework in squiggol, but the IO support is awful.
07:43:04<Pseudonym>> isqrt evil
07:43:06<lambdabot> 25
07:43:23<FMota>lol
07:43:35<FMota>> 5^2
07:43:36<lambdabot> 25
07:43:39<Pseudonym>@let money = 25
07:43:41<FMota>> 5^2^2
07:43:41<lambdabot>Defined.
07:43:43<lambdabot> 625
07:43:44<Pseudonym>Now it's true.
07:43:50<Pseudonym>> money == isqrt evil
07:43:51<lambdabot> True
07:43:52<FMota>5^2^2 + 5^2
07:43:57<LeCamarade>:o)
07:44:00<FMota>> 5^2^2 + 5^2
07:44:01<lambdabot> 650
07:44:09<FMota>> 5^2^2 + 5^2 + 5 + 11
07:44:11<lambdabot> 666
07:44:19<ibid>> money^2 == evil
07:44:21<lambdabot> False
07:44:21<Pseudonym>> 562^2 + 5^2 + 2^4
07:44:23<lambdabot> 315885
07:44:26<Pseudonym>> 5^2^2 + 5^2 + 2^4
07:44:28<lambdabot> 666
07:44:33<FMota>well... it's not elegant, but it works.
07:44:49<mauke>> sqrt (2 * 666)
07:44:50<lambdabot> 36.49657518178932
07:44:51<LeCamarade>(money == isqrt 666) && (money == isqrt evil)
07:45:18<LeCamarade>@let rootOfAll = isqrt
07:45:21<lambdabot>Defined.
07:45:25<FMota>> sum[1..sum[1..8]]
07:45:26<lambdabot> 666
07:45:40<LeCamarade>> money == rootOfAll evil
07:45:42<lambdabot> True
07:45:46<LeCamarade>Be frank lambdabot
07:45:47<FMota>lol
07:45:50<LeCamarade>:-o
07:45:51<LeCamarade>+
07:45:52<LeCamarade>+
07:45:53<LeCamarade>+
07:45:54<LeCamarade>+
07:45:59<ibid>that's wrong, btw :)
07:46:11<osfameron>what's with the +s ?
07:46:16<LeCamarade>Cross.
07:46:22<ibid>@let premature x = x ^ 2
07:46:25<lambdabot>Defined.
07:46:29<ibid>@let optimization = 5
07:46:32<lambdabot>Defined.
07:46:42<ibid>> permature optimization == rootOfAll evil
07:46:43<lambdabot> Not in scope: `permature'
07:46:50<ibid>> premature optimization == rootOfAll evil
07:46:51<Pseudonym>Gotta go. Night.
07:46:51<lambdabot> True
07:47:12<FMota>:p
07:47:27<LeCamarade>@let root = (\_ _ _ -> isqrt) -- Monomorphism rest., you there?
07:47:29<sclv>:t Money
07:47:30<lambdabot>Defined.
07:47:31<lambdabot>Not in scope: data constructor `Money'
07:47:43<sclv>(fromIntegral Money) ** 2.0197391959991466
07:48:00<sclv>> (fromIntegral Money) ** 2.0197391959991466
07:48:01<lambdabot> Not in scope: data constructor `Money'
07:48:03<FMota>@let local x = sum [1..x]
07:48:06<LeCamarade>@let root = (\_ _ -> isqrt) -- Monomorphism rest., you there?
07:48:06<lambdabot>Defined.
07:48:07<lambdabot><local>:12:0: Multiple declarations of `L.root' Declared at: <local>:...
07:48:14<sclv>> (fromIntegral money) ** 2.0197391959991466
07:48:16<lambdabot> 666.0000000000003
07:48:23<LeCamarade>money == (root "of" "all") evil
07:48:30<FMota>@let variables = local 8
07:48:30<lambdabot><local>:12:12: Ambiguous occurrence `local' It could refer to either ...
07:48:37<FMota>:/
07:48:40<LeCamarade>> money == (root "of" "all") evil
07:48:40<FMota>darn
07:48:41<lambdabot> Couldn't match expected type `Integer'
07:48:58<LeCamarade>:o(
07:49:03<LeCamarade>Get back to work, you!
07:49:04<FMota>@let local_ x = sum [1..x]
07:49:07<lambdabot>Defined.
07:49:13<FMota>@let variables = local_ 8
07:49:17<lambdabot>Defined.
07:49:19<ibid>ACTION is compiling a kernel module
07:49:24<FMota>> local_ variables == evil
07:49:25<lambdabot> True
07:50:41<LeCamarade>Reddit won't get out or RO mode!
07:53:37<mauke>> iterate (sum . enumFromTo 1) 8
07:53:42<lambdabot>Terminated
07:55:55<mauke>> join (.) (sum . enumFromTo 1) 8
07:55:57<lambdabot> 666
07:56:12<geocalc>fear haskell
07:56:14<osfameron>the return value of the beast!
07:59:47<nornagon>join is like concat in that case, yes?
08:00:12<geocalc>@loosers
08:00:12<lambdabot>Unknown command, try @list
08:00:18<nornagon>@losers
08:00:18<lambdabot>Maximum users seen in #haskell: 420, currently: 362 (86.2%), active: 14 (3.9%)
08:00:30<nornagon>(learn to spell!)
08:01:04<TSC>@src join
08:01:04<lambdabot>join x = x >>= id
08:01:16<nornagon>ah.
08:01:45<nornagon>:t join (.)
08:01:47<mauke>in the list monad, >>= id is concatMap id, so concat == join
08:01:47<lambdabot>forall b. (b -> b) -> b -> b
08:02:52<pastorn-rr>@src join
08:02:52<lambdabot>join x = x >>= id
08:03:00<mauke>> join (.) sqrt 2
08:03:06<lambdabot> 1.189207115002721
08:03:20<nornagon>> sqrt 2
08:03:21<lambdabot> 1.4142135623730951
08:03:25<osfameron>huh?
08:03:27<nornagon>??
08:03:44<mauke>> (.) sqrt sqrt 2
08:03:46<lambdabot> 1.189207115002721
08:04:03<nornagon>oh ah
08:04:21<mauke>> join (^) 3
08:04:21<osfameron>but why twice?
08:04:23<lambdabot> 27
08:04:27<nornagon>so join (.) a is like a . a
08:04:40<mauke>join f x = f x x
08:05:04<nornagon>i still don't understand that :)
08:05:12<nornagon>how does that come from (>>= id) ?
08:05:38<mauke>@src (->) >>=
08:05:39<lambdabot>Source not found. Maybe if you used more than just two fingers...
08:05:42<byorgey>@src (->) (>>=)
08:05:43<lambdabot>f >>= k = \ r -> k (f r) r
08:06:07<mauke>see the duplicated r?
08:06:12<nornagon>zany
08:07:35<byorgey>it's the environment, aka "reader" monad, (r ->)
08:08:11<byorgey>@type join
08:08:13<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
08:08:35<mauke>(r -> (r -> a)) -> (r -> a)
08:08:43<mauke>@djinn (r -> (r -> a)) -> (r -> a)
08:08:43<lambdabot>f a b = a b b
08:09:34<byorgey>that is, the "environment" b gets passed in to both arguments of a two-arguement function, thus making a one-argument function.
08:10:11<greentea>Hi all. i can't seem to work out how to create a new type at the GHCi prompt, e.g. i'd like to be able to create MyBool = False | True. Can someone point me in the right direction, please?
08:10:21<byorgey>greentea: you can't, unfortunately.
08:10:36<byorgey>greentea: you'll need to write the type in a file and load the file into ghci.
08:10:38<greentea>Ah. Well, that explains that - thanks. :-)
08:10:44<greentea>Yeah, that's what i've been doing.
08:11:14<Cale>greentea: If that's the case, then you perhaps forgot the data keyword?
08:11:42<osfameron>hmmm, where is the "join" above coming from? In ghci I did :m +Control.Monad, and it complains No instance for (Monad ((->) a))
08:11:54<mauke>:m +Control.Monad.Reader
08:11:55<Cale>osfameron: Control.Monad.Instances
08:12:00<Cale>(or Reader)
08:12:04<greentea>Oh,no, i mean, it works when i load the file into GHCi, just wanted to know if there was some way of doing it without having to load up a file.
08:12:09<mauke>Reader is shorter and works in 6.4 :-)
08:12:10<osfameron>oh, so there are different definitions of it all over the shop?
08:12:22<Cale>osfameron: no, they're the same instance
08:12:27<mauke>osfameron: no, there's only one join. you're missing a Monad instance
08:13:01<osfameron>but the: join (^) 3 works fine with .Reader, and doesn't with C.M on its own
08:13:08<mauke>yes
08:13:25<byorgey>hm, does anyone know if the inability to define data types at the ghci prompt is due to a theoretical limitation, or is it simply an unimplemented feature?
08:14:07<goalieca>:type &&&
08:14:13<goalieca>:t &&&
08:14:15<lambdabot>parse error on input `&&&'
08:14:54<goalieca>tabarnac
08:15:00<byorgey>goalieca: need parens
08:15:03<byorgey>@type (&&&)
08:15:05<lambdabot>forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c')
08:15:07<Cale>osfameron: Control.Monad doesn't export the instance of Monad for ((->) e)
08:15:20<mauke>s/export/contain/
08:15:27<mauke>instances are always exported
08:15:31<Cale>Well, that too :)
08:15:39<byorgey>goalieca: for the function instance of Arrows, f &&& g = \x -> (f x, g x)
08:16:00<Cale>osfameron: Personally, I think it ought to go into the Prelude :)
08:16:21<goalieca>byorgey, thank you.
08:17:02<osfameron>Cale, mauke: ok, ta. Actually, I can't see where the monads come into it at all, I'll come back to it at some point when I'm not at work...
08:17:21<Cale>:t join
08:17:22<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
08:17:26<Cale>That's where
08:18:24<osfameron>oh, because functions are monads
08:19:59<wli>What's the join for function monads?
08:20:09<Cale>join f x = f x x
08:21:10<Cale>join :: Monad m => m (m a) -> m a, so if m = ((->) e), then join :: (e -> e -> a) -> e -> a
08:21:43<Cale>which could really be only one thing :)
08:23:41<byorgey>Cale: how much do you know about the Waterloo CS department?
08:23:50<Cale>not a whole lot
08:23:57<byorgey>ok, just wondering
08:24:05<byorgey>I'm applying to PhD programs
08:24:13<Cale>cool
08:25:31<Cale>Shallit is there, I think, if you're into formal language stuff.
08:26:26<byorgey>hm, ok, thanks, I'll take a look. Formal language stuff sounds good (I think).
08:28:22<Itkovian>Can one say that Java is strongly typed?
08:30:22<Cale>Itkovian: Yes, in some sense of the term
08:30:47<Itkovian>ok
08:31:29<Cale>Though I think its type system is a rather poor example if you want to show off strong static typing.
08:32:11<mauke>@docs Numeric
08:32:11<lambdabot>http://haskell.org/ghc/docs/latest/html/libraries/base/Numeric.html
08:32:46<Itkovian>Cale: no, I'm just reading a draft of a friend's PhD and it was menioned, and I wanted to make certain before commenting on it
08:39:15<dmwit>1% of my lines of code start with -- TODO:
08:39:18<dmwit>=(
08:40:57<Cale>Better than 100%
08:44:22<mux>bah, it's insanely hard to run a simple command, get output and the return status of the executable in haskell
08:44:43<dmwit>mux: Yeah. =(
08:45:08<mux>I fought against laziness so that I could use pOpen or hPipeFrom (from MissingH package), and now it works but I have other problems
08:45:38<mux>I get error messages from the command I'm running printed on the screen, and no easy/portable way to shut those off
08:46:33<dmwit>mux: I have a function runWithInput that I copied from jcreigh that is pretty nice, are you interested?
08:46:34<mux>I guess I could hack the pipe stuff from MissingH so that I also get stderr in the pipe and thus no screen pollution
08:46:45<mux>dmwit: very much, yes! thanks
08:47:04<quicksilver>is the missingH stuff lazy?
08:47:34<mux>the pipe* is described as such, but the hPipe* one isn't, the problem is that since I have a Handle, I have nothing but hGetContents to call
08:47:39<mux>and hGetContents is lazy
08:48:07<quicksilver>in that circumstance, I write my own strict hGetContents
08:48:09<mux>I just quicly wrote a strict hGetContents'
08:48:12<mux>yes
08:48:14<mux>I did that
08:48:18<quicksilver>normally I just iterate hGetLine
08:48:19<hpaste> dmwit pasted "for running programs in Haskell" at http://hpaste.org/3297
08:48:27<mux>I want the full output to parse it with Parsec
08:48:31<quicksilver>(and I curse the haskell gods for only giving us lazy hGetContents)
08:48:32<mux>I don't want to split it by lines
08:48:41<mauke>http://hpaste.org/3296
08:48:58<quicksilver>mux: well I join it up again afterwards :)
08:49:06<quicksilver>mux: it's just hGetLine is convenient and strict :P
08:49:07<mux> output <- pOpen ReadFromPipe "ldd" [f] hGetContents'
08:49:22<mux>once you have a strict hGetContents, this is very convenient =)
08:49:29<mauke>output <- getPipe "ldd" [f]
08:49:37<mux>if only it could pipe stderr as well so my screen doesn't get polluted
08:49:55<mux>mauke: thanks, will try this out
08:49:57<roconnor>hGetContents has broken semantics ... that can be useful /sometimes/, but not always.
08:49:58<Itkovian>dmwit: only 1%?
08:50:10<mux>mauke: oh, it's using forkProcess
08:50:22<dmwit>Itkovian: I also have a separate TODO file which has big, unfinished tasks (new features).
08:50:24<dmwit>=/
08:50:28<mux>mauke: I was trying to stay portable =) though of course ldd(1) isn't supposed to exist or be useful under Windows
08:50:29<Itkovian>lol
08:50:31<roconnor>really hGetContents should be called hUnsoundGetContents.
08:50:48<Itkovian>dmwit: you should see my Phd draft ;-)
08:50:50<osfameron>ACTION briefly pimps the London Perl Workshop: http://www.mccarroll.org.uk/~gem/pages/lpw2007-announce.txt
08:50:51<mauke>mux: fork is portable enough :-)
08:50:58<dmwit>hehehe
08:50:59<mux>for my concern, it sure is
08:51:06<mux>and that will drop the dependency on MissingH I guess
08:51:09<osfameron>looking for good, short talks, accessible to a general audience. If anyon'e interested.
08:51:15<mux>mauke: thanks =)
08:52:00<roconnor>MissingH seems like a broken idea. Independent functions out to be independently packaged.
08:52:08<roconnor>s/out/ought/
08:52:16<mux>I agree, but I found some stuff there that I didn't find elsewhere
08:52:37<mux>now that I know about FileManip though for instance, I won't use their glob function anymore =)
08:52:44<mux>FileManip is nice
08:52:50<mux>the find and glob APIs are good
09:00:35<quicksilver>roconnor: I believe that, when cosmicray started writing that, he wasn't sure how much of it he was reinventing and what should go where
09:00:49<quicksilver>roconnor: and it is his intention to slowly separate + repackage those parts which seem important
09:00:58<roconnor>:)
09:01:15<roconnor>MissingH is certainly better than nothing ... I think
09:01:49<roconnor>and presumably MissingH was made before we had such a nice Cabal/Hackage system?
09:02:56<quicksilver>yes
09:03:38<roconnor>presumably getting at a bunch of little packages should be easier.
09:03:44<roconnor>or maybe we need cabal install first.
09:03:58<roconnor>probably no need to wait.
09:06:33<quicksilver>CosmicRay is a bit too keen on lazy IO for my liking, too :)
09:07:07<roconnor>I don't pay him enought not to be lazy.
09:07:11<quicksilver>hdbc is lazy by default and I believe that is a bad decision in a DB library.
09:07:57<roconnor>oh, that sort of lazy
09:08:09<roconnor>I thought you were claiming he was lazy about dividing up MissingH ;)
09:10:37<mauke>@hoogle genericSplit
09:10:38<lambdabot>List.genericSplitAt :: Integral a => a -> [b] -> ([b], [b])
09:10:38<lambdabot>Data.List.genericSplitAt :: Integral i => i -> [b] -> ([b], [b])
09:14:48<takamura>hello
09:15:14<lokimaf_>what would be your name written in Kanji?
09:15:20<Vq^>hello takamura
09:15:36<dcoutts>@seen pgavin
09:15:36<lambdabot>I saw pgavin leaving #haskell 13h 22m 56s ago, and .
09:15:59<dcoutts>@tell pgavin gstreamer/Media/Streaming/GStreamer/Core/Types.chs:244:11: Not in scope: `cObjectUnfloat'
09:15:59<lambdabot>Consider it noted.
09:16:08<takamura>lokimaf_, I cant write kanji in this computer
09:16:23<lokimaf_>kk was just wondering
09:16:40<takamura>taka is high and mura is town
09:17:14<lokimaf_>cool, so would that be high in terms of elevation?
09:17:37<takamura>yes, many Japanese names are names of natural places
09:17:55<lokimaf_>makes sense
09:18:22<takamura>its the same for other languages
09:18:32<takamura>names of places, jobs, etc.
09:18:59<takamura>or town names
09:19:35<takamura>anyway, i'm not japanese :p
09:19:41<lokimaf_>i just noticed that your name was in abugida form and figured it was Japanese
09:19:59<lokimaf_>oh so is it an anime fascination?
09:20:17<lokimaf_>tzal gyd
09:20:20<takamura>what's abugida?
09:20:38<lokimaf_>where constonants are inherantly associated with a vowel
09:20:46<takamura>no, it's a japanese poet, Takamura Koutarou
09:20:57<takamura>ah
09:21:45<lokimaf_>so there arent any crunchy constonants in many asian languages
09:21:51<takamura>a friend of mine show me some works of Takamura and i liked it
09:21:55<takamura>and choose the nick
09:22:49<takamura>mm i dont know, japanese is not much related to other asian languages, except korean
09:23:02<takamura>it is also related to finnish
09:23:06<takamura>iirc
09:23:39<osfameron>don't think so
09:23:43<lokimaf_>hindi is abugida style language as well
09:23:52<takamura>some scholars say it is an uralo-altaic language
09:23:53<osfameron>finnish is related to estonian, and allegedly to Hungarian, but not really
09:23:54<quicksilver>finnish is related to hungarian
09:24:03<takamura>spanish is abugida also
09:24:10<quicksilver>the finno-ugrian (sp.?) languages are a small group
09:24:29<lokimaf_>naw spanish uses latin letters
09:25:01<lokimaf_>they can have constonant combinations like tcokolat
09:25:12<takamura>mm, then i didnt understood well what abugida means
09:25:21<roconnor>mmm tcokolat
09:25:23<lokimaf_>http://en.wikipedia.org/wiki/Abugida
09:25:24<lambdabot>Title: Abugida - Wikipedia, the free encyclopedia
09:25:25<roconnor>:P
09:25:35<osfameron>lokimaf_: I've seen txokolat, in Catalan and Basque writing
09:25:50<osfameron>quicksilver: I've read it as "finno-ugric"
09:26:03<takamura>tcokolat is not spanish
09:26:06<takamura>chocolate
09:26:42<lokimaf_>tcokolat iz inglic
09:27:01<lokimaf_>fonetik englic
09:27:19<lokimaf_>c = sh
09:27:28<takamura>now i checked some japanese grammar, and it says japanese can be a uralic or altaic language
09:27:35<takamura>ah
09:28:40<takamura>i allways wondered why english spelling is so difficult, why so many consonants? >_<
09:28:45<lokimaf_>xaskel = haskell
09:29:38<lokimaf_>konsonants ar a strengt
09:30:03<lokimaf_>do tzal gyd
09:30:47<takamura>now i read wikipedia, japanese is not abugida
09:30:48<lokimaf_>oh well
09:30:52<takamura>demotic egiptian is, i think
09:31:19<raxas>takamura: did you considered learning czech? "Plch zdrhl skrz drn, prv zhltl hrst zrn." is a correct and meaningfull czech sentence
09:31:42<lokimaf_>what does it mean
09:31:43<takamura>raxas, oh my god!!
09:32:07<lokimaf_>?
09:32:36<raxas>plch is kind of mouse. so it is about he ate some grain and run away through the grass
09:33:10<takamura>wow
09:33:49<takamura>what languages are related to czech?
09:34:22<lokimaf_>k uel aim of tu pretend tu bi produktiv, meibi sliip iven, iz 5:30am
09:34:25<raxas>takamura: slovak and polish
09:34:41<lokimaf_>leitrz
09:34:52<ivanm>I finally managed to fix the looping problems in my (first-ever) STM-based app... except that even after it finishes ghci is still using large amounts of CPU... is there a way of killing off the threads?
09:35:40<sjanssen>ivanm: killThread?
09:35:55<takamura>lokimaf_, inglic is easier than english :D
09:36:08<ivanm>@where killthread
09:36:08<lambdabot>I know nothing about killthread.
09:36:12<ivanm>@where killThread
09:36:13<lambdabot>I know nothing about killthread.
09:36:16<takamura>i will try to learn it
09:36:19<ivanm>dammit, wrong command
09:39:10<mux>@src error
09:39:11<lambdabot>error s = throw (ErrorCall s)
09:39:54<ivanm>sjanssen: is there an easier way for a thread to kill itself or for the controlling thread to kill all sub-threads?
09:40:05<ivanm>or can I just go: killThread myThreadId ?
09:40:27<sjanssen>hmm, I'm not sure what will happen with killThread myThreadId
09:41:01<ivanm>ACTION goes off to try
09:41:17<sjanssen>yeah, that's safe
09:41:36<sjanssen>or you could just throw an exception
09:41:45<ivanm>doesn't work...
09:41:49<ivanm>@type killThread
09:41:50<lambdabot>Not in scope: `killThread'
09:41:52<ivanm>@type myThreadId
09:41:53<lambdabot>Not in scope: `myThreadId'
09:41:59<ivanm>grr...
09:42:10<ivanm>@type Control.Concurrent.myThreadId
09:42:12<lambdabot>IO GHC.Conc.ThreadId
09:42:17<ivanm>@type Control.Concurrent.killThread
09:42:19<lambdabot>GHC.Conc.ThreadId -> IO ()
09:42:21<sjanssen>killThread =<< myThreadId
09:42:26<ivanm>yeah
09:42:36<ivanm>but my point was, just doing "killThread myThreadId" won't work :p
09:43:25<ivanm>stack overflow :(
09:44:05<ivanm>I don't know if its my code, or how busy my comp is, forkIO or STM, but the results it should be printing out every "timestep" come out in a rather jerky fashion :s
09:44:37<scook0_>buffering, maybe?
09:44:53<hpaste> ivanm pasted "Stack overflow with STM" at http://hpaste.org/3298
09:48:08<Lemmih>ivanm: 'return ()' instead of 'killThread =<< myThreadId' still gives a stack overflow.
09:48:25<ivanm>Lemmih: well, it didn't for me... maybe I had more RAM without it :s
09:48:37<ivanm>s/without it/before when I didn't have it
09:49:06<quicksilver>I would personally always collect threadIds when I fork
09:49:12<ivanm>OK
09:49:24<ivanm>so, how could I do that?
09:49:35<quicksilver>thread <- forkIO ...
09:49:38<ivanm>shift the forkIO from the newAnt to where I do the mapM_ ?
09:49:57<quicksilver>change newAnt's type to IO ThreadID?
09:50:00<quicksilver>and remove the return ()
09:50:40<scook0>(I'm personally not seeing a stack overflow, compiled or not)
09:50:42<ivanm>quicksilver: then turn mapM_ to mapM ?
09:50:45<quicksilver>yes
09:50:49<ivanm>*nod*
09:50:57<quicksilver>and presumably keep the list of threadIds around somewhere
09:51:01<quicksilver>to kill them all off at the end
09:51:07<ivanm>*nod*
09:51:39<quicksilver>this is, by the way, an annoyance of thread based programming in ghci
09:51:43<quicksilver>I submitted a bug about it
09:52:06<quicksilver>http://hackage.haskell.org/trac/ghc/ticket/1399
09:52:08<lambdabot>Title: #1399 (better support for developing threaded applications in ghci) - GHC - Trac
09:52:23<quicksilver>still it's probably good practice to collect thread IDs
09:52:28<quicksilver>and kill em all off when that job is done
09:52:34<quicksilver>(unless they are coded to die automatically)
09:52:49<ivanm>yay! it worked!
09:53:12<LeCamarade>Me, what I wanted was to do ...
09:53:17<quicksilver>I love how easy it is to change a couple of types in a program :)
09:53:27<quicksilver>changing somethign from IO () to IO ThreadId is so logical
09:53:29<quicksilver>...
09:53:44<ivanm>I changed "mapM_ ..." to "ants <- mapM ...", and then at the end of runSystem added "mapM_ killThread ants"
09:53:46<LeCamarade>A list of IO actions in parallel and have 'em return something.
09:54:01<LeCamarade>And I failed.
09:55:09<ivanm>LeCamarade: :(
09:57:31<hpaste> sjanssen pasted "parsequence" at http://hpaste.org/3299
09:57:36<sjanssen>LeCamarade: ^^^
09:58:41<LeCamarade>See, thread stuff take IO (). Which doesn't return sane values. So ... I can't fetch say web pages in parallel. Short of IORef, which me no like.
09:58:52<EvilRanter>sjanssen, wouldn't a channel be perfect for that sort of thing?
09:59:01<LeCamarade>Oh. Wait. Nice paste.
09:59:10<sjanssen>EvilRanter: perhaps, depends on whether the result order matters
09:59:30<EvilRanter>ah, yes, i see. yours preserves order.
09:59:43<LeCamarade>Well, I am re-writing my spider from Ruby. In Ruby it did:
10:01:14<LeCamarade>[url1, url2, url3].map {|x| open(x) {|f| f.read} } # Result is ... [data1, data2 ...]
10:01:17<Lemmih>Beware of exceptions.
10:01:26<LeCamarade>Sorry it is Miranda. ;o)
10:01:40<LeCamarade>Miranda is a Trademark of Research Software.
10:02:34<LeCamarade>And the Haskell version didn't quite fit. That's clean. Lemme stab again soon.
10:02:42<ivanm>looks like my problem still isn't fully solved... since if I run it a few times I still keep getting stack overflow errors :s
10:03:17<sjanssen>Lemmih: yes, I should catch the exception and stick it into the MVar
10:03:31<ivanm>and for some reason, if I take away the "killThread =<< myThreadID" bit, it crashes even earlier :s
10:03:35<Lemmih>ivanm: writeTVar state $! val
10:03:56<sjanssen>of course, the program will crash with "blocked indefinitely", which is almost equivalent :)
10:04:07<ivanm>yeah
10:04:12<ivanm>which it looks like what it's doing :s
10:05:44<ivanm>OK, for some reason when "threadKill =<< myThreadId" is removed, then ghci doesn't reduce in CPU/Mem usage :s
10:06:12<Lemmih>Works for me.
10:07:34<sjanssen>LeCamarade: the Haskell equivalent is mapM (\x -> open x >>= read) [url1, url2, url3] -- assuming valid definitions of open and read
10:08:05<ivanm>OK, looks like there's a bug with my code :s
10:08:06<quicksilver>or forM [url1,url2,url3] (\x -> open x >>= read) if you prefer that order
10:08:37<quicksilver>but it's not parallel which is what LeCamarade is after
10:08:47<sjanssen>is the Ruby version parallel?
10:09:01<sjanssen>also, it is trivial to write parMapM
10:09:14<quicksilver>you just did :)
10:09:16<quicksilver>more or less
10:09:20<sjanssen>right
10:10:24<hpaste> sjanssen annotated "parsequence" with "factor into a futures library" at http://hpaste.org/3299#a1
10:14:02<quicksilver>sjanssen: nice, except you forget to catch the exceptions
10:14:11<sjanssen>quicksilver: yeah, that was a half edited copy
10:14:25<sjanssen>I forgot I was in the middle of adding exception support :)
10:16:13<quicksilver>nice idea of a Future type though
10:17:10<hpaste> sjanssen annotated "parsequence" with "with exceptions" at http://hpaste.org/3299#a2
10:17:14<sjanssen>Haskell rocks.
10:17:29<SamB_XP_>parsequence?
10:19:17<sjanssen>SamB_XP_: yep, a version of sequence that runs each action concurrently
10:19:51<osfameron>ACTION worked through the "Tying the Knot" with lazy lets at weekend
10:20:05<SamB_XP_>shouldn't it take some kind of ... strategy for ensuring the evaluation of the return value?
10:20:15<SamB_XP_>(if desired)
10:20:26<sjanssen>ACTION thinks readMVar m >>= either throw return is beautiful
10:20:29<osfameron>to generate a doubly linked list. Actually the hardest thing was traversing the list (because of all the Maybe's getting in the way)
10:20:41<sjanssen>SamB_XP_: the client is responsible for that
10:21:10<SamB_XP_>sjanssen: hmm.
10:21:45<SamB_XP_>so, like, each IO action has to apply said strategy before returning?
10:21:53<sjanssen>sure
10:22:00<quicksilver>well this was designed for cases where the IO is what you actually 'want' to do
10:22:05<SamB_XP_>fair enough, I guess
10:22:10<quicksilver>if your code was doing 'pure work' then yes
10:22:14<quicksilver>a strategy might make sense
10:22:39<quicksilver>in very many cases the IO is enoguh though
10:22:45<SamB_XP_>I guess so
10:22:47<quicksilver>(as long as you're not using brokenlazyIO :P)
10:23:00<SamB_XP_>hehe
11:21:19<ivanm>I don't suppose there is an easy way in ghci to find all threads in that session?
11:21:27<ivanm>just to see if I forgot to close any, etc.
11:21:44<quicksilver>no
11:21:49<quicksilver>see my bug report :)
11:32:53<ivanm>quicksilver: heh, true
11:35:18<ivan`>is there a normal way to do distributed computing in haskell?
11:35:21<ivan`>ie, objects over network
11:35:48<Lemmih>Nope.
11:36:36<quicksilver>no
11:36:42<quicksilver>that's a hard problem (TM)
11:36:58<quicksilver>actually immutability makes some parts of it much easier, theoretically
11:36:58<ivan`>there's nothing like python's twisted?
11:37:07<quicksilver>not that I've heard of
11:37:19<matthew_->well, there're json bindings
11:37:24<matthew_->and there's Data.Binary
11:37:31<quicksilver>that's not the same thing :P
11:37:36<quicksilver>that's just APIs which might help you build one
11:37:39<matthew_->indeed
11:37:44<matthew_->also, it has a different name
11:37:49<quicksilver>;P
11:37:52<matthew_->;)
11:39:15<ivan`>ACTION wanders back to his simple little python world
11:39:31<ivan`>with lack of lazy and messy stream code
11:41:02<quicksilver>ivanm: a "transparent" distribution architecture for haskell would be a beautiful thing, though
11:41:15<quicksilver>ivanm: although you'd have to make some decisions about how 'transparent' you really wanted it to be
11:41:19<ivanm>how do you mean "transparent" ?
11:41:30<ivan`>is erlang the only thing that does both SMP and network distribution properly?
11:41:36<ivan`>it seems like i can't have both worlds
11:41:38<Botje>see-through lingerie for cabal packages!
11:42:36<matthew_->ivan`: yeah, that wouldn't surprise me
11:42:45<quicksilver>ivanm: well, so that code didn't need to be aware it was running on multiple machines
11:42:50<matthew_->the only issue is that erlang's SMP support is currently rubbish
11:42:52<quicksilver>ivanm: to some extent, at least
11:43:11<ivanm>quicksilver: *nod*
11:43:15<ivan`>if there's any confusion i'm not ivanm
11:43:18<ivan`>nor ivan
11:43:22<matthew_->so running the erlang VM with SMP support turned on often results in things running more slowly across multiple cores than on a single core
11:43:29<ivanm>ivan`: nor ivant? :p
11:43:38<ivan`>heh
11:43:53<matthew_->I reckon you are the same person and just like talking to yourself ;)
11:44:14<Botje>ivanBACKQUOTE
11:44:17<ivan`>backtick
11:44:44<pejo>ivan, did you check GdH?
11:44:48<hkBst>nasty insects, them backticks
11:44:48<quicksilver>I was aware that you were different people
11:44:58<quicksilver>but tab-complete did get the wrong one at one point :)
11:45:06<quicksilver>thus drawing ivanm into the conversaton by mistake :)
11:45:19<ivan`>i'm looking at GdH
11:45:27<quicksilver>tab-complete always seems to prefer pure alpha names to partly punctuation names...
11:45:43<pejo>But as you mention, Erlang has a pretty good track record in the kind of thing you seem to want to do.
11:45:43<ivan`>last-used order works for me
11:49:08<mux>System.FilePath.Find is really sexy
11:51:14<yitz>@seen bos
11:51:14<lambdabot>bos is in #haskell and #ghc. I last heard bos speak 1d 5h 42m 51s ago.
11:51:26<yitz>Well, let him know that next time you see him.
11:51:40<mux>yeah, I intend to :-)
11:52:28<quicksilver>although 'find' should be called unsafeDontUseThisFind
11:52:32<quicksilver>'fold' is nice though :)
11:52:50<mux>what's so unsafe about find ? *gulps*
11:52:54<mux>I just switched to using it
11:52:59<quicksilver>it's unsafe interleaving IO
11:53:05<mux>files <- find always (anyPerms 0111) path
11:53:15<mux>recursing over all executable files in a directory
11:53:20<mux>so, ugh, you're saying the above code is unsafe?
11:53:21<yitz>It's not _so_ unsafe - just a little.
11:53:23<quicksilver>you could do really strange stuff if you do anythign which changes the predicate
11:53:29<mux>ah
11:53:32<quicksilver>before you'd consumed the whole list
11:53:37<mux>I guess my usage is ok though
11:53:53<mux>it's not doing anything funky with the predicates
11:54:06<quicksilver>as long as you know that none of the code that operates on files would affect the output of files
11:54:09<quicksilver>as it were
11:54:15<quicksilver>e.g. as long as none of it is changing permissions
11:54:21<yitz>I think the only issue is that if something changes in the fs while you are iterating you may get weird results.
11:54:22<quicksilver>creating new dirs
11:54:22<quicksilver>etc
11:54:25<mux>okay, I'm not doing this
11:54:38<quicksilver>yitz: or if *you* change something in the fs, while you are iterating
11:54:45<yitz>right.
11:54:52<quicksilver>yitz: you could easily set up an infinite loop if you create a directory, e.g.
11:54:56<mux>both sound unpleasant
11:55:04<yitz>unless you are careful
11:55:08<quicksilver>right
11:55:30<quicksilver>I just hate it when people add new referentially opaque features to the language
11:55:47<quicksilver>when I'm busy trying to tell people that referential transparency is one of the reasons I use haskell :)
11:56:07<quicksilver>have to keep adding "as long as you don't use... hdbc, FilePath.Find .... "
11:56:12<mux>I think people are conspiring to get you to stop using haskell :-)
11:56:14<ico>where can I find the haskell's select() implementation, for asynchronously waiting on multiple file descriptors ?
11:56:27<quicksilver>ico: the canonical answer is 'just use threads'
11:56:32<mux>ico: you tipically don't use select() / poll() / whatever in haskell, we have threads
11:56:36<quicksilver>ico: threads do the right thing (they use select() internally)
11:56:40<ico>ok, I see
11:56:53<ico>My imperative brain is hurting more and more ...
11:56:59<quicksilver>if you really want it, it's somehwere in System.POSIX or therabouts
11:57:00<mux>that's expected
11:57:09<quicksilver>ico: threads in haskell are really really cheap. Almost free.
11:57:20<mux>and soooooooooooooo damn easy
11:57:20<mux>forkIO, that's it.
11:57:20<ico>I'll take your advice and do the thread thing then
11:57:23<quicksilver>ico: so it's quite safe to fork two new threads for every file descriptor
11:57:27<quicksilver>(one for reading, one for writing)
11:57:38<ico>new to haskell threading though, more to learn today
11:58:37<mux>ACTION garbage collects the countless 'do' that end up being useless after code refactoring
11:58:47<mux>I always, always forget about those
11:59:32<mux>it's not as if they were harmful, but I find it quite unaesthetic to have many of those scaterred around the code
12:00:24<quicksilver>makes your code read like frank sinatra
12:00:26<quicksilver>do be do be do
12:00:35<mux>heheh
12:04:17<TSC>I "do" it my way?
12:15:39<ndm>@seen dcoutts
12:15:39<lambdabot>dcoutts is in #gentoo-haskell, #haskell, #ghc and #haskell-overflow. I last heard dcoutts speak 34m 22s ago.
12:16:06<ndm>@slap dcoutts
12:16:06<lambdabot>ACTION smacks dcoutts about with a large trout
12:21:36<dcoutts>hia ndm
12:21:53<LeCamarade>Phew. Reddit is back.
12:24:15<yitz>Besides threads, you can also use hGetBufNonBlocking
12:25:45<yitz>Underneath the hood, I don't think GHC uses select/poll/epoll at all.
12:26:17<dcoutts>yitz: yes it does
12:26:32<mux>it has no choice but using those functions
12:26:33<yitz>I heard that Einar K. experimented with these in his network-alt library.
12:26:48<mux>otherwise you just cannot implement forkIO
12:26:49<yitz>oh yeah? interesting.
12:26:53<dcoutts>that's exactly how ghc does all blocking and non-blocking IO
12:27:06<mux>that's exactly how any 100% userland threading library does it
12:27:08<yitz>OK
12:27:13<mux>ie, libc_r under FreeBSD is doing the same
12:27:28<mux>you have no choice about it, you _need_ to prevent blocking
12:28:31<dcoutts>yitz: it could be improved to use system-specific improvements over poll/select
12:28:35<dcoutts>ie kpoll, epoll etc
12:30:56<mux>kqueue, kevent
12:31:05<dcoutts>oh, right
12:31:15<mux>it sure would help for cases where we have many threads
12:31:20<profmakx>anyone tried bootstrapping ghc on FreeBSD-Current/amd64? I am getting stuck when compiling the rts
12:31:42<dcoutts>mux: that should be easier to do now in the threaded rts
12:31:42<mux>profmakx: what's the error message?
12:31:53<mux>dcoutts: I need to take a look at this code
12:31:53<dcoutts>mux: since the IO manager thread is implemented in Haskell
12:31:58<mux>hmm, nice
12:32:12<dcoutts>mux: so it should be easier to do system-specific impls of it
12:32:16<mux>ACTION nods
12:32:35<profmakx>mux Linker.c:3556:0: error: `R_X86_64_32S' undeclared (first use in this function)
12:32:46<mux>hmm, unfriendly message :-)
12:33:22<yitz>There are Simon posts that report problems with poll/select. He says readNonBlockingFD is implemented using read with O_NONBLOCK. http://www.haskell.org/pipermail/haskell-cafe/2006-February/014619.html
12:33:25<lambdabot>Title: [Haskell-cafe] Re: standard poll/select interface, http://tinyurl.com/2xxajz
12:33:26<profmakx>it has something todo with "MAP_32BIT"
12:33:34<dcoutts>mux, profmakx: it'll be some #ifdef problem I expect
12:33:39<mux>yeah
12:33:46<mux>it's hard to tell without more context though
12:33:52<mux>and context may be totally lost at this point
12:33:56<dcoutts>"MAP_32BIT" is a linux thing I think
12:34:05<profmakx>yes it is
12:34:07<dcoutts>it's to mmap into the first 32bit of the address space
12:34:15<mux>profmakx: I have yet to test building GHC on RELENG_7, but I'll do soon
12:34:16<dcoutts>eg for loading code
12:34:34<mux>since 7.0-R is for soon now, we'd better make it possible for people that install it to use ghc
12:34:43<mux>dcoutts: oh, evil
12:34:56<profmakx>unfortunately i am in no way a ghc expert i don't know where to start :)
12:35:00<mux>it's the kind of things wine uses
12:35:09<mux>to map DLLs at their expected address
12:35:18<dcoutts>mux: no, that's MAP_FIXED
12:35:34<mux>MAP_FIXED is portable
12:35:38<mux>I'm definitely talking about something else
12:36:04<dcoutts>mux: I thought it was to do with the 'small' code model, where function pointers are 32bit and get sign-extended to 64bit
12:36:06<mux>(and MAP_FIXED can fail)
12:36:33<mux>dcoutts: I know there's something else: we are lacking some feature that wine needs, and wine is thus failing for us
12:36:38<mux>maybe that has been fixed though
12:36:39<profmakx>thats what it says in linker.c
12:36:59<mux>anyways, undefined MAP_32BIT sounds like worth trying, at least
12:37:14<profmakx>well i defined MAP_32BIT to be 0
12:37:25<profmakx>then the error i pasted earlier turned up
12:37:50<mux>beware, they may check for it using #fdef
12:38:01<mux>in which case, it would still succeed if you defined MAP_32BIT to 0
12:38:05<mux>try #undef MAP_32BIT
12:39:26<profmakx>i might also have gotten something wrong with the bootstrap setup, because they #ifdef x86_64_HOST_ARCH
12:39:30<profmakx>but the host is 32bit
12:39:36<profmakx>the target is 64
12:39:52<profmakx>i think i will try a clean start first :)
12:42:23<ekidd>Good morning.
12:44:30<LeCamarade>ekidd: Good afternoon.
12:45:20<TomMD>@time LeCamarade
12:45:22<lambdabot>Local time for LeCamarade is Mon Oct 15 15:45:17 2007
12:47:57<profmakx>LeCamarade is ahead of my timezone!
12:51:11<LeCamarade>:o)
13:03:23<mux>damn, and I thought haskell-cafe@ would be low volume
13:06:33<roconnor>*l*
13:06:48<roconnor>apparently haskell-cafe is a flamewar fest
13:07:38<ndm>yeah
13:07:52<ndm>but jerzy seems to have started 2 in 2 days
13:09:39<quicksilver>jerzy appears to be failing to communicate effectively in some cases
13:09:44<quicksilver>a lot of cross-purposes going on
13:09:59<quicksilver>I recommend a good user agent for reading the cafe :)
13:10:44<quicksilver>does anyone know if isaac dupree is an IRCer?
13:14:12<pierre->hi all
13:14:34<ndm>hi pierre-
13:24:52<igel>is there a Vector type in haskell?
13:25:11<igel>one that allows indiced access to elements in O(1)?
13:25:17<kpreid>igel: Data.Array
13:25:39<igel>yeah sure, but i mean one that has insert and delete already implemented
13:25:53<igel>so that the array is replaced if it is to small
13:26:22<ADEpt>igel: you need growable one? Data.Sequence. Not O(1), but O (nlogn) (IIRC)
13:27:01<ADEpt>igel: besides, you might be better off with Data.Map or Data.IntMap, depending on your task
13:27:35<igel>there is no task, i was just wondering
13:27:51<ADEpt>igel: then, DataIntMap it is :)
13:30:25<igel>how come IntMap a is faster than Map Int a?
13:30:41<quicksilver>cleverer algorithm
13:30:51<quicksilver>using the internal structure of ints
13:31:31<quicksilver>Data.Sequence does things in O(log (distance from nearest end))
13:31:41<quicksilver>which is as good as O(1) in practice, in many cases
13:31:46<ADEpt>+1
13:32:05<igel>hmm, i have some time today
13:32:10<quicksilver>of course it does some things faster
13:32:32<igel>i'll just check out data.seq and write a Vector
13:32:48<quicksilver>append is O(log(smaller sequence))
13:33:02<quicksilver>whereas append in a naive vector is O(sum of sizes of two sequences)
13:33:23<igel>sure, a vector is quite static
13:33:30<igel>but reading is fast
13:33:45<igel>i normally use vectors for, say, guis
13:33:54<igel>if you represent a list
13:34:11<igel>and everytime it is displayed, you need index-based access to the elements
13:34:19<quicksilver>but you don't, of course :)
13:34:23<igel>much more often that changing the original strucutre
13:34:30<quicksilver>typically displaying a list involves iterating through it
13:34:35<quicksilver>or iterating through a sublist
13:34:39<quicksilver>not indexed access...
13:34:49<etnt>I just noticed the binary stuff, now I wonder if there exist anything similar to Erlang's bitsyntax ?
13:35:10<igel>hmm that sounds reasonable^^ :)
13:35:34<quicksilver>igel: in practice I would be very surprised if a sequence fails to provide good enoguh performance
13:36:02<quicksilver>the main disadvantage of a sequence over traditional imperative structures is not O(1) access, but memory locality
13:36:23<igel>well it might prove ineffective for index-based replacing then
13:36:24<quicksilver>so if you used a sequence for 1 million elements in a very random access fashion
13:36:42<MyCatSchemes>quicksilver: my cache hurts at the very prospect.
13:36:47<quicksilver>then your main problem would be that the imperative C++ array-based vector has locality
13:36:53<quicksilver>exactly, MyCatSchemes
13:37:16<quicksilver>igel: update on sequence is O(log (distance to nearest end))
13:37:42<quicksilver>cache locality and memory access patterns are much more important than notional O(1) access
13:37:53<quicksilver>This is, in fact, because O(1) access isn't really O(1) :)
13:38:04<quicksilver>O(1) access is only O(1) if you also have a cache hit
13:38:12<igel>do you mean paging issues?
13:38:12<EvilRanter>or, depending on how you look at it, O(log n) is really O(1)
13:38:14<quicksilver>and C++-arrays are much more likely to get cache hits most of the time
13:38:24<EvilRanter>;)
13:38:26<quicksilver>igel: well not paging in the OS sense, no
13:38:42<quicksilver>igel: but caching at the CPU cache level
13:38:49<quicksilver>similar ideas of course
13:39:08<igel>ok.. that's new to me
13:39:45<quicksilver>for "normal" applications, such as your GUI example, you will not find the data structure to be the bottleneck
13:39:57<quicksilver>and you would be please with Data.Sequence's performance
13:40:12<quicksilver>you might even win somethign over the C++ equivalent due to fast growing and appending
13:40:15<quicksilver>in some cases
13:40:19<quicksilver>and you get cheap undo support for free!
13:40:20<igel>well i'm not really into gui programming with haskell
13:40:21<quicksilver>which is really nice
13:40:42<quicksilver>the main kind of example where data locality would bite you would be writing a graphics package
13:40:44<igel>the last gui framework i really learned was awt/swing
13:40:52<quicksilver>you wouldn't want to Data.Seq an entire image of pixels
13:40:57<quicksilver>that would be painful
13:41:09<quicksilver>say, 80 million pixels, 4 bytes each :)
13:41:25<igel>and implementing a swing model means implementing interfaces with methods like "elementAt(int)"
13:41:57<igel>and if such a method is invoked once for each displayed index, it is better to have random access :)
13:45:19<quicksilver>typically it's enough that the complexity is not O(n)
13:45:31<quicksilver>O(log n) is much much better than O(n)
13:46:01<quicksilver>it's unusual to find examples where O(1) vs O(log n) matters; it's also fiendishly hard to demonstrate and analyse
13:46:16<quicksilver>because various hardware issues confuse the difference between the two anyway
13:46:34<roconnor>ACTION prefers O(inverse ackermann(n))
13:46:46<iank>roconnor: :'D
13:47:05<MyCatSchemes>ACTION prefers O(inverse ackermann(n,graham's number))
13:47:25<igel>:D
13:47:26<LeCamarade>O(0)
13:47:28<iank>ACTION prefers O(3)
13:47:38<roconnor>O(3)=O(1)
13:47:54<iank>.. I know.
13:47:55<LeCamarade>o(-1) -- Predicts.
13:48:06<iank>But I rather like to bullshit that O(3) takes three times as long :)
13:48:07<osfameron>at YAPC::Vienna Damian Conway showed us how to write code in O(-1) time
13:48:15<MyCatSchemes>O(busybeaver-inverse(n))
13:48:36<osfameron>using positronic variables that travel back in time
13:48:36<roconnor>MyCatSchemes: know any non-constant algorithms known to be of that order?
13:48:46<LeCamarade>:o)
13:49:13<LeCamarade>Bottom algorithms?
13:49:21<MyCatSchemes>roconnor: depends what you're measuring. Certainly none of that order in time. ^_^
13:49:59<profmakx>mux, i seem to have got the rts to compile by undefining x86_64_HOST_ARCH
13:50:04<roconnor>There is some unification algorithm that is O(n*inverse achermann(n))?
13:57:37<kosmikus>ndm: ping
13:58:58<fasta>Can I catch stack overflows?
13:59:37<roconnor>interesting question
13:59:45<roconnor>should be easy to test
14:00:12<fasta>It doesn't say ***Exception Foobar
14:00:24<fasta>So, it seems that it works on a different level.
14:00:33<fasta>Which would imply the answer was no.
14:01:28<LeCamarade>> let die () = 0 + die () in die ()
14:01:33<lambdabot> Exception: <<loop>>
14:01:34<roconnor>:(
14:01:51<LeCamarade>It says Exception for me.
14:02:27<roconnor>LeCamarade: that isn't a stack overflow
14:02:28<vincenz>it's not that simple in general tho
14:02:33<vincenz>with lazy data structures
14:02:39<vincenz>you coudl have the overflow during consumption and not construction
14:02:40<roconnor>> foldl (+) 0 [1..]
14:02:48<lambdabot>Terminated
14:02:52<roconnor>> foldr (+) 0 [1..]
14:02:55<lambdabot> Exception: stack overflow
14:03:01<vincenz> ^^^^^^^^
14:03:04<LeCamarade>From GHCi: *** Exception: stack overflow
14:03:16<vincenz>@hoogle catch
14:03:17<lambdabot>Prelude.catch :: IO a -> (IOError -> IO a) -> IO a
14:03:17<lambdabot>Control.Exception.catch :: IO a -> (Exception -> IO a) -> IO a
14:03:17<lambdabot>GHC.ConsoleHandler.Catch :: (ConsoleEvent -> IO ()) -> Handler
14:03:47<ToRA>Prelude Control.Monad.Fix Data.List Control.Exception> Control.Exception.catch (print $ foldr1 (+) [0..]) (const $ putStrLn "caught")
14:03:48<ToRA>caught
14:03:52<LeCamarade>catch is for IO actions only, no?
14:04:01<vincenz>add a return :)
14:04:13<vincenz>ToRA: try "return" iso "print"?
14:04:18<Olathe>ACTION returns.
14:04:34<fasta>Maybe it is because I use xc that the Exception *** isn't printed in compiled programs.
14:05:03<roconnor>LeCamarade: correct. You have to catch an IO action that demands a stack overflow
14:05:12<ToRA>vincenz: if you s/return/print then it fails
14:05:15<roconnor>otherwise there would never be a stack overflow
14:05:16<ToRA>but i'd expect it to
14:05:33<ToRA>since it's the print call in ghc that is forcing the foldr1
14:05:38<ToRA>*ghci
14:05:59<LeCamarade>Oh. :o)
14:06:01<vincenz>i guess you'd need to seq it
14:06:39<quicksilver>even imprecise exceptions can only be caught in IO
14:06:40<Saizan>?type evaluate
14:06:40<ToRA>ah nice, with ghci 6.8
14:06:42<ToRA>Prelude> foldr1 (+) [0..]
14:06:42<ToRA>Stopped at <exception thrown>
14:06:42<ToRA>_exception :: e = stack overflow
14:06:42<lambdabot>Not in scope: `evaluate'
14:06:43<ToRA>[<exception thrown>] Prelude>
14:06:45<quicksilver>see the awkward squad paper
14:07:12<quicksilver>unless I'm mistaken
14:07:58<LeCamarade>:t par
14:08:00<lambdabot>forall a b. a -> b -> b
14:09:42<quicksilver>catching imprecise exceptions in pure code would violate referential transparency, I think
14:10:22<vincenz>yep
14:10:33<LeCamarade>But I don't know if I'll ever grow to like exceptions. Even before I knew about Maybe a, I didn't like them.
14:11:55<quicksilver>I think they have their place
14:12:20<quicksilver>but in many (most?) situations there are preferrable alternatives
14:12:21<roconnor>whare are imprecise exceptions? Violations of the abstract machine?
14:12:38<ndm>kosmikus: pong
14:12:38<quicksilver>they're a kind of _|_
14:12:53<quicksilver>as such, I think they're denotationally ok
14:13:07<roconnor>stack overflow isn't _|_
14:13:18<quicksilver>the strange part is that you can catch them..
14:13:24<quicksilver>but IO is allowed to be strange
14:13:30<dcoutts>roconnor: that's an asynchronous exception
14:13:35<roconnor>oh
14:13:40<dcoutts>as is heap overflow
14:13:48<dcoutts>or an exception thrown from another thread
14:13:56<roconnor>quicksilver: I keep encountering things which are both outside and inside.
14:14:02<fasta>So, can I happily continue the complete program despite the stack overflow?
14:14:25<dcoutts>fasta: you can catch it in some outside exception handler in IO
14:14:31<quicksilver>fasta: in general it's hard to tell "how far things got" before the overflow
14:14:38<roconnor>fasta: doesn't seem so unreasonable. The entire IO action is aborted, stack is cleaned up, everyone is happy.
14:14:41<quicksilver>fasta: but if you don't care, then you can continue
14:14:55<quicksilver>if you do care, then you hace to implement some kind of 'checkpointing' into IORef/Mvar
14:14:59<quicksilver>or similar
14:15:12<dcoutts>fasta: ghci catches does exactly that for example.
14:15:29<dcoutts>it catches all exceptions, prints them and goes back to the read/eval loop
14:15:31<roconnor>well, the IO action is aborted baddly. Side-effects stay.
14:15:36<fasta>quicksilver: The application is that I do a thousand "tasks" and I either want to know how long the took or whether they failed.
14:15:46<quicksilver>roconnor: "aborted" rather than "rolled back"
14:15:50<quicksilver>fasta: yes, that should be fine
14:15:53<fasta>quicksilver: but I don't want to babysit the machine, so it seems like it should work
14:16:05<fasta>they*
14:16:10<quicksilver>fasta: but if some of the tasks have IO side-effects, it is possible that the failed ones caused partial side-effects
14:16:17<dcoutts>quicksilver: though if you use bracket carefully you could arrange to roll things back explicitly
14:16:25<quicksilver>dcoutts: absolutely
14:16:26<dcoutts>eg deleting temp files etc etc
14:16:35<fasta>quicksilver: the tasks only have side-effects at the beginning
14:16:37<quicksilver>dcoutts: but the dfault behaviour alone doesn't do that :)
14:16:41<dcoutts>yes
14:16:42<quicksilver>fasta: then it should be quite fin
14:16:51<quicksilver>fasta: see sjanssen's earlier post about futures
14:16:54<fasta>quicksilver: which are guaranteed to be completed before a stack overflow can occur.
14:17:17<fasta>quicksilver: I am not subscribed anymore, since there was too much noise.
14:17:41<fasta>I do check the archives occasionally, but I used to read everything
14:17:44<wsdo_okadr>I would like to ask regarding Context-Dependent grammars
14:17:55<wsdo_okadr>for example I read in some textbook I have(wich I find pretty good that)
14:18:08<wsdo_okadr>LR1={wcw | w in (0,1)*}
14:18:11<wsdo_okadr>wich is quite ok
14:18:14<wsdo_okadr>but c is not quite defined
14:18:33<fasta>And Google isn't what it used to be either.
14:18:35<wsdo_okadr>I have a hunch it's some context
14:18:57<wsdo_okadr>but What is it more exactly ?
14:19:21<fasta>wsdo_okadr: it seems some constant expression
14:19:21<wsdo_okadr>(0,1)* I know that is the freegroup generated by 2 elements(0 and 1 in this case)
14:19:50<wsdo_okadr>all sequences of 0 and 1 that have at some point a constant
14:20:06<fasta>wsdo_okadr: you should complain to whoever gave you that book :)
14:20:39<mrd>not quite. it has to be the same sequence of 0s and 1s on either side of c
14:20:50<mrd>what you described is regular
14:21:53<glen_quagmire>hai my name is lolcatz i here to conquore
14:23:00<wsdo_okadr>mrd: yes you're right,I wasn't paying enough attention
14:23:29<wsdo_okadr>What is usually understood by |w| where w is some word generated by {0,1} ?
14:23:35<wsdo_okadr>in the context of formal languages
14:23:50<wsdo_okadr>I forgot it was written at the start of the book.
14:25:20<quicksilver>fasta: I actually meant h paste post :)
14:25:26<quicksilver>fasta: he said something here about it
14:25:31<quicksilver>fasta: I'll find it for you
14:25:39<fasta>quicksilver: oh, so Google is still fine ;)
14:26:00<quicksilver>fasta: http://hpaste.org/3299
14:26:03<kosmikus>ndm: well, I was a bit irritated about System.FilePath docs mentioning isDrive etc., but not exporting the functions
14:26:08<quicksilver>fasta: the thid annotation
14:26:14<kosmikus>ndm: but I found out that they're only exported by the Windows version
14:26:19<quicksilver>fasta: note that it has the exceptions in the type
14:26:28<kosmikus>ndm: do you happen to know what System.Info.os reports for a Windows system?
14:28:03<fasta>quicksilver: I don't see the significance of that, but I do something very similar already.
14:28:25<fasta>quicksilver: I adapted the "compete" function from the wiki.
14:29:07<quicksilver>the significance was that it caught all exceptions
14:29:13<quicksilver>including, presumably, stack overflows
14:29:19<quicksilver>and turned them into exception values
14:30:18<fasta>@type try
14:30:20<lambdabot>Not in scope: `try'
14:33:52<fasta>quicksilver: I suppose the significance is that other languages have builtin "futures" and in Haskell you can build them yourself, since otherwise this is isomorphic to what I did.
14:34:51<quicksilver>fasta: fair enough
14:36:48<fasta>quicksilver: but after a stack overflow, have I lost the rest of the control stack?
14:37:10<quicksilver>I don't know how threads and stack overflows inter-relate
14:37:13<fasta>Can I protect a part somehow?
14:37:16<quicksilver>I'd hope it was thread local but I'm not sure
14:37:23<dcoutts>fasta: it's really just like any other exception
14:37:38<dcoutts>fasta: you can use catch, bracket etc etc
14:37:50<fasta>dcoutts: ok, so it only destroys everything up to the point of the IO action that started the mess?
14:38:17<dcoutts>fasta: catch is a wrapper round a computation, so you don't get the result of the computation, you get the exception instead
14:38:52<fasta>dcoutts: ok, nice.
14:39:16<ndm>kosmikus: "mingw32"
14:39:18<fasta>"stack overflow" seemed to indicate that it overwrote the start of the stack somehow.
14:39:38<fasta>But I guess the implementors are not that stupid ;)
14:39:41<quicksilver>no, just that the stack ran out of the space it decided to allocate for it
14:39:54<roconnor>I think the stack allocator knows how much space is available.
14:39:54<quicksilver>haskell has a checked stack, in other words
14:40:01<ndm>kosmikus: which is pure evil, of course
14:40:17<roconnor>ndm: so that is why haskell is slow ;)
14:40:37<ndm>roconnor: ?
14:40:41<ndm>evil /= slow
14:41:01<roconnor>ndm: oh, why is a checked stack evil if not because it is slow?
14:41:11<roconnor>ndm: woops
14:41:16<roconnor>you are responding to kosmikus
14:41:19<fasta>When I use the xc feature, I still get a "stack trace", although I catched the exception.
14:41:19<roconnor>my bad
14:41:25<ndm>roconnor: oh, yeah, stack overflow is evil because of slowness
14:41:37<ndm>roconnor: but heap checks are much more easy to remove, and just as slow
14:41:50<roconnor>AFAIK, only prim-ops use the stack.
14:42:00<roconnor>but I sort of think I might be wrong.
14:42:12<fasta>I find it odd that I get stack overflow, though. I was expecting to run out of heap space, but I guess the two compete for the same memory at some point.
14:42:26<ndm>roconnor: its the Haskell stack, not the C stack
14:42:51<ndm>fasta: stack overflow really does mean stack overflow, not because of heap pressure
14:42:54<roconnor>ndm: yeah, but I thought GHC used the heap for everything other than + and *.
14:43:03<wsdo_okadr>hi ndm
14:43:06<wsdo_okadr>ndm: nice to see you :)
14:43:20<ndm>roconnor: it has a separate stack (which is on the C heap)
14:43:26<ndm>hi wsdo_okadr - have we met?
14:43:33<roconnor>ndm: really?
14:43:38<roconnor>ndm: what gets pushed?
14:43:44<kosmikus>ndm: I see, thanks
14:43:47<ndm>roconnor: yes, parameters to functions
14:44:11<roconnor>ndm: really?
14:44:15<ndm>roconnor: really :)
14:44:28<ndm>(with about 85% confidence)
14:44:37<roconnor>I figured it would just change focus on a graph when ``entering'' a function
14:44:52<ndm>its not really a graph reduction machine at its heart
14:44:55<roconnor>I should go reread how a G-machine works.
14:45:00<ndm>by the time its been converted to CMM etc
14:45:06<roconnor>ndm: oh
14:45:25<ndm>its kinda graph reduction, but the actually gritty details don't look much like it by the end
14:45:27<roconnor>does CMM have a stack?
14:45:42<quicksilver>In general I don't think it will push a new parameter reference on the stack if there is still one reachable
14:45:43<ndm>yes, but GHC creates its own "stack" in the CMM heap
14:45:49<quicksilver>will means it has to do it 'sometimes'
14:45:56<quicksilver>but not always. I think.
14:46:02<roconnor>ndm: interesting
14:46:17<roconnor>ndm: can you make an example of a stack overflow without using primops?
14:46:34<quicksilver>foldl' (+) 0 [1..]
14:46:44<roconnor>isn't (+) a primop?
14:46:44<quicksilver>the fact that might use primops is not relevant
14:46:49<quicksilver>use Integer if you like
14:46:52<quicksilver>or a custom Num instance
14:47:09<quicksilver>it's a stack overflow however (+) is written
14:47:18<quicksilver>as long as (+) is strict in both parameters
14:47:23<roconnor>quicksilver: you are claiming that will give a stack overflow even on Data Nat = Zero | Succ Nat ?
14:47:37<roconnor>quicksilver: ah right, no primops and no seq.
14:47:47<quicksilver>"as long as (+) is strict in both parameters"
14:47:48<roconnor>even still, I'll try your example.
14:47:52<quicksilver>you don't need to use seq to be strict
14:47:58<quicksilver>some things just are strict...
14:48:18<quicksilver>actually (+) only needs to be strict on one side but I was too lazy to work out which
14:48:24<quicksilver>the point is, you build up an infinite thunk
14:48:29<quicksilver>and infinite thunks are a stack overflow
14:48:43<wsdo_okadr>ndm: yesterday
14:49:07<wsdo_okadr>wsdo_okadr: I read hughes article on FP and came here to talk about it
14:50:17<ndm>ah, i remember
14:50:22<ndm>under a different username?
14:50:26<roconnor>quicksilver: stack overflows, not heap overflows?
14:51:31<quicksilver>roconnor: yes
14:51:40<quicksilver>roconnor: infinite thunks are stack overflows
14:59:40<Tac-Tics>I imagine *thunk* is the sound a thunk actually makes when it gets evaluated in Haskell
15:00:06<roconnor>quicksilver: I get heap exhausted
15:00:12<roconnor>@paste
15:00:13<lambdabot>Haskell pastebin: http://hpaste.org/new
15:00:45<hpaste> roconnor pasted "attempt to stack overflow" at http://hpaste.org/3300
15:00:55<ndm>LeCamarade: just finished reading your "C sucks" article
15:01:10<hpaste> roconnor annotated "attempt to stack overflow" with "Result: Heap exhausted" at http://hpaste.org/3300#a1
15:01:17<Saizan>roconnor: i think you need foldr to stack overflow
15:01:17<ndm>i love the qwe123 quote :)
15:01:26<Saizan>> foldr (+) 0 [1..]
15:01:29<lambdabot> Exception: stack overflow
15:02:09<roconnor>Saizan: I get a screen full of Succs, and then the same heap exhausted error.
15:02:21<fasta>Can this cause a stack overflow? f x = maybe (return x) (\k -> f k) (foo x)
15:02:22<roconnor>Saizan: the goal is to generate a stack overflow without using a prim-op
15:02:52<Saizan>roconnor: ah well, define (+) to pattern match on the right
15:03:06<quicksilver>roconnor: but you have a lazy (+)
15:03:08<fasta>I am currently assuming that that runs in constant space.
15:03:14<quicksilver>I'm talking about a strict (+)
15:03:15<roconnor>Saizan: will foldr (flip (+)) work fo you?
15:03:23<fasta>(as an iterative recursive process)
15:03:30<roconnor>quicksilver: how would you like me to make it strict?
15:03:42<quicksilver>not use the peano numbers?
15:03:56<quicksilver>you seem to be drawing a fallacious link between strict and primops?
15:04:05<Saizan>roconnor: it should, still heap overflow?
15:04:06<quicksilver>ok, Int is strict, and Int has primops
15:04:09<roconnor>quicksilver: if I don't use peano numbers, I have to use a primop ... which is my point: only prim-ops cause stack overflows.
15:04:10<quicksilver>but that's not the point :)
15:04:16<quicksilver>no, that's not true
15:04:25<quicksilver>a type can be strict and not primop
15:04:37<roconnor>quicksilver: fine, how do I make it strict?
15:05:11<roconnor>and not use primops
15:06:28<roconnor>Saizan: foldr (flip (+)) still gives me a heap exhausted error.
15:07:29<roconnor>I don't see how to make any operatation strict without using either a primop or perhaps using DeepSeq.
15:09:04<roconnor>ah, got it!
15:09:12<roconnor>foldr (++) [] (repeat ([]::[()]))
15:09:19<roconnor>stack overflow!
15:09:22<roconnor>w00t
15:09:25<roconnor>> foldr (++) [] (repeat ([]::[()]))
15:09:33<tibbe>if B.pack "my constant string" appears somewhere in the middle of an expression will GHC hoist it to the top level as a true constant or will it recompute it every time?
15:09:37<lambdabot> Exception: <<loop>>
15:09:45<tibbe>or will laziness do the trick?
15:09:47<roconnor>WTF!
15:10:08<roconnor>:(
15:10:19<quicksilver>'loop' is essentially a way that ghc can detect certain stack overflow conditions
15:10:22<quicksilver>among other things
15:10:23<roconnor>It gave me a stack overflow on GHC 6.6
15:10:27<quicksilver>obviously it's not guaranteed
15:10:41<roconnor>(to be honest, I was excepting loop)
15:10:46<Saizan>lambdabot: uses -O2
15:11:13<Saizan>?src (++)
15:11:13<quicksilver>tibbe: in principle it will recompute it every time, but I have a feelig there is a rewrite rule for it
15:11:13<lambdabot>(++) [] ys = ys
15:11:13<lambdabot>(++) (x:xs) ys = x : xs ++ ys
15:11:38<quicksilver>tibbe: and because of the rewrite rule, it will only be computed once. Not sure though.
15:11:39<tibbe>quicksilver: ok, I guess I should just check the -dump-simpl
15:11:56<roconnor>-O2 on ghc 6.6 still gives me a stack overflow
15:12:01<quicksilver>roconnor: to answer your question "How do I make a (+) strict without primops" the answer is generally "use case"
15:12:16<quicksilver>roconnor: case is the primitive haskell concept which implements strictness
15:12:22<roconnor>quicksilver: I understand that, but that only puts it in head normal form.
15:12:26<quicksilver>right
15:12:35<roconnor>quicksilver: is that strict enough for you?
15:12:39<quicksilver>but if your type is shallow that is strict enough :)
15:12:46<quicksilver>and in this case, it was enough for []
15:12:53<quicksilver>because of the the way you were using []
15:13:02<quicksilver>which "wasn't very deep"
15:13:28<roconnor>anyhow, I'm moderately happy I got a stack overflow
15:13:36<roconnor>although I'm surprised I don't get loop
15:13:44<roconnor>and I'm suprised lambdabot does get loop
15:13:50<Saizan>?version
15:13:51<lambdabot>lambdabot 4p548, GHC 6.6 (Linux i686 2.66GHz)
15:13:52<lambdabot>darcs get http://www.cse.unsw.edu.au/~dons/lambdabot
15:15:38<quicksilver>I have previously observed odd behaviour with LB
15:15:47<quicksilver>suggesting it might have some non-standard falgs
15:16:28<roconnor>indeed
15:20:17<kosmikus>bringert: thanks a lot for the mail :) looks great!
15:20:59<bringert>kosmikus: you're welcome! Thanks for the typesetting help.
15:21:27<kosmikus>bringert: no problem. good luck for the defense.
15:22:34<bringert>kosmikus: btw, don't you think the font looks a bit weird? I think the glyphs have uneven line width, but noone I've asked seems to be as picky as me. Also, some of the figures are a bit crappy, dot2tex doesn't work that great.
15:23:34<swiert>bringert: are you defending your thesis soon?
15:23:45<bringert>swiert: just my lic thesis
15:23:53<kosmikus>bringert: they look a bit weird, but I assumed that this was beyond your influence
15:23:54<Igloo>lic?
15:24:01<swiert>bringert: ah - ok.
15:24:09<swiert>best of luck though.
15:24:29<SimonRC>hmm
15:24:39<SimonRC>after reading some Haskell' stuff...
15:24:41<swiert>Igloo: licentiate thesis, I think.
15:24:51<kosmikus>bringert: looks a bit like the file has been generated with PS3 fonts at a specific resolution and then been scaled.
15:25:12<SimonRC>has a solution to the problem with MonadWriter and associated types been fixed?
15:25:20<SimonRC>*found
15:25:53<SimonRC>(there is nowhere to put the Monoid restriction in the associated types syntax)
15:25:56<swiert>Igloo: It's a milestone in a Swedish PhD after 2/3 years.
15:26:35<Igloo>Ah, OK, thanks
15:27:51<bringert>kosmikus: could it have anything to do with how I generted the PDF? I use T1 and lmodern, and pdflatex without any options. Or is it the printer who messed up?
15:28:08<bringert>Igloo: yeah, what swiert said
15:28:37<kosmikus>bringert: lmodern should be safe
15:29:03<kosmikus>are you printing A4 and scaling later?
15:33:12<roconnor>> foldr const () (repeat ())
15:33:14<lambdabot> ()
15:33:31<roconnor>> foldr (flip const) () (repeat ())
15:33:32<lambdabot> Exception: <<loop>>
15:34:27<roconnor>:/
15:34:43<Tac-Tics>> repeat ()
15:34:45<lambdabot> [(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),...
15:35:15<puusorsa>this seems interesting, http://hpaste.org/3299 , could someone help me a bit in figuring out how to use it? :)
15:35:17<wsdo_okadr>> repeat ( repeat () )
15:35:19<lambdabot> [[(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),()...
15:35:34<wsdo_okadr>> let a ()
15:35:34<lambdabot> Parse error
15:35:36<wsdo_okadr>> let a = ()
15:35:36<lambdabot> Parse error
15:35:51<roconnor>> let a = () in a
15:35:53<lambdabot> ()
15:35:57<wsdo_okadr>roconnor: why in a ?
15:35:59<puusorsa>i thought mkFuture readLine would return something that could be fed to askFuture
15:36:13<wsdo_okadr>> let a = () in a; repeat ();
15:36:13<lambdabot> Parse error
15:36:24<wsdo_okadr>how can I write multiple lines ?
15:36:29<wsdo_okadr>for the lambdabot
15:36:34<roconnor>wsdo_okadr: let in declares local variables for some expression
15:36:54<wsdo_okadr>I want to write MULTIPLE LINES :)
15:37:08<roconnor>wsdo_okadr: lambdabot only accepts one expession.
15:37:16<chessguy>wsdo_okadr, the multiple lines you wrote don't make sense
15:37:31<roconnor>same way the top level print-eval-loop does.
15:37:38<roconnor>er
15:37:40<roconnor>bad example
15:37:54<roconnor>ACTION forgot about the other let expression
15:38:05<roconnor>wsdo_okadr: there are two let expressions in Haskell
15:38:07<chessguy>> let a = () in {a; repeat () }
15:38:07<lambdabot> Parse error
15:38:15<quicksilver>puusorsa: it does for some values of 'fed'
15:38:19<chessguy>> let a = () { a; repeat () }
15:38:20<lambdabot> Parse error
15:38:29<roconnor>wsdo_okadr: one let expression works on expression, the other let works inside do blocks.
15:38:30<quicksilver>puusorsa: you have to 'feed' it via >>= since they are monadic actions
15:39:00<puusorsa>oh of course silly me. thanks.
15:39:10<roconnor>GHCi's top level print-eval-loop is much like being inside a do expression
15:39:27<roconnor>so GHCi's lets at the prompt are the let's that go inside do
15:39:41<roconnor>however lambdabot does't work inside the IO monad
15:39:59<roconnor>so the let expression you give are the other kind.
15:40:18<roconnor>(except when you give lambdabot a let statement inside a do expression)
15:40:26<bringert>kosmikus: the pdf is A4 (http://www.cs.chalmers.se/~bringert/publ/lic/lic.pdf), and it think it's just cut to G5 (swedish paper size, 169 x 239 mm, often used for dissertations)
15:40:34<bringert>s/it/I/
15:41:03<roconnor>but in that case lambda bot is given something like do { let a = (); return a} , with an explicit do.
15:42:38<kosmikus>bringert: so it's cut, but not scaled? then I have no idea what went wrong. so if you print the file on your own printer, it also looks like that?
15:43:00<bringert>kosmikus: no, as far as I remember
15:44:36<shapr>@quote
15:44:36<lambdabot>spj says: it looks like hopscotch! (referring to a funny notation for lists)
15:44:38<shapr>w00!
15:44:39<bringert>kosmikus: even if it was scaled down, why would it look like that, unless they use some very crappy scaling or scale by a large factor?
15:44:41<shapr>@quote bringert
15:44:42<lambdabot>bringert says: psicho: so you are saying that your teacher gave you two days to do an assignment in a language you didn't know?
15:45:24<kosmikus>bringert: crappy scaling would be enough, even by a small factor
15:45:35<shapr>Sounds quotable
15:46:23<kosmikus>shapr: what are you doing these days?
15:46:50<shapr>kosmikus: Hacking on HAppS, trying to get back into the Haskell community, considering getting a CS degree. What about you?
15:46:53<bringert>kosmikus: ok, thanks. I'll have someone else print my phd thesis.
15:47:04<dons>?yow!
15:47:04<lambdabot>Can you MAIL a BEAN CAKE?
15:47:14<bringert>shapr: when are you moving back to sweden?
15:47:38<bringert>hey dons, did you say that you have a small http implemenation we could embed in cabal-install?
15:47:40<shapr>bringert: I'm not. Min flickvänn har slutat vår relation.
15:47:50<bringert>shapr: crap
15:47:53<dons>bringert: ah yes. i do.
15:48:04<exDM69>I was reading YAHT last night, and I almost figured out how the IO monad works.
15:48:12<shapr>bringert: Yeah, that happened a month ago, and I'm still recovering.
15:48:12<dons>its in the link checker i uploaded to hackage a few months ago
15:48:20<dons>exDM69: sweet :)
15:48:27<exDM69>I still didn't quite get what do's and sequencing was about, but I guess I'll figure it out if I try it
15:48:27<dons>welcome!
15:48:30<bringert>shapr: how is it doing?
15:48:36<shapr>ACTION shrugs
15:48:41<dons>?undo do x <- getChar ; y <- getChar ; print (x,y)
15:48:41<lambdabot>(getChar >>= \ x -> getChar >>= \ y -> print (x, y))
15:48:52<kosmikus>bringert: so you don't have the university print it for you?
15:48:55<dons>>>= sequences things by gluing them in a lovely dependency order
15:49:10<exDM69>I just don't have an intresting idea for a Haskell project. (or in fact, any project)
15:49:17<kosmikus>shapr: sounds good. I'm back in Utrecht, have you heard?
15:49:21<shapr>No, I didn't know that!
15:49:27<dons>exDM69: you could contribute to an existing project, perhaps?
15:49:32<dons>seen xmonad, for example?
15:49:33<shapr>Are you there for the long term?
15:49:37<dons>lots of space there to add code
15:49:40<exDM69>dons: I don't think I have the skills yet
15:49:56<kosmikus>shapr: I have a position for 5 years. Let's see what happens.
15:49:56<dons>you never know till you try :)
15:50:01<exDM69>dons: and Xmonad is not exactly my brand of vodka
15:50:09<dons>if you're looking for small tasks, you could try the 99 haskell questions quiz on the wiki
15:50:09<shapr>dons: Looking at the people locations for AmeroHaskell, the most central location appears to be Portland, think we could find a venue?
15:50:12<exDM69>dons: I was thinking of writing a card game
15:50:18<dons>shapr: definitely
15:50:21<dons>shapr: PSU could do it
15:50:26<exDM69>dons: there is this one card game that has particularly intresting algorithms
15:50:27<kosmikus>dons, exDM69: then let's write Xapplicativefunctor ;)
15:50:33<dons>kosmikus: :)
15:50:37<dons>conal would love that
15:50:45<dons>kosmikus: actually, i'm looking to move more code out of the X monad
15:50:58<dons>user code, for example, should run in a very constrained Reader environment
15:51:29<kosmikus>dons: sounds good; so that users cannot easily mess up everything?
15:51:34<dons>right
15:51:41<dons>we don't really want them calling into the X server
15:51:45<shapr>dons: Ok, sounds like a plan.
15:51:46<dons>or messing up the core's internal state
15:51:53<kosmikus>dons: oh, you've released 0.4, right?
15:51:53<exDM69>dons: hey, nice. I'll try to check out the wiki.
15:51:55<dons>shapr: ok, let's set up a mailing list to sort this out
15:51:58<dons>kosmikus: later today
15:52:00<kosmikus>ACTION should probably upgrade again
15:52:01<dons>the release candidate is out
15:52:08<kosmikus>what's new?
15:52:30<dons>rules, so that you can set behaviour for particular clients: e.g. gimp always floats, or mplayer goes on workspace 2
15:52:32<quicksilver>shapr: that's got to be a weird distribution to make portland central?
15:52:40<dons>hmm, a gazillion new extensions. gnome support
15:52:43<quicksilver>shapr: lots of developers in alaska shifting the centre of gravity that way?
15:52:50<kosmikus>dons: great.
15:53:01<kosmikus>but actually, I don't really find much I'd want from xmonad.
15:53:07<kosmikus>it just works.
15:53:13<dons>yeah, that's good to know
15:53:18<shapr>quicksilver: Mostly that Oregon and California have the most Haskellers. There's roughly ten Haskellers outside of OR & CA.
15:54:11<dons>shapr: if you can set up a list, i can start looking for local interest
15:54:17<kosmikus>oh, it's HCAR time again.
15:54:20<shapr>dons: Awright
15:54:21<dons>also, portland's close enough to .ca we might attract Cale down :)
15:54:26<shapr>Yeah, that would be cool :-)
15:54:28<kosmikus>ACTION makes a note to send out a call for contributions.
15:54:42<dons>kosmikus: scary. i can't imagine how we can keep track of everything new any more
15:54:49<kosmikus>dons: hehe
15:55:01<kosmikus>all the more important to have a report on it ;)
15:55:01<dons>i can send you the weekly news announcements since the last hcar, if you like
15:55:10<kosmikus>maybe
15:55:19<kosmikus>I'll first look through my own archives
15:55:22<dons>yep
15:55:37<kosmikus>oh, btw, I'm looking for a new editor :)
15:55:42<kosmikus>this will be the last HCAR I do
15:55:56<ndm>kosmikus: again? seems very recently the last one went round...
15:56:06<kosmikus>ndm: 6 months
15:56:11<kosmikus>it's always been like that
15:56:13<ndm>yeah, doesn't feel like it!
15:56:19<dons>been a busy 6 months
15:56:25<kosmikus>May and November
15:56:28<ndm>indeed
15:56:37<ndm>haven't been home for the last month, pretty much
15:56:46<dons>ACTION off to work to hammer out some more lambdas
15:56:48<kosmikus>so, if you guys know anyone who might be interested/suitable for becoming HCAR editor, please tell me
15:57:08<LeCamarade>dons: Wait!
15:57:09<shapr>dons: I'll mail you about the list
15:57:15<dons>LeCamarade: quick!
15:57:15<kosmikus>I'll send out an announcement together with the release of this HCAR that I'm going to step down
15:57:23<dons>kosmikus: hmm, i'll see if i can think of someone
15:57:26<LeCamarade>See? Damn Galois! Dem a go take away our channel friends!
15:57:29<LeCamarade>:o(
15:57:37<kosmikus>it would be a shame if it wouldn't be continued though, I think
15:57:45<dons>kosmikus: need to identify some promising phd student with a few years available
15:57:48<LeCamarade>dons: Just wanted to congratulate you on the talk - it was a concert!
15:57:52<LeCamarade>:o)
15:57:56<dons>hah :)
15:57:57<dons>thanks.
15:58:00<exDM69>dons: http://www.korttipelit.net/Kasino_in_English.htm <<-- this is the one I thaught of doing in Haskell
15:58:03<lambdabot>Title: Kasino
15:58:03<kosmikus>dons: yes, a PhD student would be good.
15:58:06<shapr>LeCamarade: They also fund our channel friends. It'd suck if they all had to start writing Java for a living.
15:58:16<LeCamarade>We should draw up tour dates for the Lambda band. SPJ and the Wailer.
15:58:30<shapr>SPJ and the Redexes?
15:58:34<dons>kosmikus: there's a bunch of guys at chalmers. and some new guys at utrecth (alexey perhaps?)
15:58:41<dons>kosmikus: people who came to the hackathon might be possibles..
15:59:00<kosmikus>dons: yes, you can be sure that I'll ask around here in Utrecht.
15:59:06<dons>:)
15:59:07<LeCamarade>dons: But why do you people say IPI instead of API? :o)
15:59:09<byorgey>hm, I don't think Cale's particular slice of .ca is very close to Portland =)
15:59:21<LeCamarade>Okay. You're pardoned. You may rise.
15:59:22<dons>LeCamarade: :P I don't! your ears are broken, mate.
15:59:32<LeCamarade>That came out as mite!
15:59:38<LeCamarade>`mite'
15:59:40<dons>streuth
15:59:48<LeCamarade>pweaver. Another Galois guy.
15:59:56<kosmikus>ACTION &
16:00:00<dons>oh, huh. phil's here. cool
16:00:13<dons>you should all say hi next time -- he's super interesting.
16:00:16<exDM69>btw, how should I do random shuffling for a list (or array) in Haskell?
16:00:19<shapr>@seen pweaver
16:00:19<lambdabot>I saw pweaver leaving #haskell 36s ago, and .
16:00:33<shapr>hi pweaver! I hear you're interesting.
16:00:39<dons>exDM69: there's a new wiki article on haskell.org about random shuffling
16:00:47<dons>exDM69: check the 'Recent changes' page from the front page
16:00:54<dons>hey pweaver :)
16:00:57<pweaver>?
16:01:00<dons>how's the serial port hacking going?
16:01:11<pweaver>how do people know about me, has dons been talking
16:01:17<dons>sssh1
16:01:23<LeCamarade>pweaver: We've been told everything about you, we are dying to hear your side of the story. Is it true you speak in Haskell, and need an interpreter?
16:01:37<exDM69>dons: thanks, I'll check it out
16:01:38<pweaver>it's going well, the new guy Joel found a Haskell module for serial interface for Win32
16:01:49<dons>sweet.
16:01:52<pweaver>...
16:01:52<dons>we should bundle that up nicely
16:01:56<shapr>pweaver: Did you do reflective metaprogramming stuff for Rosetta?
16:01:58<dons>since it keeps coming up on the mailing lists
16:02:01<LeCamarade>ACTION &
16:02:03<pweaver>i think i did :)
16:02:06<dons>shapr: yeah, i think so.
16:02:21<dons>pweaver: do you have a link for that composable monadic semantics magic stuff handy
16:02:26<exDM69>0.o, haskell.org is down
16:02:29<dons>some people here would love to poke around in that, i suspect
16:02:45<shapr>pweaver: That's nifty.
16:02:51<dons>exDM69: huh, just went down it seems.might be back up soonish
16:03:45<pweaver>hmm... i'm not sure
16:03:49<Igloo>It's not down, just very slow
16:03:54<Igloo>Are we being dotted again?
16:04:02<dons>hmm, not that i'm aware of
16:04:09<pweaver>it was only published a week or two ago
16:04:25<pweaver>there's supposed to be an October release of the code
16:04:43<shapr>Haskelldotted!
16:04:59<Igloo>LA is 130
16:05:51<shapr>?
16:05:52<shapr>oh
16:06:44<pweaver>... either dons is invisible at his desk or is chatting from home
16:06:53<pweaver>or i'm not looking at the right desk
16:08:05<dons>i'm at home :) getting some furniture delivered today to our new apartment
16:08:19<pweaver>ah, cool
16:08:23<dons>Igloo: hmm?
16:08:58<Igloo>"hmm?"?
16:09:16<dons>ah, 130 or 1.30?
16:09:21<Igloo>130
16:09:23<dons>load avg?
16:09:26<Igloo>Yup
16:09:28<dons>crap
16:09:51<Igloo>It's fallen to 90 now, so whatever it was might be over
16:10:37<bringert>dons: I had a quick look at that yesterday, I can't see that it gets the body
16:11:04<bringert>dons: but that should be easy to fix
16:11:40<bringert>dons: I guess it could get the body straight to a file
16:12:53<dons>bringert: yeah, it should be easy enough to hack up , to avoid that dependency
16:13:04<dons>and maybe do it in bytestrings at the same time
16:14:06<Igloo>There's no obvious guily page, other than the front page
16:14:28<apfelmus>hi :)
16:14:37<apfelmus>i'm looking for file system semantics
16:14:59<apfelmus>but i'm stumbling in the dark currently
16:15:35<shapr>apfelmus: Did you see Simon Marlow's email about how getContents only works if the file system also has pure FP semantics?
16:15:52<Mortez>omg, how can I resolve ambiguous (-) when trying to make a type an instance of class Num :S I need (-) operator for the fields, but ghci will not understand what I want :(
16:16:14<shapr>apfelmus: It's several months old, but the summary is that lazy file reading only works if the contents of the file do not change between reads.
16:16:21<hpaste> BoudewijnE pasted "SIRDS problem" at http://hpaste.org/3302
16:16:30<boudewijne>can someone help me on an image-generation problem?
16:16:39<boudewijne>I can create images using the code on hpaste
16:16:52<apfelmus>shapr: no, i didn't see it. link?
16:16:52<boudewijne>but they have a 'line' through them
16:17:49<shapr>apfelmus: http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/4759 & http://permalink.gmane.org/gmane.comp.lang.haskell.libraries/4761
16:17:50<lambdabot>Title: gmane.comp.lang.haskell.libraries
16:18:01<Dybber>Why is maximum not tail-recursive? I get stack overflow when finding maximum of a list with 1 mio items
16:18:09<shapr>apfelmus: It was on my blog, but my blog does not exist anymore.
16:18:18<apfelmus>:'(
16:18:44<shapr>I'll make a new blog when HAppS-Begin is usable for that purpose.
16:19:06<Igloo>:-)
16:19:15<Dybber>>maximum [1..1000000]
16:19:28<apfelmus>actually, i was more interested in the usual POSIX semantics
16:19:41<apfelmus>how to do atomic file write and stuff?
16:19:51<boudewijne>can someone please help me?
16:19:54<shapr>apfelmus: Have you seen http://www.haskell.org/halfs/ ?
16:19:54<lambdabot>Title: Halfs, A Haskell Filesystem
16:20:05<shapr>@where halfs
16:20:05<lambdabot>http://www.haskell.org/halfs
16:20:46<byorgey>Mortez: maybe paste the code you are having trouble with on hpaste?
16:20:47<pgavin>@src Bounded
16:20:47<lambdabot>class Bounded a where
16:20:47<lambdabot> minBound, maxBound :: a
16:21:06<byorgey>Dybber: the problem isn't that maximum isn't tail recursive, it's that it isn't strict enough.
16:21:48<byorgey>Dybber: use foldl1' max instead.
16:21:50<dons>Igloo: i note the page count for the front page has jumped by about 10k since yesterday
16:21:58<byorgey>> maximum [1..1000000]
16:22:00<lambdabot> 1000000
16:22:00<dons>its over the 900k mark now
16:22:10<byorgey>well, that works anyway since lambdabot uses -O2.
16:22:37<byorgey>> foldl1' max [1..1000000]
16:22:39<lambdabot> 1000000
16:22:57<Igloo>dons: Do you know if that's faster than normal?
16:22:58<dons>apfelmus: seen Oleg's zipper file system paper?
16:23:00<Dybber>byorgey, what do you mean that it "isnt strict enough"?
16:23:12<dons>Igloo: yes, way faster. typically we see 1-2k per day on the front page
16:23:27<apfelmus>ACTION saw it all ;)
16:23:30<dons>i suspect a lot of that 10k came in the past hour, since i don't recall it being over 900k earlier
16:23:37<shapr>Sounds it'd be interesting to see the referrers for the past 24 hours.
16:23:54<Igloo>dons: The only easy fix I have is to make it static. It would be great if someone could look properly at making the wiki more resilient to lots of hits
16:24:02<apfelmus>i mean, i'm not (yet) looking for a new fp-filesystem
16:24:08<dons>hmm, the front page really could be static
16:24:10<fasta>I get the stack overflow during unsafeFreeze
16:24:21<fasta>I thought that was a noop.
16:24:22<apfelmus>just how exactly the "normal" filesystem on my box handles concurrency
16:24:29<Dybber>I thought the stack exception was because of to many recursive calls
16:24:40<Igloo>dons: It has the events and news on
16:24:50<dons>Igloo: but those are static
16:24:54<quicksilver>Igloo: there are well-known solutions to that sort of thing
16:24:57<dons>you have to 'flush' to get the front page regenerated
16:25:01<Igloo>And it would also look like you weren't logged in
16:25:12<apfelmus>are files locked when two processes try to read them? to write them?
16:25:13<quicksilver>Igloo: mostly they involve putting a mostly-transparent proxy in front
16:25:16<byorgey>Dybber: the important point is that Haskell is lazy, i.e. expressions do not have to be evaluated until their results are needed.
16:25:18<Igloo>quicksilver: I know, but we need someone to find a good one and apply it to haskell.org's wiki
16:25:29<quicksilver>apfelmus: on unix-style systems, there is no locking by default
16:25:39<quicksilver>apfelmus: on win32-style systems, there is crude pessimistic locking by default
16:26:08<byorgey>Dybber: so, a call like maximum [1..1000000] might end up as the (yet unevaluated) expression, max 1 (max 2 (max 3 (max 4 ...
16:26:27<apfelmus>quicksilver: so, it's nondeterministic on unix?
16:26:27<byorgey>Dybber: then, when the result is finally needed, that huge expression will be evaluated, which will cause a stack overflow.
16:26:36<Dybber>foldr1 max [1..1000000] is also giving stack overflow. My own tail recursive version doesn't
16:26:42<Igloo>The Haskell98 file operations impose single-writer-or-multiple-reader locks, IIRC
16:26:45<Dybber>byorgey, ok
16:26:54<quicksilver>apfelmus: in some sense, yes. The affect of two proceses concurrently modifying the same file is subject to the whims of the kernel scheduler
16:26:59<Igloo>s/operations/functions/
16:27:17<quicksilver>apfelmus: in practice however this is a very useful thing to be able to do, and processes choose whatever locking discipline suits them best
16:27:23<byorgey>Dybber: it's possible that your own version doesn't overflow not because it is tail recursive per se, but because the compiler was able to figure out some optimization that it couldn't with maximum.
16:27:37<byorgey>Dybber: tail recursion is much less important in a lazy language like Haskell.
16:27:47<fasta>Can unsafeFreeze handle negative indices?
16:27:50<Igloo>dons: Where is the hit counter?
16:27:56<byorgey>Dybber: I'd point you to an excellent page discussing this and related issues on the wiki, but it appears to be very slow at the moment...
16:28:05<apfelmus>quicksilver: ah. so, there is a separate mechanism for locking files? (i'm a unix n00b)
16:28:24<dons>Igloo: when you're logged in, there's one at the bottom of each page (in my style, anyway), and on the special pages
16:28:30<dons>click on 'popularity'
16:29:11<Tac-Tics>byorgey: why is tail recursion less important?
16:29:19<Dybber>byorgey, ok thanks, i dont really know how the lazyness is implemented, could be fun to look into.
16:29:43<Igloo>ACTION logs in, but finds no counter or popularity
16:30:22<dons>Igloo: hmm, maybe its only in text mode browsers.. ?
16:30:24<bringert>dons: would you have time to hack cabal-install to use your http module?
16:30:32<apfelmus>quicksilver: i mean, i basically ponder the implementation of a wiki with flat files storage and want to get the concurrency right.
16:30:38<Igloo>Ah, it's just not in the default skin
16:30:43<dons>bringert: possibly, during this week
16:30:46<dons>Igloo: ah yes
16:31:01<dons>Igloo: http://haskell.org/haskellwiki/Special:Popularpages
16:31:02<lambdabot>Title: Popular pages - HaskellWiki
16:31:28<hpaste> Mortez pasted "Help on resolving ambiguity.." at http://hpaste.org/3303
16:31:35<Igloo>dons: Ah, is there a Popularinthelast24hours?
16:31:53<bringert>dons: great. I'm using my minial spare time to work on various other parts, like installing local packages, install directories and verbosity
16:31:54<Igloo>Or 1 hour, or anything?
16:32:09<dons>bringert: yeah, verbosity is one thing.
16:32:24<byorgey>Tac-Tics: for several reasons. First of all, even with a tail-recursive function you can still get stack overflows due to too much laziness.
16:32:26<dons>so i might look at the http stuff
16:32:39<dons>Igloo: not that i know of, but maybe someone else is more familiar with mediawiki admin
16:32:51<dons>Igloo: glguy might know, if he logs in soon
16:33:04<Igloo>OK, ta
16:33:15<Igloo>Anyway, I have http://www.haskell.org/static/Haskell.html ready if we have problems again
16:33:15<lambdabot>Title: Haskell - HaskellWiki
16:33:20<byorgey>Tac-Tics: and from the other angle, sometimes laziness creates opportunities for efficiency even in non-tail-recursive functions that would be inefficient in a strict language.
16:33:22<bringert>dons: 'cabal install' can now install the package in the current dir btw, like your cbi
16:33:26<quicksilver>apfelmus: if everything that accesses the file is using haskell, I believe you may be safe already
16:33:27<dons>cool
16:33:32<byorgey>Tac-Tics: although I can't think of an example off the top of my head.
16:33:45<apfelmus>quicksilver: oh?
16:33:51<ddarius>byorgey: concat
16:33:52<bringert>dons: it doesn't install in /usr/local even with --global, but I'm fixing that now
16:33:59<ddarius>byorgey: In fact any usage of foldr
16:34:15<dons>bringert: ah right, but --user should use --prefix=$HOME by default?
16:34:22<dons>(that's an faq on #xmonad)
16:34:54<byorgey>ddarius: oh right, thanks
16:35:04<bringert>dons: it uses $HOME/.cabal now
16:35:10<ddarius>ACTION wonders how dons got 'an'; 'an' eff ay que ?
16:35:11<apfelmus>quicksilver: ah, "Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files"
16:35:17<byorgey>Dybber: here's the page I was referring to, I think you'll probably find it enlightening: http://www.haskell.org/haskellwiki/Stack_overflow
16:35:18<lambdabot>Title: Stack overflow - HaskellWiki
16:35:31<apfelmus>quicksilver: what about several Haskell processes?
16:35:47<dons>bringert: right, cool.
16:36:09<Choko_>is there some nice fast way of computing ``n! mod h'' ?
16:36:11<Dybber>byorgey, thanks I will read that
16:36:29<dons>ddarius: faq = "eff ae queue" :)
16:37:13<Mortez>byorgey: http://hpaste.org/3303 haskell just owns me :/
16:37:31<quicksilver>apfelmus: then I suspect you should do your own locking
16:38:27<apfelmus>yeah, i suppose. i don't know how, though, i know next to nothing about posix file operations
16:39:03<quicksilver>I'd be inclined to have a single long-running haskell server
16:39:18<quicksilver>and have the "CGI-scripts" access mediated via the single server
16:39:24<quicksilver>using sockets, I suppose
16:39:35<quicksilver>maybe that's more heavy-weight than you want :(
16:40:13<apfelmus>i think so :(
16:40:43<apfelmus>isn't there a posix function that somehow locks stuff?
16:41:35<ibid>there's advisory locking and (optional) mandatory locking
16:41:36<apfelmus>i mean, the ideal thing would be STM for the file system
16:41:52<apfelmus>ibid: what's that?
16:41:54<ddarius>ACTION tends to pronounce it 'fack'
16:42:10<ibid>in flock(2) and fcntl(2)
16:42:18<ibid>apfelmus: what's which?
16:42:53<ibid>fctntl F_GETLK F_SETLK and F_SETLKW are advisory locking
16:43:33<ibid>ah, could also be mandatory locking if the kernel and the file system support it
16:43:34<kolmodin>I'm a lambdabot and I'm ok, I hack all night and I surf all day!
16:44:09<apfelmus>ibid: is there any online text/tutorial about that besides the man pages?
16:44:15<dons>kolmodin: :)
16:44:22<hpaste> fasta pasted "Stack overflow minimal case" at http://hpaste.org/3304
16:44:24<ibid>apfelmus: probably. use google :)
16:44:25<quicksilver>a good book on unix systems programming would cover it
16:44:32<ibid>but flock/fcntl locking isn't reliable if you have to support all read-world scenarios
16:44:44<kolmodin>:)
16:44:47<quicksilver>ibid: it's fine if you can assume that only your processses access it
16:44:50<fasta>I create an array with about one million elements; any modern computer should be able to do that.
16:44:59<kolmodin>dons: did my patch work for you on 64bits?
16:45:02<quicksilver>ibid: or, you don't care too badly if some other process screws it up
16:45:09<dons>kolmodin: getting to it. but seems like the right thing
16:45:15<ibid>quicksilver: that's assuming the filesystem implements it
16:45:26<kolmodin>aye. it's what Tim said, but his patch didn't apply any more
16:45:27<ibid>quicksilver: some NFS filesystems, iirc, disregard it completely
16:45:42<quicksilver>hmm that rings a bell
16:45:46<kolmodin>?localtime dons
16:45:46<quicksilver>but I'm not sure you're right
16:45:48<lambdabot>Local time for dons is Mon Oct 15 09:45:46 2007
16:45:51<kolmodin>oo :)
16:45:56<quicksilver>I think they disregard it w.r.t. other clients machines
16:46:08<quicksilver>but for two clients on the same physical machine, it works?
16:46:30<quicksilver>(that is, worst case. Good NFS servers get it right even in the hard case)
16:46:44<ibid>quicksilver: possible
16:47:02<ibid>quicksilver: as i said, if you have to support all real-world scenarios :)
16:48:30<fasta>Why doesn't this work? http://hpaste.org/3304
16:48:36<apfelmus>hm, now i'm scanning google results for an online unix systems tutorial ...
16:49:07<apfelmus>but i just want STM for files. no brain damage, just atomic $ readFile a >>= writeFile b
16:50:21<ibid>apfelmus: you want a transactional file system. there aren't any for unix, as far as i know
16:50:34<ibid>apfelmus: unless you count database engines
16:50:41<apfelmus>that would be fine if i could implement it myself
16:51:02<apfelmus>i mean, the database engines have to do it in some way, too
16:51:26<osfameron>would that be hard to implement efficiently?
16:51:54<osfameron>I mean, would you end up storing a lot of swap files and so on with uncommitted changes? The design must be quite interesting.
16:52:01<apfelmus>i.e. i'm fine with a directory that only my Haskell code can read/write to
16:52:27<astrolabe>fasta: which compiler?
16:52:31<fasta>astrolabe: GHC
16:53:02<astrolabe>fasta: My only guess is that you could increase the stacksize of the run time system.
16:53:14<ibid>osfameron: basically, it's a journaling filesystem done with some care and with a transaction API attached
16:53:19<apfelmus>osfameron: well, i hope i could get away with making STF an applicative functor instead of a full monad
16:53:32<fasta>astrolabe: I don't understand why it would use a lot of stack in the first place.
16:54:14<ibid>osfameron: the basic idea is that all data is written in an append-only journal, and you build (disposable) indexes to speed up access
16:54:21<astrolabe>fasta: The default memory grabbed by the RTS is pretty small if I recall correctly.
16:54:30<fasta>astrolabe: 16MB, IIRC
16:55:01<osfameron>ibid: a bit like a piece table but done at the filesystem basis?
16:55:01<bos>you can easily push that way down. i've run with an initial heap size of 256KB.
16:55:12<ibid>osfameron: no idea what a piece table is
16:55:19<fasta>bos: Why doesn't this work? http://hpaste.org/3304
16:55:31<fasta>bos: that's the problem we are talking about
16:56:01<astrolabe>fasta: Isn't that small? How much room does a Maybe Int take?
16:56:14<osfameron>ibid: it's a way of storing text for a text-editor or similar structure. You keep a list of all the "pieces" of text, as indices against a) the original text buffer and b) an appendable buffer of "new" text (insertions/modifications or appends)
16:56:38<ibid>osfameron: sounds similar
16:56:41<fasta>astrolabe: I don't know exact numbers but it's less than 20 bytes, I think.
16:57:05<fasta>astrolabe: but there's no need to have more than a constant number of elements on the stack
16:57:59<ibid>osfameron: the log basically contains "inode 634 block 4200 was xyz now it is foo, changed by process quux" entries
16:58:33<fasta>Maybe I can reimplement newArray
16:58:38<ibid>osfameron: so it's an undo list, only it's authoritative
16:58:51<osfameron>ibid: sounds interesting, I'll have to read up on it.
16:58:58<osfameron>"authoritative" in what sense ?
17:00:22<ibid>osfameron: think a text editor. you have the editor buffer and you have an undo list. the authoritative version of the data is the edit buffer, and the undo list is just to support the undo feature. in a jornalling design, the editor buffer is just a cache, and the authoritative version of the data is what you can piece together by running through the journal (the undo list)
17:01:08<osfameron>ah ok. Very like a piece table/enfilade.
17:01:12<ibid>osfameron: authoritative in the sense that if it's out of sync with your buffer, it's the buffer that gets thrown out and not the journal
17:01:34<ibid>osfameron: enfilade, the xanadu concept?
17:01:35<osfameron>ibid: I'll read up ta. (Heading off now though... I shouldn't get involved in interesting things at end of day...)
17:01:41<osfameron>see yas
17:01:45<ibid>osfameron: i know that one :) and it's similar yes
17:02:06<osfameron>ibid: yeah, enfilads rock (they're basically like the piece table but with a balanced tree managing the pieces, so more efficient)
17:02:22<ibid>osfameron: i used to collaborate with ted :)
17:02:24<osfameron>ibid: I keep on meaning to get time to write a text editor based on one (in Perl or Haskell)
17:02:37<osfameron>ibid: really! That must have been interesting
17:02:44<hpaste> byorgey annotated "Help on resolving ambiguity.." with "fixed" at http://hpaste.org/3303#a1
17:03:11<ibid>osfameron: it was until ted lost patience with us geeks :)
17:03:23<osfameron>ibid: I'm really interested in discussing enfilades some more at some point if you have time.
17:03:23<byorgey>Mortez: ^^ that should work.
17:03:29<ibid>osfameron: osfameron have a look at http://antti-juhani.kaijanaho.fi/ie/
17:03:31<lambdabot>Title: Ibid's Editor
17:03:42<osfameron>ibid: but right now I'd better go as I promised it's my turn to cook tonight :-)
17:03:56<ibid>(no history support)
17:04:43<osfameron>cool! ((laters))
17:05:11<Mortez>byorgey++
17:08:07<dons>http://programming.reddit.com/info/5yc9f/details :)
17:08:08<lambdabot>Title: programming: Testing your web applications with Haskell
17:09:19<shapr>I like that binding.
17:12:44<bos>fasta: i don't know why you're getting a stack overflow, sorry.
17:12:57<fasta>bos: I think it depends on whether profiling is on or off.
17:13:08<fasta>bos: I just tried it in ghci and there it works.
17:13:22<fasta>bos: when I compile the example program without profiling it also works
17:13:28<bos>fasta: so it works if profiling is off? huh.
17:14:00<fasta>bos: yes, I verified it now
17:20:59<MyCatSchemes>> liftM Char.toUpper "foo bar baz"
17:21:01<lambdabot> "FOO BAR BAZ"
17:21:07<MyCatSchemes>:t liftM
17:21:09<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
17:21:11<MyCatSchemes>:t map
17:21:13<lambdabot>forall a b. (a -> b) -> [a] -> [b]
17:21:23<dmwit>:t liftM `asTypeOf` map
17:21:25<lambdabot>forall a1 r. (a1 -> r) -> [a1] -> [r]
17:21:36<MyCatSchemes>ACTION brainexplode.
17:21:47<MyCatSchemes>dmwit: where the Hell did you get asTypeOf from? That was awesome. :)
17:21:57<dmwit>=)
17:22:09<dmwit>It's a throwback to before type annotations, I gather. =)
17:22:27<mrd>it's in haskell for dealing with things that lexical type variables would do
17:22:52<MyCatSchemes>:t asTypeOf
17:22:52<dmwit>asTypeOf is just a type-restricted const.
17:22:54<lambdabot>forall a. a -> a -> a
17:23:20<MyCatSchemes>@djinn a -> a -> a
17:23:20<lambdabot>f _ a = a
17:23:54<oerjan>@src asTypeOf
17:23:55<lambdabot>asTypeOf = const
17:24:02<oerjan>@src const
17:24:02<lambdabot>const x _ = x
17:24:20<MyCatSchemes>:t liftM `const` map
17:24:22<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
17:24:41<MyCatSchemes>:t map `const` liftM
17:24:41<dmwit>:t (const :: a -> a -> a) liftM map
17:24:43<lambdabot>forall a1 r. (a1 -> r) -> [a1] -> [r]
17:24:44<lambdabot> Ambiguous type variable `m' in the constraint:
17:24:44<lambdabot> `Monad m' arising from use of `liftM' at <interactive>:1:12-16
17:25:07<oerjan>MyCatSchemes: the last argument of const has no effect on the type of the result
17:25:26<MyCatSchemes>oerjan: ah. Is the effect of asTypeOf a hack in the compiler, then?
17:25:32<oerjan>asTypeOf has the same _value_ definition as const, but _not_ the same type
17:25:43<oerjan>no, it simply has a type annotation
17:26:25<fax>good afternoon
17:27:20<MyCatSchemes>oerjan: ahhh, I see. Thank you.
17:27:26<MyCatSchemes>fadec: good evening.
17:27:42<fax>wow
17:27:50<fax>very nice cats
17:27:52<dmwit>fax: Also, good morning.
17:28:38<dmwit>"boxed cat has a uniform representation"
17:28:40<fax>oh geez "catmorphism"
17:28:41<fax>lol
17:30:27<dmwit>KittyT
17:30:47<MyCatSchemes>"Tail recursion", heehee.
17:31:15<dmwit>That one is so cute!
17:33:14<birkenfeld>http://pocoo.org/~gbrandl/monomorph.png :)
17:33:51<liyang2>Oh man. Are we still on the \cats? @_@
17:39:54<liyang2>I'm getting all the jokes apart from `The impossible'. Halp?
17:40:23<Beelsebob>it's getting out the box
17:40:28<dmwit>It looks like the cat's leg is way way long.
17:40:35<dmwit>...impossibly long.
17:40:42<oerjan>it's a ghc error message for compiler bugs, i think
17:40:59<dmwit>liyang2: And one of GHC's famous error messages is "The impossible has happened! Report it." or something like that.
17:41:06<Beelsebob>heh
17:41:11<liyang2>oerjan: I know that much. ^^;
17:41:26<Beelsebob>my personal favorite has to be lazy bitestring
17:41:29<oerjan>liyang2: wasn't sure which part you were not getting :)
17:41:33<liyang2>Beelsebob: guess that makes some sort of sense for me. ^^;
17:42:06<liyang2>maybe it just failed to tickle me on the right parts. ^^;
17:42:16<Beelsebob>someone needs to do an amerous cat, with some comment about playing with IO and my monads
17:42:43<liyang2>ACTION likes olegcat
17:42:56<Beelsebob>it's too much of an in joke
17:43:22<oerjan>they all are
17:43:25<liyang2>Don't kid yourself. The whole site is too much of an in-joke. :p
17:43:37<Beelsebob>yeh... but that one is *too much* of an in joke
17:43:44<Beelsebob>it requires knowledge of the community
17:43:47<Beelsebob>not just the languag
17:43:47<liyang2>ACTION loevs KittehT more
17:43:50<Beelsebob>language*
17:43:59<Beelsebob>yeh, the kittehT rocks
17:44:02<liyang2>And my. simoncat's looking cool.
17:44:36<fax>hehehe
17:44:41<liyang2>Beelsebob: and the compiler, let's not forget. :)
17:44:48<Beelsebob>that too
17:45:22<liyang2>Hang on, did I just say *the* compiler? I didn't mean that. There are other Haskell compilers...
17:45:27<liyang2>(Right guys?)
17:48:20<Spark>there are no haskell compilers
17:48:49<HodriUser-381>selam
17:49:16<dmwit>Hi asd!
17:49:59<dolio>There is no spoon.
17:50:25<dmwit>There is no red pill.
17:50:47<oerjan>Ceci n'est pas un pipe.
17:51:08<oerjan>*une
17:52:21<mrd>someone wrote that on a steam pipe in a building here
17:52:23<mrd>=)
17:52:46<dmwit>"There is no pipe"?
17:52:57<dmwit>?babel fr en ceci n'est pas un pipe
17:52:58<lambdabot> this is not a pipe
17:53:07<Spark>lol, pipe is feminine
17:53:17<mrd>?google magritte ceci n'est pas une pipe
17:53:19<lambdabot>http://en.wikipedia.org/wiki/The_Treachery_of_Images
17:53:19<lambdabot>Title: The Treachery Of Images - Wikipedia, the free encyclopedia
17:53:58<Spark>i saw that referred in some pixel pushing art once
17:54:08<Spark>ceci n'est pas une pixele
17:54:12<Spark>or something like that
17:54:36<liyang2>This is not my fist on your FACE.
17:54:39<Spark>because it had a pixel under a magnifying glass, and it was a rabbit or something
17:56:10<liyang2>Spark: how's London? :-/
17:58:42<Spark>i'm living in the 4th least pleasant place to live in the UK
18:01:22<ivant>yay, we had our first official Haskell User Group meeting in St.Petersburg on Saturday!
18:01:45<bos>excellent!
18:01:56<Spark>did you have a group hug
18:01:58<ivant>26 people were there!
18:02:15<ivant>oh, we forgot about a group hug :-)
18:02:16<bos>nice.
18:03:31<ivant>if somebody ever decide to come to St.Petersburg, be sure to prepare a talk for our HUG :-)
18:05:39<pierre->ivant: yeah, spbhug was really great
18:07:35<byorgey>@seen shapr
18:07:35<lambdabot>shapr is in #scannedinavian, #xmonad, #haskell-blah and #haskell. I last heard shapr speak 58m 16s ago.
18:08:08<byorgey>shapr: so AmeroHaskell might be in the northwest instead of southeast now?
18:08:18<shapr>yup
18:08:32<mrd>catty corner
18:08:48<shapr>Portland seems like the easiest place to get a venue, and where the most potential attendees are already located.
18:09:06<mrd>ACTION is in another corner
18:09:23<byorgey>shapr: yeah, that makes sense. it's a bit farther away for me of course, but I'll see if I can still come, depending on when it is and whether I can get cheap plane tickets
18:11:53<shapr>cool
18:15:32<bos>portland would be perfect. where's the wiki page again?
18:15:34<byorgey>I'm actually planning to apply to PSU, so 'twould be a good chance to visit, especially if it happens before December. dunno how likely that is though.
18:16:01<byorgey>@wiki AmeroHaskel
18:16:01<lambdabot>http://www.haskell.org/haskellwiki/AmeroHaskel
18:16:08<byorgey>erm, but spelled correctly =P
18:20:04<MyCatSchemes>@seen Zeppelin
18:20:05<lambdabot>I haven't seen Zeppelin.
18:20:09<MyCatSchemes>@seen Jesus
18:20:09<lambdabot>I haven't seen Jesus.
18:20:21<MyCatSchemes>@seen The_Invisible_Pink_Unicorn
18:20:21<lambdabot>I haven't seen The_Invisible_Pink_Unicorn.
18:20:23<Baughn>@seen me
18:20:23<lambdabot>me has changed nick to olsner.
18:20:23<lambdabot>I saw olsner leaving #haskell 1d 7h 55m 6s ago, and .
18:20:37<Baughn>MyCatSchemes: Also, it's an invisible pink dragon. Get it right.
18:21:04<MyCatSchemes>@seen my_toes_in_fourty_years._So_now_I_go_to_weightwatchers.
18:21:04<lambdabot>I haven't seen my_toes_in_fourty_years._So_now_I_go_to_weightwatchers..
18:21:21<Baughn>@seen lambdabot
18:21:22<lambdabot>Yes, I'm here. I'm in #friendly-coders, #scannedinavian, #gentoo-haskell, ##logic, #xmonad, #unicycling, #perl6, #parrot, #jtiger, #haskell-soc, #haskell-overflow, #haskell-blah, #scala, #haskell, #
18:21:22<lambdabot>ghc and #darcs
18:21:56<MyCatSchemes>Baughn: wikipedia disagrees.
18:22:35<MyCatSchemes>Hell, even Google's keyword completion in Firefox immediately comes up with "unicorn" whenever I type "invisible pink"
18:22:53<Baughn>I was wondering what was up with those search words
18:23:07<Baughn>Google, you say. Fun.
18:23:19<fax>lambdabot can unicycle too?
18:23:32<Baughn>lambdabot, can you unicycle?
18:23:38<oerjan>@unicycle
18:23:39<lambdabot>Unknown command, try @list
18:23:50<Baughn>Guess not. She's too embarrassed to answer.
18:26:05<roconnor>@vixen can you unicycle?
18:26:06<lambdabot>i sure can
18:26:31<Baughn>@seen dons
18:26:31<lambdabot>dons is in #xmonad and #haskell. I last heard dons speak 8m 44s ago.
18:44:32<shapr>Is there a headless X server? Something that can run without display hardware?
18:44:46<shapr>I want to run automated tests with the recent selenium binding from Galois on a machine without a display.
18:45:14<dons>shapr: hmm, i think it needs a real browser running javascript
18:45:24<dons>i'm unaware of a way to run it 'offline' as such
18:45:41<kaol>like xserver-xorg-video-dummy? (on Debian, at least)
18:46:03<liyang2>shapr: a VNC server?
18:46:18<ToxicFrog>shapr: NX? You'll need a remote system with an X terminal to get it started, though.
18:46:37<dmwit>liyang2: And how would you control the VNC server, without a display?
18:47:00<ToxicFrog>...hmm.
18:47:01<liyang2>dmwit: same question goes to the original request. :)
18:47:07<liyang2>(XTEST?)
18:47:30<dmwit>liyang2: You can surely get remote connection that has no X in it to control the server, but that doesn't help control VNC.
18:47:33<shapr>Selenium starts up the browser by itself.
18:47:43<ToxicFrog>I have pmap :: Double -> (a -> a) -> [a] -> State b [a]
18:48:20<liyang2>well, some early VNC servers manifest themselves as X11 servers that don't require display hardware. That's all I know.
18:48:31<ToxicFrog>I have mutate_one :: Solution -> Solution, where Solution = [Int], and it calls pmap..
18:48:38<shapr>liyang2: That's an idea, thanks.
18:48:47<ToxicFrog>It needs to become Solution -> State b Solution, yes?
18:48:50<shapr>kaol: -dummy sounds good, I can try that locally.
18:49:22<byorgey>ToxicFrog: not necessarily. There are functions like runState, execState, and evalState that let you extract things from the State monad.
18:49:33<byorgey>ToxicFrog: it depends what you want.
18:49:56<oerjan>ToxicFrog: is the b really polymorphic? in which case i don't see how pmap could use the state at all?
18:50:01<ToxicFrog>Hrm
18:51:24<ToxicFrog>ACTION tries to figure out how to explain this
18:51:47<ivant>shapr, AFAIR, there is a thing called x virtual framebuffer server
18:51:54<ToxicFrog>I have this function, mutate, which takes a Solution and creates a new Solution out of it; data Solution = Solution [Int]
18:52:04<ToxicFrog>So, ideally, the definition is
18:52:35<ToxicFrog>mutate (Solution s) = Solution (pmap 0.5 (+1) s)
18:52:50<roconnor>ACTION gets a version of iowidget to typecheck
18:52:57<oerjan>ToxicFrog: what is the _actual_ type of pmap?
18:53:01<roconnor>Now to attempt to create my first widget!
18:53:02<ToxicFrog>However, pmap doesn't return an [a], it returns a State [Double] [a], because internally it needs state
18:53:11<oerjan>ok
18:53:20<oerjan>so b = [Double]
18:53:36<ToxicFrog>pmap :: forall a. Double -> (a -> a) -> [a] -> State [Double] [a]
18:54:02<byorgey>@type execState
18:54:03<ToxicFrog>Yes, sorry
18:54:04<lambdabot>forall s a. State s a -> s -> s
18:54:10<byorgey>@type evalState
18:54:12<lambdabot>forall s a. State s a -> s -> a
18:54:35<oerjan>seems like you want evalState
18:55:02<byorgey>ToxicFrog: I think you want mutate (Solution s) = Solution (evalState (pmap 0.5 (+1) s) ??)
18:55:10<byorgey>where the ?? is whatever the appropriate initial state is
18:55:40<roconnor>what is the basic Gtk2hs widget for a simple text entry box?
18:55:53<ToxicFrog>The initial state comes from the attached State monad via get, I think
18:55:54<dcoutts_>roconnor: Entry
18:56:26<ToxicFrog>Basically, mutate needs to be in State, and I'm having trouble with the interaction between State and user-defined types
18:56:40<roconnor>thx
18:57:02<oerjan>ToxicFrog: every state monad needs to get its initial state on "startup"
18:57:26<ToxicFrog>oerjan: the original initial state is created and passed in by main
18:57:43<oerjan>oh, so there is a global State monad?
18:57:48<ToxicFrog>From there, it gets carried around until more_randoms way at the bottom of the call graph needs it.
18:58:18<ToxicFrog>Which I had working back when I was just using [[Int]]
18:58:24<ToxicFrog>Rather than [Solution]
18:58:36<ToxicFrog>The problem I'm running into is that I can'
18:58:38<shapr>ivant: xvfb looks like exactly what I need, thanks!
18:58:46<oerjan>in that case you probably cannot escape State that easily
18:58:54<ToxicFrog>I'm not trying to escape it!
18:59:09<ToxicFrog>The issue is that I want to return a State [Double] Solution
18:59:34<ToxicFrog> But I can't see how to turn a State [Double] [Int] into a State [Double] (Solution [Int])
18:59:44<oerjan>liftM Solution
18:59:56<ToxicFrog>@type liftM
18:59:58<lambdabot>forall a1 r (m :: * -> *). (Monad m) => (a1 -> r) -> m a1 -> m r
19:01:27<roconnor>dcoutts_: Is it possible to invoke the onEditableChanged callback by hand? I don't see a function for that.
19:01:44<ToxicFrog>Erm. I don't have a monad going in, only coming out.
19:02:01<ToxicFrog>And the signature isn't (a->b), it's (a->m a)
19:02:03<oerjan>but pmap is in the monad
19:02:06<dcoutts_>roconnor: not sure, lemme look. In general you can't poke all callbacks, since many of them have extra arguments
19:02:18<ToxicFrog>Yes. That's the problem. I give it a list, I get a monad list out.
19:02:27<byorgey>i.e. mutate (Solution s) = liftM Solution $ pmap 0.5 (+1) s
19:02:38<ToxicFrog>...oh, right
19:02:58<roconnor>dcoutts_: If I change an attribute by hand, will the callback be called?
19:03:08<ToxicFrog>...right, right! Solution has type [Int] -> Solution
19:03:12<ToxicFrog>Didn't realize that
19:03:12<roconnor>dcoutts_: change an attribute with set
19:03:13<ToxicFrog>Thank you
19:03:33<dcoutts_>roconnor: sure, if you modify the content of the Entry then the changed signal will fire
19:03:57<dcoutts_>roconnor: you have to go to greater lengths to get the opposite behaviour, to modify without getting the signal
19:04:55<roconnor>so I should set the callback and then set the inital value to have the callback called on initialization?
19:05:15<roconnor>I think I can do that
19:06:54<Saul_>Hey guys
19:07:09<Saul_>I have a bit of a problem (not really, more of a mental exercise)
19:07:26<dmwit>Hi Saul_!
19:07:36<dmwit>We all love mental exercise.
19:07:54<Saul_>I have a problem that is defined using snoc lists, but I want to rewrite it to a definition using cons lists
19:08:06<Saul_>the list itself shouldn't be reversed though
19:08:14<Saul_>and it should be proven correct
19:08:48<Saul_>the function I have is:
19:08:52<Saul_>f [] = 0
19:09:14<Saul_>f (s <| b) = 10 * f s + b
19:09:52<Saul_>dmwit: Hi
19:10:54<oerjan>Saul_: sounds like you essentially want to change a foldr (on snocs) to a foldl (on conses)
19:11:48<oerjan>(well, a foldl on snocs, which has the same structure as a foldr on conses)
19:11:59<Saul_>oerjan: I guess (aren't foldrs on cons though, and foldls on snoc)?
19:12:56<oerjan>you can have foldls and foldrs on both, but mirrored
19:13:22<Saul_>I see
19:13:37<Saul_>But that is way too generic, I just need it in this specific case
19:13:44<oerjan>so the way to write each for a snoc is to write the opposite for a cons
19:14:03<Saul_>the function basically turns [1, 2, 3, 4] into 1234
19:14:08<oerjan>well you need to use the same structure
19:15:11<roconnor>dcoutts_: It kinda works!!!!
19:15:23<oerjan>actually you need to generalize slightly, because a foldl on (cons) lists requires passing the accumulating argument
19:15:23<dcoutts_>roconnor: only kinda?
19:15:40<roconnor>dcoutts_: well, it didn't quite initialize properly
19:15:49<roconnor>but once it got going to worked
19:15:55<dcoutts_>ok
19:15:58<roconnor>I build an echo dialog
19:16:07<roconnor>using two entry boxes
19:16:15<Saul_>Well I already have a accumulating function that calculates the same as f already, but I need to derive one from the definition of f
19:16:29<roconnor>using Phooey with a Gtk2hs backend!
19:16:41<dcoutts_>roconnor: oh, cool!
19:17:16<dcoutts_>roconnor: so to do all that nicer you want a way to get a signal for a specific attribute
19:17:27<dcoutts_>roconnor: which is possible in Gtk+, but we've not bound it yet
19:17:33<dcoutts_>and I should look into doing so
19:17:34<roconnor>dcoutts_: ah yes
19:17:39<roconnor>that would be much better
19:17:46<Saul_>@src foldl
19:17:46<lambdabot>foldl f z xs = lgo z xs
19:17:46<lambdabot> where lgo z [] = z
19:17:46<lambdabot> lgo z (x:xs) = lgo (f z x) xs
19:17:51<Saul_>@src foldr
19:17:51<lambdabot>foldr k z xs = go xs
19:17:52<lambdabot> where go [] = z
19:17:52<lambdabot> go (y:ys) = y `k` go ys
19:18:22<dcoutts_>roconnor: something like: on widget (attrChanged attr) $ do ...
19:18:35<oerjan>as you see, go is the function you already have essentially
19:19:18<oerjan>so you probably want the corresponding lgo
19:19:21<Saul_>I basically also have lgo as well
19:19:58<roconnor>dcoutts_: that would look more like the existing wxHaskell code
19:20:14<dcoutts_>roconnor: what api does it use?
19:20:15<Saul_>I really don't have much of a problem with writing accumulating functions and stuff, but the exercise is to derive one from the other
19:21:22<Saul_>I have g a [] = a
19:21:40<Saul_>and g a (x:xs) = g (10 * a + x) xs
19:21:48<oerjan>yeah
19:21:50<Saul_>g 1 = f
19:21:58<dcoutts_>roconnor: or rather, what would you write in wx to get the same effect ?
19:22:40<Saul_>I even derived a weird accumulating version of f, but it still works with snoc lists
19:22:43<Beelsebob>Saul_: use fold
19:22:58<oerjan>i am not sure, but maybe one could view it has a kind of CPS transformation?
19:23:02<oerjan>*as
19:23:13<Saul_>g x y [] = y
19:23:37<roconnor>dcoutts_: I'm not certain. I don't fully appreciate what the wxHaskell code I'm replacing does.
19:23:41<Saul_>g x y (s <| b) = g (x * 10) (x * b + y) s
19:23:47<Saul_>g 1 0 = f
19:23:49<dcoutts_>roconnor: ok :-)
19:23:51<Saul_>CPS?
19:23:59<roconnor>dcoutts_: but there is a fair amount of use of `on`
19:24:07<roconnor>which I've replaced
19:24:22<Saul_>Beelsebob: I would first have to derive fold, so that would probably make it more work
19:24:33<Saul_>oerjan: CPS?
19:24:35<dcoutts_>robreim: I think their 'on' means turn a signal into a function valued attribute
19:24:38<dcoutts_>oops
19:24:43<dcoutts_>roconnor: ^^
19:24:49<oerjan>continuation passing style
19:24:57<roconnor>dcoutts_: right, I have no idea at this point
19:25:01<Saul_>ah ok
19:26:20<Saul_>I don't really have a lot of experience with that, and I would also have to prove it correct first
19:27:50<oerjan>do you have a proven function for converting between snoc and cons lists? perhaps you could compose it with that, and somehow unravel the result
19:28:32<Saul_>Nope, that's the problem
19:28:47<fox86>anyone know how to completely turn off indentation when using haskell-mode in emacs? (remove-hook 'haskell-mode-hook 'turn-on-haskell-indent) does disable some of the fancier stuff, but not everything. i would like "return" to just make a newline without indenting at all and then rather tab my way to where i want to be. maybe this is a question for #emacs, but they don't seem to use haskell-mode
19:29:06<Saul_>I do have some calculation rules, but they aren't much help
19:29:32<oerjan>maybe make that first, as otherwise it would seem hard to even define what it means for your original exercise to be correct...
19:30:23<Saul_>Yeah I've tried some things, but no luck so far :(
19:30:37<oerjan>although when i think about it, such a conversion function would essentially also be a foldl...
19:31:34<dons>http://programming.reddit.com/info/5yciu/details
19:31:35<lambdabot>Title: programming: Ask Reddit: How do I get a job hacking Haskell all day?
19:31:39<dons>anyone else have suggestions?
19:32:17<oerjan>calculation rules? like a : (b <| c) = (a : b) <| c ?
19:32:34<Lemmih>@seen dcoutts_
19:32:34<lambdabot>dcoutts_ is in #gentoo-haskell, #haskell, #ghc and #haskell-overflow. I last heard dcoutts_ speak 7m 50s ago.
19:32:41<dcoutts_>hia Lemmih
19:32:45<Saul_>Yeah like those (although that particular one is missing)
19:33:06<araujo>dons, starting your own startup
19:33:09<oerjan>actually i guess <| could be defined as a haskell function (not to be pattern matched on, though)
19:33:20<roconnor>dcoutts_: Hmm, I guess when the text attribue on an entry is set, the onEntryActivate callback isn't fired?
19:33:22<beschmi>fox86: what function gets called by "return"? C-h k RET
19:33:51<dcoutts_>roconnor: the activate is what happens when you press enter in the Entry box
19:34:16<Saul_>well the calculation rule you suggested in reverse would be a proper definition
19:34:18<ivant>oh, I wish one day I could get a job hacking Haskell
19:34:30<roconnor>dcoutts_: I think I will have to fire that initally by hand
19:34:37<eyeris>How can I make ghc infer Float from `Int / (Int + Int)`? (the Int is being returned by `length :: [a] -> Int`)
19:34:40<fox86>beschmi:" RET runs the command newline-and-indent-relative"
19:34:42<oerjan>right
19:34:42<Saul_>combined with [] <| b = b : []
19:35:34<oerjan>eyeris: use fromIntegral or genericLength
19:35:51<dcoutts_>roconnor: I don't think I understand, that signal does not correspond to any property of the widget, it's more like the signal you get when someone presses a button widget
19:35:54<Lemmih>dcoutts_: I've been told that SOE/Gtk once had problems on Windows. HsSDL is now in the same situation. Do you have any wise words or hints?
19:36:11<dcoutts_>Lemmih: what kind of problems?
19:36:13<Saul_>I've tried using those, but then I got stuck
19:36:20<eyeris>oerjan thanks
19:36:29<dcoutts_>Lemmih: most of our problems were to do with making it easy for windows users to install
19:37:04<dcoutts_>Lemmih: so you could make an installer, the hint there is InnoSetup, it's what gtk2hs and ghc-6.8 use
19:37:25<roconnor>dcoutts_: yeah, I want to initalize the edit box with a string, and then notify the event handler, as if the enter key was pressed. Seems like a reasonable initalization routine to me.
19:37:38<beschmi>fox86, runs command newline here in haskell-mode
19:38:53<dcoutts_>roconnor: hmm, so is the behaviour that you want, that the values calculated based on the entry's text should only update when the user presses enter in the box ?
19:39:43<roconnor>dcoutts_: I think so. I think updating as they type would be really annoying in most cases.
19:40:22<roconnor>... I should test to see what the wxHaskell version did
19:40:28<dcoutts_>roconnor: you should ask conal how he manages that kind of update policy
19:40:58<roconnor>I should, but I think he was able to always fire any event handler.
19:43:19<dcoutts_>roconnor: of course you can always run the event handler directly if you were the one who connected it
19:45:50<dons>augustss with his hackathon tshirt :) http://catenova.org/~lemmih/ICFP07/images/pa040054.jpg
19:49:17<earthy>nice shirt, btw. I like the axe in the lambda.
19:49:31<earthy>(mrchebas had his on today)
19:51:42<Saul_>Argh, I give up
19:51:53<Saul_>oerjan: Thanks for your help
19:53:07<dons>earthy: cool :)
20:09:34<eyeris>I'm trying to use the Text.CSV package. I import Text.CSV and Text.ParserCombinators.Parsec but ghci still tells me that both CSV and ParseError are not in scope.
20:09:49<dons>how do you import them?
20:09:59<dons>and did you touch your .hs file, so ghci can see non-exported symbols?
20:10:49<eyeris>I import them at the top of my .hs with "import Text.CSV"
20:11:45<eyeris>I'm not sure what you mean by touching the .hs file. I can touch it with the unix command touch, but that doesn't change anything
20:12:13<sjanssen>eyeris: how did you install Text.CSV?
20:14:00<eyeris>runghc Setup.hs build/install or something like that -- from the instructions
20:14:24<eyeris>I might just be using it wrong. Here is my code (on hpaste)
20:14:41<hpaste> eyeris pasted "csverror" at http://hpaste.org/3310
20:15:27<sjanssen>eyeris: yes, you're doing it wrong :P
20:15:31<eyeris>figures
20:16:24<hpaste> sjanssen annotated "csverror" with "parseCSVFromFile returns Either ParseError CSV" at http://hpaste.org/3310#a1
20:17:11<eyeris>Ok, so I misunderstood now Either works... trying to use it more like Maybe?
20:17:31<oerjan>Maybe doesn't work like that either :D
20:18:23<oerjan>you need Just and Nothing like you need Left and Right
20:18:29<eyeris>ok yeah
20:19:22<eyeris>yay! it works!
20:25:41<n00b>how do i write a recursicve function to sum all the elements in list
20:25:55<dons>> sum [1..10]
20:25:57<lambdabot> 55
20:25:58<dons>?src sum
20:25:58<lambdabot>sum = foldl (+) 0
20:26:01<dons>?src foldl
20:26:04<lambdabot>foldl f z xs = lgo z xs
20:26:04<lambdabot> where lgo z [] = z
20:26:04<lambdabot> lgo z (x:xs) = lgo (f z x) xs
20:26:06<dons>:)
20:26:15<oerjan>?src foldl'
20:26:16<lambdabot>foldl' f a [] = a
20:26:16<lambdabot>foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
20:26:21<byorgey>a bit over-general for that specific problem, perhaps, but...
20:26:23<dons>well, that's over the top.
20:26:34<wli>mySum [] = 0 ; mySum (x:xs) = x + mySum xs
20:26:35<dons>n00b: what have you got so far?
20:28:24<n00b>i am gonna hpaste it
20:30:49<hpaste> n00b pasted "sumAll" at http://hpaste.org/3311
20:31:19<dmwit>n00b: That looks fine.
20:31:24<dmwit>Are you having a problem with it?
20:31:41<n00b>kinda learning list
20:31:52<n00b>I wrote based on you guys replies
20:31:59<dmwit>aha
20:33:41<n00b><dmwit> ???
20:35:46<n00b>how do I write a rursive definition for div in haskell ?
20:36:15<Heffalump>how efficient do you want?
20:36:28<Heffalump>ls
20:36:31<Heffalump>sorry
20:36:42<wli>I think he can take dogslow.
20:36:44<mrd>ACTION lists Heffalump's directories
20:36:48<dmwit>n00b: Do you mean, how do you divide each element of a list by a certain number, or do you really want to define div?
20:36:54<n00b>Implement the following operators (over the natural numbers i.e. positive integers) using recursive definitions: (a) * (multiplication) (b) div (division) (c) mod (modulus)
20:37:10<Heffalump>well, I suggest you consider two possible cases.
20:37:21<Heffalump>Either (a) the answer is 0 or (b) the answer is not 0.
20:51:07<hpaste> (anonymous) pasted "numDigits" at http://hpaste.org/3312
20:51:47<n00b>i am writing a recursive function to count the number of digits in a numbers
20:52:00<n00b>help pleas !!!!
20:52:34<oerjan>n00b: you might try div'ing by 10
20:53:24<byorgey>n00b: the first case looks good. In the other case, you know it has at least one digit, plus some more. How will you use numDigits to count the rest?
20:55:21<n00b>could i break down the number each time by using
20:55:24<n00b>mod
20:55:25<n00b>??
20:55:32<oerjan>n00b: div, i said :)
20:55:40<n00b>ok
20:55:47<byorgey>if you mod by 10 you'll get the last digit of the number.
20:55:56<byorgey>if you div by 10 you'll get everything BUT the last digit.
20:56:41<abell>Does it have to be recursive?
20:56:47<n00b>let a = 14 `div` 10 in if a <= 9 = 1 else a+1
20:56:55<n00b>>let a = 14 `div` 10 in if a <= 9 = 1 else a+1
20:56:58<n00b>yes
20:57:03<n00b>> let a = 14 `div` 10 in if a <= 9 = 1 else a+1
20:57:03<lambdabot> Parse error
20:57:07<TomMD>> do Nothing
20:57:09<lambdabot> Nothing
20:58:01<oerjan>n00b: then not =
20:59:16<byorgey>n00b: that's closer, but it's still not recursive. and also, you need 'if a <= 9 then 1' instead of '... = 1', as oerjan mentioned.
20:59:33<n00b>i tried it and I keep getting a stack overflow
21:00:01<n00b>otherwise = numDigits a `div` 10
21:00:22<oerjan>n00b: you need parentheses
21:01:05<oerjan>function application binds tighter than operators
21:01:25<n00b>answer always 1
21:01:42<hpaste> n00b pasted "numDigits" at http://hpaste.org/3313
21:02:10<byorgey>think about what that says. "otherwise = numDigits (a `div` 10)" means that if a >= 10, a has the same number of digits as a/10. is that true?
21:03:11<n00b>don't understand
21:03:37<byorgey>ok, let's try an example.
21:03:41<byorgey>suppose a = 587.
21:03:42<oerjan>n00b: what is numDigits (14 `div` 10)?
21:04:11<byorgey>how would evaluation of numDigits 587 proceed?
21:04:13<oerjan>(that is, what should it be?)
21:07:51<n00b>don't understand
21:08:07<n00b>i get the last digit, but what should it do ??
21:08:30<Botje>n00b: numDigits "15" = 1 + numDigits "5" = 2
21:08:41<n00b>ok
21:08:49<Botje>n00b: your code does numDigits "15" = numDigits "5" = 1
21:08:56<Botje>do you spot what's missing?
21:08:57<n00b>so one is added to the previous
21:09:58<shapr>I'm trying to start a Haskell program in a subshell with ( program ) & but I always get "Main: <stdin>: hGetChar: end of file" any idea why?
21:10:11<shapr>I tried piping some random text to the program, but I still get the same error.
21:10:30<shachaf>shapr: Does it work otherwise?
21:10:47<wli>botched SIGTTIN handling?
21:10:55<bos>shapr: probably because it's doing non-blocking IO on stdin
21:11:28<shapr>shachaf: Yes, the program works if stdin is available.
21:11:50<bringert>dcoutts: thanks for pushing those patches to cabal-1.2
21:12:37<n00b>getting a stack overflow
21:13:17<hpaste> n00b pasted "(no title)" at http://hpaste.org/3314
21:13:27<n00b>check that
21:14:58<omnId>numDigits 12 = (1 + numDigits 12) `div` 10 = (1 + numDigits ((1 + numDigits 12) `div` 10))) `div` 10
21:15:18<byorgey>n00b: your parentheses aren't in the right place. see if you can figure out why.
21:15:37<omnId>when you call numDigits recursively, it needs to take a smaller case or it'll just keep calling it forever.
21:16:02<n00b>???
21:16:04<byorgey>n00b: a very good exercise in this sort of situation is to see if you can "simulate" the code on a particular example by hand, to see if you understand what is happening.
21:16:49<omnId>n00b: in the example I showed, you need to `div` the 12 by 10 before passing it to numDigits
21:18:42<eyeris>!! is linear time, right?
21:18:48<byorgey>eyeris: yup.
21:18:49<mauke>what's a good algorithm for computing all digits of sqrt 2?
21:19:09<eyeris>So is there a more efficient way of writing something like this:
21:19:16<eyeris>let as = "abcdefg"; [ as !! x | x <- [1,4,6] ]
21:19:24<byorgey>mauke: by "good" do you mean "simple", "efficient", or what?
21:19:51<mauke>byorgey: fast
21:20:07<mauke>I need to generate more than 100000 digits in less than 20 seconds :-)
21:20:22<oerjan>eyeris: we discussed that the other day
21:20:44<eyeris>oerjan you and I did? Is there a #haskell log somewhere?
21:21:01<mauke>@where logs
21:21:01<oerjan>i don't remember if you were involved :)
21:21:01<lambdabot>http://tunes.org/~nef/logs/haskell/ http://meme.b9.com/cdates.html?channel=haskell
21:21:42<Olathe>@pl \x f -> f x
21:21:42<lambdabot>flip id
21:21:59<byorgey>mauke: maybe something on here will help? http://numbers.computation.free.fr/Constants/constants.html
21:22:00<lambdabot>Title: Mathematical Constants and computation
21:22:10<Olathe>> (flip id) 3 (+1)
21:22:12<lambdabot> 4
21:22:13<mauke>ah, thanks
21:22:18<hpaste> omnId annotated "(no title)" with "n00b:" at http://hpaste.org/3314#a1
21:22:45<oerjan>i think i did something with scanl drop...
21:23:09<byorgey>mauke: I know simple ways to compute sqrt 2 to arbitrary precision, but not fast =)
21:23:12<omnId>Olathe: s/id/($)/ is you want it to be a little clearer
21:23:15<Olathe>> flip id 3 (+1)
21:23:16<lambdabot> 4
21:23:18<omnId>if*
21:23:38<Olathe>> 3 id (+1)
21:23:38<lambdabot> add an instance declaration for
21:23:39<lambdabot> (Num ((a -> a) -> (a1 -> a1) -> ...
21:23:50<omnId>> 3 `id` (+1)
21:23:51<lambdabot> add an instance declaration for (Num ((a -> a) -> a1))
21:23:58<omnId>erm, oops
21:24:02<Olathe>> (+1) (id 3)
21:24:03<lambdabot> 4
21:24:06<omnId>> (+1) `id` 3
21:24:07<lambdabot> 4
21:24:09<mauke>byorgey: my current approach is iterate (\x -> x / 2 + recip x)
21:24:20<mauke>byorgey: with unfoldr (\a -> let (d, r) = a `divMod` b in Just (toEnum (fromInteger d + 48), r * 10)) to generate the digits
21:24:34<omnId>($) f x vs. flip ($) x f
21:25:43<byorgey>mauke: right, I'd guess that's probably not very fast =)
21:26:18<oerjan>> map head . tail . scanl (flip drop) "abcdefg" . ap (zipWith (-)) (0:) $ [1,4,6]
21:26:20<lambdabot> "beg"
21:26:20<mauke>fast enough to get 100343 digits in 16 iterations
21:26:46<byorgey>> 2^16
21:26:47<lambdabot> 65536
21:26:52<byorgey>> 2^17
21:26:53<lambdabot> 131072
21:26:56<byorgey>yup =)
21:27:29<Olathe>@pl \fs -> (\x -> map (\f -> f x) fs)
21:27:29<lambdabot>flip (map . flip id)
21:27:34<byorgey>it's the memory management and printing that take a long time.
21:28:58<byorgey>I wonder if there's a way to generate it stream-style. with your method it has to calculate the entire rational value in memory before printing anything out.
21:29:37<wli>The long division analogue for square roots.
21:29:40<mauke>the first iterations seem to take almost no time
21:29:51<mauke>but the last few rounds are really expensive
21:30:31<mauke>crap. lifting the first 14 iterations to compile time doesn't help.
21:31:01<Olathe>Usually, you have map f xs. What's a good name for q in q fs x ?
21:31:07<byorgey>wli: ah, right. I wonder if that would be faster?
21:31:14<mauke>Olathe: sequence?
21:31:29<quicksilver>KatieHuber: around? or any other openGL experts?
21:31:54<omnId>map ($ x) fs works too
21:32:09<Olathe>Right, but this is for Mathematica naming.
21:32:42<byorgey>how about Pam?
21:32:54<omnId>mapApply?
21:33:01<byorgey>ACTION only half joking
21:33:29<byorgey>ApplyEachInAListOfFunctionsToAValue?
21:33:45<ddarius>sequence
21:33:48<KatieHuber>quicksilver: here
21:34:02<quicksilver>KatieHuber: I'm trying to optimise my particle engine
21:34:25<quicksilver>KatieHuber: currently it's moving + drawing about 12,000 particles (triangles) per second
21:34:42<quicksilver>KatieHuber: which is better than the 3000 it was doing at the beginning of the evening
21:34:50<KatieHuber>you mean, 12000 particles @ 60fps?
21:34:52<quicksilver>KatieHuber: does that sounds like a reasonable speed?
21:35:02<quicksilver>no, 3000 particles at 40fps
21:35:09<quicksilver>erm
21:35:19<quicksilver>which is 120,000 particles per second in fact :)
21:35:29<quicksilver>clearly my maths is a bit limited...
21:35:53<KatieHuber>well, particle systems are almost always limited by fill rate, since they tend to be blended
21:36:17<KatieHuber>so the number of particles shouldn't matter nearly as much as the number that are on the screen
21:36:25<quicksilver>they're all onscreen
21:36:39<KatieHuber>so try taking them all offscreen, and see what your framerate does
21:36:46<quicksilver>;)
21:36:50<KatieHuber>if it improves massively, there's little point optimizing further
21:36:52<quicksilver>ACTION tries that
21:36:53<n00b>how do you implement operators recusively
21:37:01<KatieHuber>if it stays the same, then you can probably still optimize
21:37:06<n00b>???
21:37:19<omnId>n00b: the same as any other function?
21:37:20<n00b>for example the mod or div operator
21:37:20<byorgey>n00b: a function is recursive if it is defined in terms of itself.
21:37:31<n00b>ok
21:37:35<byorgey>n00b: usually, this means there will be a simple case called the 'base case' with no recursion.
21:37:38<quicksilver>KatieHuber: went up from 40fps to 44fps
21:37:45<byorgey>i.e. it's so simple you know the answer right away.
21:38:00<quicksilver>KatieHuber: I guess that means I'm still CPU-bound
21:38:01<byorgey>for example, numDigits a, when a <= 9.
21:38:03<quicksilver>KatieHuber: right?
21:38:05<KatieHuber>sounds that way
21:38:08<quicksilver>ACTION nods
21:38:09<n00b>so can a div operator call itself
21:38:11<n00b>??
21:38:21<quicksilver>well the haskell is doing quite a lot of work
21:38:30<byorgey>n00b: and the other case is the recursive case, where the function calls itself on a *simpler* version of the problem, and somehow uses that to build the complete answer.
21:38:32<quicksilver>perlin-noise generated wind turbulence
21:38:37<byorgey>n00b: sure, any Haskell function can call itself.
21:38:55<KatieHuber>time for profiling to see where the CPU time is going, then
21:38:58<quicksilver>ACTION nods
21:39:13<byorgey>n00b: for example, the recurisve case for numDigits was to recognize that if you divide the number by 10, there's one less digit, so you can count the digits of that and then add one.
21:39:18<quicksilver>I might try some simpler particle systems which don't use the perlin noise for comparison :)
21:39:26<byorgey>i.e. numDigits a = 1 + numDigits (a `div` 10)
21:39:27<n00b>base case would be like if n < 0 = error "Positive number only" else n = n + (div n)
21:39:55<byorgey>hold on, you're putting too much in there =)
21:39:58<byorgey>one thing at a time
21:40:02<omnId>n00b: probably div x y | y > x = 0
21:40:20<KatieHuber>I mean, a double-buffered STREAM_DRAW VBO, and writing directly to the MapBuffer'd pointer (can you even do that in Haskell?) would be the fastest way to get the vertices to the card
21:40:22<n00b>just a algorithm
21:40:41<KatieHuber>but there's a good chance that your problem isn't in the GL at all
21:40:47<quicksilver>KatieHuber: I've not tried using vertex buffer stuff
21:41:02<quicksilver>KatieHuber: this is all a great begin glBegin(GL_TRIANGLES)
21:41:07<KatieHuber>OMG :/
21:41:11<KatieHuber>well, start there then :p
21:41:30<quicksilver>can you change colour in the middle of a vertex buffer?
21:41:38<n00b>remember it must be recursive
21:41:49<KatieHuber>you can submit a color array
21:42:32<omnId>n00b: what's div 2 3?
21:42:57<n00b>0
21:43:07<quicksilver>KatieHuber: yeah, I'm fairly sure it's my physics engine not my GL code which is the limiting factor
21:43:08<omnId>n00b: what made you figure that out?
21:43:21<quicksilver>KatieHuber: I wasn't sure though, until you pointed that out :) so, thanks.
21:43:34<omnId>n00b: 3 > 2
21:43:46<omnId>n00b: and div 4 3?
21:43:59<n00b>1
21:44:04<quicksilver>KatieHuber: perlin noise is slow, probably I should cache some values to avoid recomputation.
21:44:23<n00b>so it is possible to recursively div two numbers
21:44:41<n00b>or more
21:44:41<omnId>n00b: div 4 3 = 1 + div (4 - 3) 3
21:45:38<omnId>you can think of division as iterated subtraction
21:48:16<hpaste> n00b pasted "(no title)" at http://hpaste.org/3315
21:48:27<n00b>getting a stack overflow
21:48:37<omnId>n00b: y > x
21:48:46<omnId>div 2 3 | 3 > 2 = 0
21:48:52<omnId>or x < y
21:51:24<quicksilver>KatieHuber: Ah. If i try a larger number of simpler particles (10,000 particles with just simple ballistic movement), then I get 20fps onscreen but 40fps offscreen
21:51:39<quicksilver>KatieHuber: so there is in fact definite room for improvement :)
21:52:27<KatieHuber>yup
21:52:45<dibblego>?check \f -> (Nothing >>= (f :: Int -> Maybe Int)) == Nothing -- why is there no instance of Arbitrary for Maybe?
21:52:46<lambdabot> add an instance declaration for (Arbitrary (Maybe Int)) In the exp...
21:53:11<quicksilver>KatieHuber: is there a rough order of magnitude I ought to be aiming for? 100,000 simply textured particles at 60fps, perhaps?
21:53:18<quicksilver>KatieHuber: this is a fairly modern laptop
21:53:54<KatieHuber>again, depends far more on blending and particle size than on the number of particles
21:54:26<quicksilver>I'm definitely using alpha and modulate
21:54:34<quicksilver>some particles I use additive blending on
21:56:20<KatieHuber>if all the particles are offscreen, 100000@60fps doesn't sound unreasonable
21:56:26<quicksilver>ACTION nods
21:56:29<shapr>Would "installHandler keyboardSignal" try to read from stdin?
21:57:05<KatieHuber>if they're all onscreen and blended and say, 30ish pixels square, you'll get many fewer, maybe 5-10k@60fps
21:57:14<KatieHuber>depends massively on your graphics card
21:57:32<KatieHuber>really not possible to give a sensible answer :/
21:57:37<quicksilver>ACTION nods
21:57:39<quicksilver>understood
21:57:51<quicksilver>it's possible to point me in the direction of the right order of magnitude though :)
21:57:54<quicksilver>which you have...
21:58:09<quicksilver>OK, now to learn about vertex arrays and VBOs
21:59:43<vincenz>@seen psykotic
21:59:44<lambdabot>I saw psykotic leaving #haskell 2h 34m 16s ago, and .
22:01:00<TomMD>Does anyone know if ndm made supero available anywhere? I really would like to play with it.
22:01:24<ddarius>ndm knows.
22:01:45<TomMD>Yes, but lambdabot hasn't seen him for 5 hours and I keep missing him.
22:01:54<omnId> @ask him
22:01:55<nopcode>hey :)
22:02:04<abell>dibblego, I think defining an arbitrary for Maybe would choose frequencies which wouldn't be appropriate in most cases
22:02:17<abell>Like returning Nothing half of the times
22:02:24<dibblego>abell, I guess
22:02:28<nopcode>how do i get, for each item in a list, the item and the rest of the list?
22:02:32<nopcode>(with the item removed)
22:02:49<dibblego>> tails [1..10]
22:02:52<lambdabot> [[1,2,3,4,5,6,7,8,9,10],[2,3,4,5,6,7,8,9,10],[3,4,5,6,7,8,9,10],[4,5,6,7,8,9...
22:02:57<dibblego>like that?
22:03:16<Olathe>@pl xs -> zip (heads xs) (tails xs)
22:03:16<lambdabot>(line 1, column 4):
22:03:16<lambdabot>unexpected ">" or "-"
22:03:16<lambdabot>expecting variable, "(", operator or end of input
22:03:17<nopcode>no, i want to pick an item in the middle of the list too, resulting in the item and the list without that item
22:03:25<Olathe>O...K
22:03:26<dmwit>see
22:03:28<omnId>f [1,2,3] = [(1,[2,3]), (2,[1,3]), (3,[1,2])]?
22:03:31<dmwit>http://okmij.org/ftp/Haskell/perfect-shuffle.txt
22:03:38<dibblego>@pl \xs -> zip (heads xs) (tails xs)
22:03:39<lambdabot>liftM2 zip heads tails
22:03:47<dmwit>There's a function there called "extract" which does what you're describing.
22:03:49<Olathe>@pl \xs -> zip (heads xs) (tails xs)
22:03:49<lambdabot>liftM2 zip heads tails
22:03:54<Olathe>Take that !
22:03:59<oerjan>@let extract l = [(x,bef++aft) | (bef,x:aft) <- zip (inits l) (tails l)]
22:04:04<lambdabot>Defined.
22:04:08<omnId>> liftM2 zip heads tails [1,2,3]
22:04:08<lambdabot> Not in scope: `heads'
22:04:12<oerjan>> extract [1..10]
22:04:14<lambdabot> [(1,[2,3,4,5,6,7,8,9,10]),(2,[1,3,4,5,6,7,8,9,10]),(3,[1,2,4,5,6,7,8,9,10]),...
22:04:20<Olathe>Ahh, inits.
22:04:27<omnId>> liftM2 zip inits tails [1,2,3]
22:04:29<lambdabot> [([],[1,2,3]),([1],[2,3]),([1,2],[3]),([1,2,3],[])]
22:04:34<TomMD>@ask ndm Is superO available to the public? I've got a MD5 implementation (2-5x slower than C when using GHC -O2) I thought might be fun to test with superO... provided I can get it setup with Data.ByteString
22:04:35<lambdabot>Consider it noted.
22:04:40<Olathe>Bah.
22:04:46<Olathe>@pl \xs -> zip xs (tails xs)
22:04:46<lambdabot>ap zip tails
22:04:58<omnId>> map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3]
22:05:00<lambdabot> Non-exhaustive patterns in lambda
22:05:03<Olathe>> (ap zip tails) [1, 2, 3, 4]
22:05:04<lambdabot> [(1,[1,2,3,4]),(2,[2,3,4]),(3,[3,4]),(4,[4])]
22:05:15<nopcode>hm :)
22:05:16<ddarius>> fix ((0:) . (1:) . ap (zipWith (+)) tail)
22:05:18<lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
22:05:27<Olathe>@pl \xs -> zip xs (tail (tails xs))
22:05:27<lambdabot>ap zip (tail . tails)
22:05:38<Olathe>> (ap zip (tail . tails)) [1, 2, 3, 4]
22:05:39<lambdabot> [(1,[2,3,4]),(2,[3,4]),(3,[4]),(4,[])]
22:05:42<shapr>Aha! it was installHandler keyboardSignal!
22:05:52<omnId>> take 3 $ map (\(xs,y:ys) -> (y, xs++ys)) $ tail $ liftM2 zip inits tails [1,2,3]
22:05:54<lambdabot> Non-exhaustive patterns in lambda
22:06:17<ddarius>> let f !a = a in f 3
22:06:19<lambdabot> Not in scope: `f'
22:06:22<Olathe>@pl \xs -> map (\t -> (head t, tail t)) (tails xs)
22:06:23<lambdabot>map (liftM2 (,) head tail) . tails
22:06:31<Olathe>> (map (liftM2 (,) head tail) . tails) [1, 2, 3, 4]
22:06:32<lambdabot> Exception: Prelude.head: empty list
22:06:49<omnId>> init $ map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3]
22:06:50<lambdabot> [(1,[2,3]),(2,[1,3]),(3,[1,2])]
22:06:56<omnId>:D
22:07:15<Olathe>@src mapWhile
22:07:15<lambdabot>Source not found. Just what do you think you're doing Dave?
22:07:29<TomMD>@src infinity
22:07:29<lambdabot>Source not found. Your mind just hasn't been the same since the electro-shock, has it?
22:07:36<dmwit>map f . takeWhile p ?
22:07:44<dmwit>?src Infinity
22:07:45<lambdabot>Source not found. I can't hear you -- I'm using the scrambler.
22:08:17<oerjan>Infinity is only a Read/Show thing, not a real constructor
22:08:20<Olathe>@pl \xs -> map (\t -> (head t, tail t)) (takeWhile (not . null) (tails xs))
22:08:21<lambdabot>map (liftM2 (,) head tail) . takeWhile (not . null) . tails
22:08:33<Olathe>> (map (liftM2 (,) head tail) . takeWhile (not . null) . tails) [1, 2, 3, 4]
22:08:34<lambdabot> [(1,[2,3,4]),(2,[3,4]),(3,[4]),(4,[])]
22:08:43<omnId>> init $ map (\(xs,y:ys) -> (y, xs++ys)) $ liftM2 zip inits tails [1,2,3,4]
22:08:45<lambdabot> [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])]
22:08:45<ddarius>@let fib n = fib' n 0 1 0 1 where fib' 0 a b c d = a; fib' n a b p q | a `seq` b `seq` p `seq` q `seq` False | even n = fib' (n `div` 2) a b (p*p+q*q) (2*p*q+q*q) | otherwise = fib' (n - 1) ((p+q)*a+q*b) (q*a+p*b) p q
22:08:46<lambdabot> Parse error
22:09:04<Olathe>Oh.
22:09:15<Olathe>I've been doing it wrong this whole time.
22:09:39<dmwit>> let extract n xs = let (b, m:e) = splitAt n xs in (m, b++e) in extract 5 [1..10]
22:09:40<lambdabot> (6,[1,2,3,4,5,7,8,9,10])
22:10:45<ddarius>@let fib n = fib' n 0 1 0 1 where fib' n a b p q | n `seq` a `seq` b `seq` p `seq` q `seq` False = undefined;fib' 0 a _ _ _ = a; fib' n a b p q | even n = fib' (n `div` 2) a b (p*p+q*q) (2*p*q+q*q) | otherwise = fib' (n - 1) ((p+q)*a+q*b) (q*a+p*b) p q
22:10:49<omnId>> zipWith (\i xs -> (xs !! i, take i xs ++ drop (i+1) xs) [0..] $ (\xs -> map (const xs) xs) [1,2,3,4]
22:10:49<lambdabot> Unbalanced parenthesis
22:10:51<lambdabot>Defined.
22:11:00<ddarius>> fib 20
22:11:01<omnId>> zipWith (\i xs -> (xs !! i, take i xs ++ drop (i+1) xs)) [0..] $ (\xs -> map (const xs) xs) [1,2,3,4]
22:11:03<lambdabot> [(1,[2,3,4]),(2,[1,3,4]),(3,[1,2,4]),(4,[1,2,3])]
22:11:03<lambdabot> 6765
22:11:14<ddarius>> map fib [1..20]
22:11:15<lambdabot> [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
22:11:30<AndyC>Hi, can anyone help me with a Parsec question please?
22:11:48<dmwit>shoot!
22:11:53<Olathe>> map fibs [270,273..280]
22:11:54<lambdabot> Not in scope: `fibs'
22:11:58<Olathe>> map fib [270,273..280]
22:12:00<lambdabot> [119447720249892581203851665820676436622934188700177088360,50598866273592314...
22:12:30<AndyC>Thanks. I am trying to parse some binary data (actually it's a Java class file).
22:12:31<jonathanv>my goodness, this fib function confuses me
22:13:05<AndyC>I'm looking at the bytecode that can be a variable number of bytes.
22:13:54<AndyC>I want to parse the first byte, do a case of on it to work out how many more bytes to read, read them then return something.
22:14:26<AndyC>I'm fine up until the second bit of parsing e.g. read in two more bytes.
22:14:38<dmwit>> let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in fib 1
22:14:40<lambdabot> 1
22:14:43<AndyC>Any ideas on a direction please?
22:14:46<dmwit>> let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in map fib [1..10]
22:14:47<lambdabot> [1,1,2,3,5,8,13,21,34,55]
22:15:07<dmwit>> let phi = (1 + sqrt 5) / 2; fib n = round ((phi ** n - (negate phi) ** (negate n)) / sqrt 5) in map fib [270,273..280]
22:15:08<lambdabot> [119447720249893657237202506912376692627920328520374419456,50598866273592779...
22:15:12<omnId>do n <- anyToken; bytes <- sequence (replicate n anyToken); ... -- something like that maybe
22:15:21<dmwit>Doesn't seem exact.
22:15:24<nopcode>hm
22:15:32<nopcode>i guess this would be easier if i just removed the element from the list
22:15:43<nopcode>by searching for it
22:15:48<dmwit>nopcode: What are you trying to do?
22:15:55<oerjan>:t replicateM
22:15:57<lambdabot>forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a]
22:15:58<dmwit>omnId: Are you familiar with do-notation for monads?
22:16:07<dmwit>err...
22:16:08<AndyC>After the first anyToken I need to look at n and decide how many more to read.
22:16:09<nopcode>dmwit: well it's a logic puzzle
22:16:19<omnId>dmwit: AndyC*? :)
22:16:22<dmwit>yes
22:16:24<dmwit>sorry
22:16:32<AndyC>yes
22:16:33<AndyC>ish
22:16:34<nopcode>dmwit: people walking over the bridge... i need to expand the state
22:16:37<dmwit>AndyC: Okay, no problem.
22:17:02<nopcode>i've got a state with lists l and r, representing the list of people on each side
22:17:25<glguy>ACTION reminds hpasters to use the annotate functionality when pasting revisions of existing code
22:17:28<nopcode>now i want to get all states which can be derived from this by moving one person in list 'r' to list 'l'
22:17:36<dmwit>varLength = do { length <- number; case length of { 0 -> fail "bad file"; n -> replicateM n anyToken } }
22:17:47<dmwit>AndyC: But more likely, you'd want:
22:17:59<dmwit>varLength = number >>= replicateM anyToken
22:18:02<dmwit>:t replicateM
22:18:04<lambdabot>forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a]
22:18:06<nopcode>so, how do i get a list with the first occurence of a given item removed?
22:18:11<AndyC>Ah, sorry. Hang on.
22:18:23<dmwit>AndyC: Well, you get the idea, though there might need to be a "flip" in my code somewhere. =P
22:18:30<omnId>you're parsing [Byte]?
22:18:35<AndyC>The first byte I read isn't how many more to read. It's an opcode.
22:18:58<AndyC>Some opcodes want two more bytes, some want one, some don't need any.
22:19:15<dmwit>AndyC: It doesn't matter what you're reading; the technique I just showed should apply equally well.
22:19:55<dmwit>nopcode: delete?
22:19:55<AndyC>So I want to say something like do op <- anyToken; case op of 0 -> arg <- parseIndex; return C op arg;
22:19:56<dmwit>:t delete
22:19:57<oerjan>AndyC: btw Parsec defines count which i guess is a restricted synonym for replicateM
22:19:58<lambdabot>forall a. (Eq a) => a -> [a] -> [a]
22:20:00<TomMD>nopcode: Look at Data.List (delete, deleteBy, deleteFirstBy)
22:20:17<puusorsa>.. damn
22:20:36<dmwit>AndyC: right
22:20:36<AndyC>oerjan: Thanks, I've used that elsewhere already.
22:20:39<nopcode>ok thanks
22:20:42<puusorsa>20sec too slow, almost managed to say something helpful :)
22:21:24<dmwit>AndyC: Though in the case statement, you'll need to add the "do" keyword again, because at that point you're out of the original do block.
22:21:33<TomMD>puusorsa: That would have made four. I already came in third - its no wonder our community is small, I keep forgetting people don't like being smothered.
22:22:25<AndyC>dmwit: Yeah, I tried that and I can't get it just so. Is the state after the 1st do still getting threaded into the 2nd do?
22:22:48<dmwit>AndyC: Things in scope in the first do should still be in scope in the case statement.
22:23:02<dmwit>AndyC: Why don't you paste the code you're trying to use? It will be a lot easier for us to help you.
22:23:03<dmwit>?hpaste
22:23:03<lambdabot>Haskell pastebin: http://hpaste.org/new
22:23:32<AndyC>Cos, it's on a different computer at work :-(
22:24:00<AndyC>It's my first time daring to enter. I don't know what I was afraid of.
22:24:00<dmwit>...
22:24:30<dmwit>ok
22:24:41<AndyC>I'll come back another time with something to show you. Thanks very much for your help.
22:24:49<dmwit>Well, good luck!
22:24:50<dmwit>=)
22:25:58<ddarius>He should join some other IRC channels...
22:46:35<raxas>ACTION failed miserably to coerce his girlfriend into haskell
22:47:26<dmwit>ACTION failed miserably to coerce his girlfriend into programming
22:47:42<dmwit>You're one step ahead of the game, raxas. =)
22:48:49<Spark>every so often, when we're on enough drugs, i try to teach my girlfriend about programming
22:48:56<Spark>usually she gets bored and i get frustrated and then the drugs wear off
22:49:05<dolio>That's the best time to learn stuff.
22:49:28<jonathanv>what drugs
22:49:43<Spark>amphetamine usually
22:49:51<jonathanv>gross
22:50:10<nopcode>how do i apply a function to a tuple of arguments?
22:50:23<dmwit>Same as usual, put them next to each other.
22:50:25<raxas>dmwit: Of course. We keep dating for more than 12 years now. But she said "No, I am too old for such a crazy coding."
22:50:29<dmwit>f (a, b, c)
22:50:42<jonathanv>why can't people just stick to weed
22:50:44<nopcode>nah i mean i want each element of the tuple to become one argument
22:50:46<dmwit>raxas: Hahaha, that's a pretty awesome quote.
22:50:50<Japsu>nopcode: use uncurry
22:51:02<omnId>(\(x,y,z) -> f x y z)
22:51:14<Japsu>> uncurry (\x y -> x + y) $ (1,2)
22:51:16<lambdabot> 3
22:51:24<omnId>@src uncurry
22:51:24<lambdabot>uncurry f p = f (fst p) (snd p)
22:51:28<Spark>jonathanv: maybe because it makes you fall asleep or go insane
22:51:30<omnId>already does it for (x, y)
22:51:40<Japsu>hmm
22:51:48<dmwit>> (+1) &&& concat $ (3, [[4,5],[6,7,8]])
22:51:49<lambdabot> Couldn't match expected type `[[a]]'
22:51:54<Japsu>@pl \f (x,y,z) -> f x y z
22:51:54<lambdabot>(line 1, column 8):
22:51:55<lambdabot>unexpected ","
22:51:55<lambdabot>expecting letter or digit, operator or ")"
22:51:55<lambdabot>ambiguous use of a non associative operator
22:51:56<jonathanv>if weed makes you fall asleep, maybe you need that sleep
22:52:01<dmwit>> ((+1) &&& concat) (3, [[4,5],[6,7,8]])
22:52:02<lambdabot> Couldn't match expected type `[[a]]'
22:52:03<omnId>dmwit: (***)
22:52:10<dmwit>oh, right
22:52:20<dmwit>> (+1) *** concat $ (3, [[4,5],[6,7,8]])
22:52:21<lambdabot> (4,[4,5,6,7,8])
22:53:49<Japsu>why can't I suddenly pattern match with a triplet
22:53:56<Japsu>in a lambda
22:53:57<Japsu>@pl let uc3 f (x,y,z) = f x y z in uc3
22:53:58<lambdabot>(line 1, column 15):
22:53:58<lambdabot>unexpected ","
22:53:58<lambdabot>expecting letter or digit, operator or ")"
22:53:58<lambdabot>ambiguous use of a non associative operator
22:54:06<dmwit>Japsu: You can, it's just ?pl that doesn't know about that.
22:54:09<Japsu>right
22:54:13<oerjan>Japsu: since there are no functions to unpack a triplet, @pl cannot do anything about them
22:54:21<Japsu>k
22:54:34<dmwit>> (\(x, y, z) -> x + y + z) (3,4,7)
22:54:36<lambdabot> 14
22:55:01<omnId>@type let uc3 f (x,y,z) = f x y z in uc3
22:55:02<lambdabot>forall t t1 t2 t3. (t -> t1 -> t2 -> t3) -> (t, t1, t2) -> t3
22:57:15<omnId>@pl (\f ((x,y),z) -> f x y z) -- it works if you use nested pairs, not pretty though :)
22:57:15<lambdabot>(`ap` snd) . (. fst) . (`ap` snd) . (. fst)
22:59:42<Olathe>@shorten (`ap` snd) . (. fst) . (`ap` snd) . (. fst)
22:59:42<lambdabot>Unknown command, try @list
22:59:44<Olathe>:(
23:00:02<omnId>(\f ((x,y),z) -> f x y z) -- :)
23:00:24<omnId>@type (`ap` snd) . fst
23:00:26<lambdabot>forall b a b1 b2. ((a, b1) -> b1 -> b, b2) -> (a, b1) -> b
23:00:38<oerjan>:t uncurry.uncurry
23:00:41<lambdabot>forall b c a b1. (a -> b1 -> b -> c) -> ((a, b1), b) -> c
23:02:00<oerjan>short enough? :)
23:02:08<nopcode>%)
23:06:22<ivanm>what's the difference between record-style types and "standard" types?
23:06:33<ivanm>record-style types are just named versions of the latter?
23:06:44<sjanssen>ivanm: not very much
23:06:59<ivanm>*nod*
23:07:03<Vulpyne>It's usually easier to deal with stuff by name than position.
23:07:18<Vulpyne>Especially if you reorder things or add/remove fields.
23:07:21<sjanssen>record style just introduces accessor functions and allows the {} pattern matching and update syntax
23:07:27<ivanm>so can you use record-style with pattern matching like with normal types?
23:08:07<ivanm>e.g. data FooBar = FB {foo :: String, bar :: String} ... f :: FooBar -> String, f FB f b = f ++ b
23:08:10<ivanm>would that work?
23:08:18<omnId>data T = C { x :: U } is like data T = C U; x (C a) = a
23:08:20<ivanm>make that f (FB f b)
23:08:45<ivanm>so does pattern matching work?
23:09:03<omnId>yes
23:09:28<omnId>also f (FB {foo = f, bar = b}) = f ++ b
23:09:34<ivanm>*nod*
23:09:57<ivanm>though presumably record-style makes it easier to extract one particular variable than in non-record style or by using a tuple?
23:09:57<oerjan>> case Just 1 of Just {} -> True; _ -> False
23:10:03<lambdabot> True
23:10:26<ivanm>how did that work? the {} matches everything?
23:10:57<EvilRanter>it's a curiosity of the grammar
23:11:06<ivanm>*nod*
23:11:16<EvilRanter>it's record syntax for "record with no fixed fields"
23:11:22<ivanm>ahhh
23:11:33<ivanm>so {} is equivalent to _ ?
23:11:33<EvilRanter>but it happens to work for constructors that weren't defined as records, too
23:11:45<ddarius>ivanm: No.
23:11:52<omnId>ivanm: a record pattern needs a Constructor
23:11:54<EvilRanter>it's independent of number of parameters on the constructor
23:11:55<ivanm>so is that a curiosity as defined in H98, or just implementation-specific
23:12:00<ivanm>ddarius, omnId: *nod*
23:12:10<ivanm>EvilRanter: ahhhhh
23:12:13<oerjan>H98
23:12:17<EvilRanter>> case (1,2) of (,) {} -> True; _ -> False
23:12:18<lambdabot> Warning: Pattern match(es) are overlapped
23:12:18<lambdabot> In a case alterna...
23:12:35<EvilRanter>hm. well, it parsed, so it made my point :)
23:12:39<ivanm>so its a way of pattern matching constructors rather than just the parameters?
23:12:47<ivanm>i.e. working out which constructor was used
23:12:56<omnId>Just {} is equivalent to Just _
23:13:20<oerjan>would have been nice if you could do the opposite - pattern match on a field regardless of constructor
23:13:24<omnId>say Constr has 3 fields, Constr {} is Constr _ _ _
23:13:34<ivanm>*nod*
23:13:35<oerjan>but alas
23:13:36<ddarius>oerjan: That would rarely make sense.
23:14:06<ivanm>oerjan: wouldn't that only work with constructors with the same number of parameters, and possibly the same types of parameters?
23:14:09<oerjan>ddarius: say if you have a type with two constructors that share a field
23:14:45<ddarius>I didn't say it never made sense.
23:14:58<omnId>ivanm: different constructors can share a field name, but it must have the same type.
23:15:17<ivanm>*nod*
23:15:17<omnId>data Foo = Bar { x :: String, y :: Int } | Baz { x :: String }
23:15:25<omnId>x :: Foo -> String
23:15:55<ivanm>so to access the x field, if fb :: Foo, then its just fb.x ?
23:16:06<ddarius>This isn't Java.
23:16:06<omnId>x fb
23:16:13<omnId>x is a selector function
23:16:21<ddarius>x is just a function
23:16:24<omnId>hence x :: Foo -> String
23:17:36<ivanm>oh.... I was going off this: http://research.microsoft.com/~simonpj/Haskell/records.html
23:17:43<ivanm>or is this just a proposal?
23:18:00<omnId>just a proposal
23:18:37<omnId>modifyX f foo@(Foo {x = oldx}) = foo {x = f oldx} -- a sensible modifyX definition
23:20:11<ivanm>ahhh
23:23:40<Betovsky>hi
23:23:43<Betovsky>one question
23:24:06<shapr>?
23:24:20<Betovsky> let fun = (scanl1 (*)) . enumFromTo 1
23:24:23<Betovsky>this works
23:24:32<Betovsky>let fun = (scanl1 (*)) . enumFromTo
23:24:36<Betovsky>this doesnt work
23:24:51<Betovsky>shouldnt be able to work?
23:24:59<Betovsky>being fun to receive 2 args
23:25:02<EvilRanter>?type (scanl1 (*)) . enumFromTo
23:25:03<chessguy>@type (scanl1 (*)) . enumFromTo
23:25:07<lambdabot> Couldn't match expected type `[a]'
23:25:07<lambdabot> against inferred type `a1 -> [a1]'
23:25:09<lambdabot> Couldn't match expected type `[a]'
23:25:09<lambdabot> against inferred type `a1 -> [a1]'
23:25:13<EvilRanter>?type (.)
23:25:16<lambdabot>forall b c a. (b -> c) -> (a -> b) -> a -> c
23:25:16<oerjan>. always threads exactly one argument
23:25:19<EvilRanter>?type scanl1 (*)
23:25:21<lambdabot>forall a. (Num a) => [a] -> [a]
23:25:26<EvilRanter>?type enumFromTo
23:25:28<lambdabot>forall a. (Enum a) => a -> a -> [a]
23:25:29<omnId>fun1 x = scanl1 (*) [1..x] ; fun2 x = scanl1 (*) [x .. ???]
23:25:57<EvilRanter>?src (.)
23:25:57<lambdabot>(.) f g x = f (g x)
23:25:59<Betovsky>hmm i think i see
23:26:07<EvilRanter>(f . g) x = f (g x)
23:26:13<EvilRanter>so (f . g) x y = f (g x) y
23:26:34<Betovsky>isn't there something like (.) but the second function receives 2 args?
23:26:41<omnId>@type let (f .: g) x y = f (g x y) in scanl1 (*) .: enumFromTo
23:26:43<lambdabot>forall a. (Num a, Enum a) => a -> a -> [a]
23:27:09<oerjan>@pl \f g x y -> f (g x y)
23:27:10<lambdabot>(.) . (.)
23:27:25<omnId>((f .) . g) x y = (f .) (g x) y = (f . g x) y = f (g x y)
23:27:28<chessguy>ah, the old hooter
23:27:43<omnId>@type (scanl1 (*) .) . enumFromTo
23:27:45<lambdabot>forall a. (Num a, Enum a) => a -> a -> [a]
23:28:29<Betovsky>hehe
23:28:33<Betovsky>thx
23:28:35<oerjan>more generally, you pack the first function inside as many (_ .) as you need
23:28:59<omnId>@pl \x y z -> f (g x y z)
23:28:59<lambdabot>((f .) .) . g
23:29:21<oerjan>@pl \f g x y z -> f (g x y z)
23:29:21<lambdabot>(.) . (.) . (.)
23:29:59<Betovsky>hmm
23:30:12<chessguy>by the way everyone, it's now been proven that any 2 numbers are equal to each other. all of mathematics is screwed. time to go home. http://www.mathbin.net/15013
23:30:16<lambdabot>Title: MathBin.net - Proof that any 2 numbers are equal to each other
23:31:28<oerjan>@slap chessguy
23:31:29<lambdabot>ACTION smacks chessguy about with a large trout
23:31:38<chessguy>ACTION grins
23:34:36<roconnor>conal: I made my first phooey application with a gtk2hs backend.
23:34:55<roconnor>conal: runUI (stringEntry "Initial String" >>= stringDisplay)
23:40:14<roconnor>ACTION doesn't believe that the limit of integrals is the same as the integral of a limit.
23:40:39<oerjan>indeed not without further restrictions
23:43:25<gwern>hey everyone. I remember someone once telling me that a way to improve on 'nub' performance was instead a (toList . fromList) using Data.Set or whatever, but that the latter did not produce the exact same output as the former somehow - that the better performance came at a cost
23:43:33<gwern>does anyone remember what the difference was?
23:43:43<gwern>(I'd test for myself, but my ghc is currently broken)
23:43:45<oerjan>order
23:43:59<bos>you'll get your list sorted if you pipe it through a Map or Set.
23:44:33<gwern>a Map too? but I thought it was Set's feature that it didn't admit duplicates
23:45:03<bos>it does, but if you put in [4,3,3,2,5,1], you'll get out [1,2,3,4,5]
23:45:11<bos>doesn't, that is
23:45:26<oerjan>map doesn't admit duplicates either
23:45:52<Olathe>@src nub\
23:45:52<lambdabot>Source not found. Have you considered trying to match wits with a rutabaga?
23:45:53<Olathe>@src nub
23:45:53<lambdabot>nub = nubBy (==)
23:45:56<Olathe>@src nubBy
23:45:56<lambdabot>nubBy eq [] = []
23:45:57<lambdabot>nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs)
23:46:14<gwern>huh. so what exactly is a Map then? (I know I should look this up but I'm feeling lazy)
23:46:40<EvilRanter>a map is a "function" from its key type to its value type
23:46:48<omnId>> M.fromList [(1,'a'), (2,'b')] M.! 2
23:46:50<lambdabot> 'b'
23:47:06<EvilRanter>so you can have several keys pointing to the same value, but not several instances of the same key
23:47:11<gwern>hmm. so... a little like an array then?
23:47:24<EvilRanter>a (Set a) is kinda like a (Map a ())
23:47:29<oerjan>i think you can do something hairy with zip [0..] to preserve order using map to nub
23:47:30<omnId>other languages call them hashes or associative arrays.
23:47:53<gwern>ah, I see then
23:47:57<EvilRanter>it is kinda like an array, yeah, in some respects
23:48:10<EvilRanter>but it's got different constraints on the key, and is much less space-efficient
23:48:34<EvilRanter>but better algorithmically for a lot of things; heck, it can even be more space-efficient, if your keys are very spread out
23:48:34<oerjan>actually you may not even need a map, just sortBy
23:48:35<jbauman>tail recursion?
23:48:49<jbauman>oops, scrolled up
23:49:38<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy _ _ [] = []; uniqBy eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:49:39<lambdabot> arity mismatch for 'uniqBy'
23:49:48<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy _ _ [] = []; uniqBy' eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:49:48<lambdabot> arity mismatch for 'uniqBy'
23:49:53<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (elem x ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:49:56<lambdabot> []
23:49:59<Olathe>Bah.
23:50:12<dcoutts_>@seen dons
23:50:13<lambdabot>dons is in #xmonad and #haskell. I last heard dons speak 22m ago.
23:50:53<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (eq x) ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:50:54<oerjan>Olathe: you cannot use elem
23:50:54<lambdabot> []
23:51:03<dcoutts_>dons: I'd like to do a binary 0.4.1 point release with ghc-6.4, 6.6, 6.8 compatibility
23:51:04<oerjan>too slow :)
23:51:08<omnId>(map head . group . sort) I think would do quickly enough. I'm not sure how it compares to (toList . fromList)
23:51:09<Olathe>I know.
23:51:23<Olathe>I'm doing it with a list, which can then be converted to using a set or something.
23:51:45<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq') ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:51:46<lambdabot> Parse error
23:51:50<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq`) ps) then x:(uniqBy' eq (x:ps) xs) else uniqBy' eq ps xs in uniq [5, 2, 3, 5, 4, 2]
23:51:52<lambdabot> []
23:51:54<Olathe>Bah.
23:52:23<Olathe>> let uniq = uniqBy (==); uniqBy eq = uniqBy' eq []; uniqBy' _ _ [] = []; uniqBy' eq ps (x:xs) = if (any (x `eq`) ps) then uniqBy' eq ps xs else x:(uniqBy' eq (x:ps) xs) in uniq [5, 2, 3, 5, 4, 2]
23:52:24<lambdabot> [5,2,3,4]
23:52:26<Olathe>There.
23:52:31<Olathe>Ordering is preserved.
23:52:46<oerjan>that's just nubBy
23:52:46<Olathe>Not sure how to use sets, though.
23:52:59<Olathe>Right, but you can replace the list with a set to get the speedup.
23:53:06<Olathe>With nubBy, you can't.
23:53:13<Olathe>@src nubBy
23:53:13<lambdabot>nubBy eq [] = []
23:53:13<lambdabot>nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs)
23:54:00<dons>dcoutts_: seems reasonable
23:54:05<dons>there was a 32 bit import issue anyway
23:54:09<dons>so we hvae to do a minor release
23:54:18<dons>but backporting all the constructor changes is just sucky
23:54:30<dcoutts_>dons: I've done it, it was easy
23:54:36<dcoutts_>dons: and it's easy to make bytestring-0.9 build with ghc-6.4 and 6.6
23:54:46<dcoutts_>I've got all the changes locally
23:54:58<dcoutts_>I'm just building the latest ghc snapshot so I can test with 6.8
23:55:05<oerjan>@let on e f x y = f x `e` f y
23:55:10<lambdabot>Defined.
23:55:35<dcoutts_>dons: and I'll send the changes to unix-compat and tar to bringert
23:55:40<dons>huh, http://alberrto.googlepages.com/easyvision
23:55:42<lambdabot>Title: Alberrto - easyVision
23:55:51<dons>dcoutts_: great work.
23:55:59<dons>that'll keep people happy then
23:56:04<dons>`This is an experimental Haskell system for fast prototyping of computer vision and image processing applications'
23:56:25<dcoutts_>dons: what we need is for cabal-install to support local package repos, so one can test packaging changes locally
23:56:26<Olathe>Ahh, uniqBy won't work, just uniq.
23:56:51<dcoutts_>dons: even better would be 'unpacked' local package repos
23:56:55<dons>mm
23:57:02<oerjan>> map snd . sortBy (comparing fst) . map head . groupBy ((==) `on` snd) . sortBy (comparing snd) . zip [0..] $ [5,2,3,5,4,2]
23:57:04<lambdabot> [5,2,3,4]
23:57:05<dcoutts_>dons: so that it builds from the source tree, rather than a tarball
23:57:41<dcoutts_>dons: imaging unpacking all the tarballs in a hackage repo in place, then just editing and building
23:58:10<dons>yeah
23:59:03<Olathe>> let uniq = uniq' Data.Set.empty; uniq' _ [] = []; uniq' set (x:xs) = if (Data.Set.member x set) then uniq' set xs else (x:uniq' (Data.Set.insert x set) xs) in uniq [5, 2, 3, 5, 4, 2]
23:59:05<lambdabot> [5,2,3,4]
23:59:08<Olathe>There we are.

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