Experimental IRC log haskell-2009-04-27

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:04:04<pumpkin_>wow, this is beastly
00:04:05<pumpkin_>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2246#a2246
00:04:18<pumpkin_>it begs for CSE
00:05:00<monochrom>information wants to be freed? code wants to be CSEed?
00:05:31<mauke>malloc() wants to be free()d
00:05:34<pumpkin_>:P
00:05:41<monochrom>hehehe
00:05:54<monochrom>@remember mauke malloc() wants to be free()d
00:05:55<lambdabot>I will never forget.
00:06:52<pumpkin_>my code is so applicative
00:06:54<pumpkin_>yet so ugly
00:08:05<SubStack>rewrite it in c
00:08:09<pumpkin_>lol
00:08:28<SubStack>then it will look very pretty by comparison
00:08:46<pumpkin_>I dunno, this is pretty ugly
00:09:06<pumpkin_>it's a direct translation of http://github.com/unmarshal/hstats/blob/da695128f67a2e9e32337b30cc2abb17d16a5457/src/Math/Statistics.hs to my folds
00:09:11<wli>I think pretty much everywhere expressions can recurse have to go from expr to (expr, Maybe typeQualifier) or some nightmare like that.
00:10:14<ray>stop saying "my folds" pumpkin_
00:10:19<ray>it's a bit creepy
00:10:20<wli>A few other places need it, too, like left hand sides of let bindings, lambda-bound variables, and so on.
00:10:28<pumpkin_>ray: my humps? my lovely lady lumps
00:10:28<ray>you might as well say "my pretties"
00:10:57<ray>i was thinking more wicked witch of the west
00:11:17<mauke>oh, is that what www stands for?
00:11:20<wli>Maybe even variables bound by label extraction in case statements.
00:13:16<EvilTerran>pumpkin_, i think defining, say, (|*|), (|/|), and (|-|) as liftA2'd versions of (*), (/), and (-) would help
00:13:21<EvilTerran>slightly
00:13:25<pumpkin_>probably :P
00:13:37<pumpkin_><^^> looks kind of like a bat
00:13:56<ray><^_^>
00:13:57<Axman6>ACTION was about to suggest ^*^, ^/^ and ^_^
00:14:02<EvilTerran>ACTION grumbles about the naming of <*>
00:14:15<EvilTerran>otherwise, the obvious choice would be <*> </> <->
00:14:26<ray>stupid applicative
00:14:28<EvilTerran>ACTION would've just called it <> or something
00:14:38<EvilTerran>"f <$> x <> y <> z"
00:14:58<pumpkin_>yeah
00:15:08<pumpkin_>not a fan either
00:15:11<adamvo>what about *>
00:15:20<Axman6>Applicative i think
00:15:27<Axman6>@hoogle (*>)
00:15:27<lambdabot>Control.Applicative (*>) :: Applicative f => f a -> f b -> f b
00:15:28<lambdabot>Control.Applicative (<**>) :: Applicative f => f a -> f (a -> b) -> f b
00:15:28<lambdabot>Control.Applicative (<*>) :: Applicative f => f (a -> b) -> f a -> f b
00:15:36<EvilTerran>... actually, <$> would make most sense as the name for <*>, as then an (OP) :: a -> b -> c would suggest (<OP>) :: Applicative f => f a -> f b -> f c
00:15:38<mmmulani>is the expected type, the type present?
00:16:04<ray>who writes these haskell standard libraries anyway, jeez
00:16:13<mauke>mmmulani: expected type: what the context around it wants; inferred type: what the thing itself provides
00:16:18<EvilTerran>(< ... >) as an outerfix adoperator
00:16:19<EvilTerran>:P
00:16:33<mmmulani>ouuuu
00:16:48<EvilTerran>(the "ad-" in "adoperator" as in "adverb")
00:16:54<mauke>>
00:17:02<ray>operigatoni
00:17:06<mauke>> 'x' == ()
00:17:08<lambdabot> Couldn't match expected type `Char' against inferred type `()'
00:17:24<mauke>('x' ==) is the context. it wants another Char
00:17:28<mauke>() itself has the type ()
00:18:05<mmmulani>would (map (\x->[x,x]) [1..10]) provide the type [[Int] -> Int]?
00:18:08<adamvo>> map isUpper "()"
00:18:09<lambdabot> [False,False]
00:18:31<mauke>:t map (\x->[x,x]) [1..10]
00:18:32<lambdabot>forall a. (Enum a, Num a) => [[a]]
00:18:46<mauke>no, just [[Int]]
00:18:49<mmmulani>hmmmm
00:19:25<gwern>@quote crap
00:19:26<lambdabot>gzl says: [on why monads are scary] maybe it's because people look up monad on wikipedia, find the category theory page, and crap themselves
00:19:29<gwern>@quote crap
00:19:29<lambdabot>gzl says: [on why monads are scary] maybe it's because people look up monad on wikipedia, find the category theory page, and crap themselves
00:19:41<gwern>@quote magical.*evil
00:19:41<lambdabot>No quotes match. Are you on drugs?
00:19:50<pumpkin_>well, the fold composition version doesn't stack overflow on large lists, and the hstats one does
00:19:53<pumpkin_>so I guess that's my comparison
00:20:00<gwern>@quote Gracenotes foldr chosen for its magical evil terminating powers
00:20:00<lambdabot>No quotes match. :(
00:20:03<gwern>@remember Gracenotes foldr chosen for its magical evil terminating powers
00:20:04<lambdabot>I will remember.
00:20:18<gwern>@quote lisp.*to.*haskell
00:20:18<lambdabot>dons says: you start with lisp, get to statically typed lisp (ML), add laziness, add whitespace to solve the parens stuff, add syntax sugar (for human programmability), and finally, add purity (i.e.
00:20:18<lambdabot>true functional programming), and you've got haskell
00:20:22<gwern>@quote lisp.*to.*haskell
00:20:22<lambdabot>dons says: you start with lisp, get to statically typed lisp (ML), add laziness, add whitespace to solve the parens stuff, add syntax sugar (for human programmability), and finally, add purity (i.e.
00:20:23<lambdabot>true functional programming), and you've got haskell
00:20:36<gwern>@remember uninverted Moving from lisp to haskell with respect to functions is like moving from c to perl with respect to strings.
00:20:36<lambdabot>Done.
00:20:40<Axman6>gwern: that was me technically
00:20:51<gwern>@forget uninverted Moving from lisp to haskell with respect to functions is like moving from c to perl with respect to strings.
00:20:51<Axman6>the magical evil terminating one
00:20:51<lambdabot>Done.
00:20:58<gwern>gah
00:21:02<Axman6>heh
00:21:04<gwern>@remember uninverted Moving from lisp to haskell with respect to functions is like moving from c to perl with respect to strings.
00:21:05<lambdabot>I will remember.
00:21:11<gwern>@forget Gracenotes foldr chosen for its magical evil terminating powers
00:21:11<lambdabot>Done.
00:21:17<gwern>@remember Axman6 foldr chosen for its magical evil terminating powers
00:21:17<lambdabot>Good to know.
00:21:20<gwern>phew!
00:21:21<Gracenotes>wha
00:21:22<pumpkin_>ACTION needs more power!!!
00:21:22<Axman6>:P
00:21:28<gwern>@quote infinitely.*fast
00:21:28<lambdabot>Berengal says: [On infinitely fast computers] The OS probably has a failsafe built in: If a program is running it's in an infinite loop and needs to be killed...
00:21:40<gwern>@quote functions.*crap
00:21:40<lambdabot>nikki93 says: After a bit more delving, I've come to see the power of haskell at last. You have to treat functions like crap, forget about the C idea that they're 'big things'. They're not.
00:21:48<gwern>@quote fix.*error
00:21:48<lambdabot>Berengal says: I was squashing a bug, got frustrated, and typed "fix error" in ghci...
00:21:51<gwern>@flush
00:22:33<Axman6>what's @flush do? saves stuff to dick?
00:22:37<Axman6>disk -_-
00:22:47<Gracenotes>actually, Axman6, I think I deserve credit for that quote
00:23:00<Gracenotes>"Axman6's reinterpretation of Gracenotes"
00:23:05<Axman6>well, you do, but that version of it was mine
00:23:12<pumpkin_>@remember Axman6 what's @flush do? saves stuff to dick?
00:23:13<lambdabot>Okay.
00:23:21<ray>we'll settle this in the ring
00:23:21<Axman6>>_<
00:23:27<Gracenotes>I licensed it under CC-by-SA, you don't think you can get away with using it without attribution?
00:23:32<Gracenotes>and an explicit CC license?
00:23:37<Axman6>leave me alone, i just woke up and i haven't had nearly enough sleep :(
00:23:55<Gracenotes>NO I WILL SUE IN A COURT OF LAW IN TRENTON, NJ
00:23:59<pumpkin_>http://github.com/pumpkin/folds/blob/09863966c1b701da5f9cc5ecdc5f3246ca48a905/Folds.hs :P
00:24:05<Gracenotes>YOU JUST WATCH IT SIR
00:24:08<gwern>Gracenotes: come on, no one here knows that
00:24:10<Axman6>gwern: good luck with the extradition :)
00:24:12<Elly>best court case ever
00:24:14<Axman6>uh, Gracenotes
00:24:24<Gracenotes>gwern: just for you
00:24:32<gwern>ACTION feels obscurely pleased
00:24:36<gwern>SOLLOG KNEW WHY
00:24:41<Axman6>ACTION missed the joke
00:25:01<floyd>is there any way to modify an element in a list of tuples?
00:25:17<pumpkin_>map first/second f
00:25:19<Axman6>:t first
00:25:21<lambdabot>forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a (b, d) (c, d)
00:25:28<Gracenotes>[¬º-°]¬
00:25:30<Axman6>:t first id
00:25:32<lambdabot>forall a d. (a, d) -> (a, d)
00:25:37<Axman6>hmm, bad example
00:25:38<pumpkin_>> map (first (+1) (zip [1..10] [2..11])
00:25:39<lambdabot> <no location info>: parse error on input `;'
00:25:42<pumpkin_>> map (first (+1)) (zip [1..10] [2..11])
00:25:44<lambdabot> [(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11)]
00:25:44<Elly>what the hell? how is that first
00:25:50<Axman6>:t first fromJust
00:25:51<lambdabot>forall a d. (Maybe a, d) -> (a, d)
00:26:03<Gracenotes>@type first `asTypeOf` (undefined::a->b->c)
00:26:05<lambdabot>forall b c d. (b -> c) -> (b, d) -> (c, d)
00:26:05<gwern>@hoogle first
00:26:05<lambdabot>Control.Arrow first :: Arrow a => a b c -> a (b, d) (c, d)
00:26:05<lambdabot>Data.Monoid newtype First a
00:26:05<lambdabot>Data.Monoid First :: Maybe a -> First a
00:26:16<gwern>oh, it's an arrow thing
00:26:22<Gracenotes>@type second `asTypeOf` (undefined::a->b->c)
00:26:23<lambdabot>forall b c d. (b -> c) -> (d, b) -> (d, c)
00:26:28<Elly>@type id
00:26:30<lambdabot>forall a. a -> a
00:26:32<pumpkin_>Gracenotes: `asTypeOf` (undefined :: T) === :: T :P
00:26:38<Gracenotes>o rly
00:26:45<Gracenotes>@type second :: a->b->c
00:26:46<lambdabot> Couldn't match expected type `a' against inferred type `b -> c'
00:26:47<lambdabot> `a' is a rigid type variable bound by
00:26:47<lambdabot> the polymorphic type `forall a b1 c1. a -> b1 -> c1'
00:26:50<Gracenotes>failure.
00:26:57<pumpkin_>zomg
00:27:01<pumpkin_>ACTION failz
00:27:05<Axman6>-_-
00:27:11<Gracenotes>yeah, just when you want to unify it, not type it
00:27:13<mauke>:t second `asTypeOf` fmap
00:27:15<lambdabot>forall b c d. (b -> c) -> (d, b) -> (d, c)
00:27:16<pumpkin_>aha
00:27:23<pumpkin_>nice
00:27:35<Axman6>my laptop is not warm enough! i needs moar project euler
00:27:39<pumpkin_>ACTION lurnz noo stuff evury day by being a douchebag
00:27:46<Gracenotes>:t first `asTypeOf` fmap -- but :o
00:27:48<lambdabot>forall b. (b -> b) -> (b, b) -> (b, b)
00:28:16<gwern>dang it. I've been stressing with 'ab' gitit for an hour and a half now, and memory has only increased 1.8x
00:28:37<gwern>is this enough for my profiling to tell me the memory? enquiring minds want to know but dare not kill gitit to find out!
00:28:53<Gracenotes>pumpkin_: don't worry, I teach people things every day by being a douchebag! Okay, that was a joke, people.
00:29:05<pumpkin_>I'm tempted to make folds into Num/Fractional/RealFloat instances
00:29:09<pumpkin_>but that would feel really dirty
00:29:19<ray>do it
00:29:29<Axman6>gwern: it's a wiki right? edit a whole bunch of pages (or turn off any anti spam stuff for a few days)
00:29:29<Gracenotes>weird Num instances are unnatural :o
00:29:36<pumpkin_>it's cuz GHC isn't giving me the power I desire!!!!
00:29:42<ray>weird num instances are the lifeblood of haskell
00:30:08<Gracenotes>I mean, usually people think as Nums as concrete types -- they're working with typeclass methods, but thinking like they're Ints or Doubles or suchlike
00:30:16<Axman6>pumpkin_: no my son, it is you who is not giving GHC the power it needs
00:30:25<gwern>I recently enjoyed defining (+) on lists; but I kept it normal and just defined it as (++)
00:30:34<pumpkin_>@src Num
00:30:35<lambdabot>class (Eq a, Show a) => Num a where
00:30:36<lambdabot> (+), (-), (*) :: a -> a -> a
00:30:36<lambdabot> negate, abs, signum :: a -> a
00:30:36<lambdabot> fromInteger :: Integer -> a
00:30:43<Axman6>ACTION hopes you all read that in a deep fatherly voice
00:30:48<pumpkin_>nice, I can define all of those :P
00:30:57<Gracenotes>fromInteger 4 = replicate 4 undefined >_>
00:31:09<Gracenotes>works for [a].
00:31:16<pumpkin_>lol
00:31:26<Gracenotes>well. fromInteger n. and you'd have go Integer -> Int
00:32:02<Gracenotes>gwern: have you taken Eastern Religions?
00:32:05<pumpkin_>oh, I can't do fromInteger
00:32:40<wli>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2245#a2247 <-- still needs substantial work
00:32:41<gwern>Gracenotes: I took a course on indian philosophy (focusing on buddhism & hinduism); just 'Eastern Religions' sounds way too basic for me
00:33:15<Gracenotes>gwern: mm, yeah, I'd imagine. But it's a basic historical and cultural overview of Taoism, Buddhism, Hinduism, and Confucianism
00:33:29<Gracenotes>AAS 102
00:33:34<gwern>sounds seriously dull
00:33:41<pumpkin_>okay, I really hate the numeric typeclasses
00:33:46<pumpkin_>(just in case anyone wondered)
00:33:47<gwern>those schools aren't interesting until you get into the details
00:33:50<pumpkin_>!!!
00:34:09<Gracenotes>hm. Well I need a DEC B >_>
00:34:18<gwern>like nagargjuna and madhyamika is dull as heck to read about, until you read his verses on the middle way, and blow your brain trying to understand his arguments and how/whether they're fallacious
00:34:21<Axman6>i had an idea last night about how to make my AVar semi-stomic variables into actually atomic variables
00:34:33<Axman6>but i'll have to wait a week to implement it :(
00:34:36<gwern>Gracenotes: why not take a higher course than that?
00:34:57<Gracenotes>well, I have to take something in the DEC B category: http://www.sunysb.edu/ugrdbulletin/current/coursesbyDEC.pdf
00:35:22<Gracenotes>The Bible as Literature is more high-level. But possibly boring I suspect, and filled with Christians
00:35:41<gwern>Gracenotes: I'd avoid 'as Literature'; if it were real higher criticism, then it'd be worthwhile
00:35:51<kerlo>> map (map (*)) [1,2,3] [4,5,6]
00:35:52<lambdabot> Couldn't match expected type `[t1] -> t'
00:35:57<Gracenotes>mm. So any DEC B suggestions then? >_>
00:36:10<kerlo>I didn't expect that to work anyway. :-P
00:36:12<gwern>Gracenotes: but as literature is just an invitation for a load of bullshit and people rationalizing away the flaws and inconsistencies and politics
00:36:31<mauke>> liftM2 (*) [1,2,3] [4,5,6]
00:36:33<lambdabot> [4,5,6,8,10,12,12,15,18]
00:36:37<gwern>Gracenotes: from the looks of it, it's just listing the punishment detail^W^Wintroductory classes guaranteed to be offered
00:36:44<kerlo>ACTION applauds
00:36:56<Gracenotes>gwern: yeah. required to take one.
00:36:59<gwern>Gracenotes: I would seriously doubt that if you took one of the higher classes on the real philosophy/theology, that it couldn't be applied
00:37:31<Gracenotes>oh, they apply. But for different categories.
00:37:46<gwern>Gracenotes: why not ask one of the professors?
00:38:27<floyd>how can i insert an item into a list by index?
00:38:28<Axman6>quick question, what's the emacs curcor keyboard command (^W) for moving back a word?
00:38:35<gwern>..oh, this is real helpful output - 'MAIN 83% RAM'
00:38:41<gwern>Axman6: M-b?
00:38:43<Gracenotes>gwern: because I have no philosophical background whatsoever? :)
00:38:56<gwern>sink or swim then!
00:39:02<Axman6>gwern: seems to be it, ta :)
00:39:48<Axman6>Gracenotes: intro to poetry, or intro to cinema
00:40:12<Axman6>poetry's good stuff
00:40:33<Axman6>gets the brain working in ways geeks like us are probably not all that used to
00:41:19<Gracenotes>I'm disappointed there's no Japanese cinema course
00:41:31<gwern>Gracenotes: you checked solar?
00:41:46<Gracenotes>although there's an Asian cinema. And, still, a different DEC category
00:42:57<Gracenotes>ACTION watched Suicide Club yesterday. Weird film.
00:43:23<mauke>what's the first rule of suicide club?
00:43:36<Gracenotes>to be connected to yourself
00:43:46<Gracenotes>... sorta.
00:44:11<pumpkin_>meanF = sumF / genericLengthF
00:44:22<pumpkin_>geometricF = productF ** (recip genericLengthF)
00:44:24<pumpkin_>ACTION feels dirty
00:44:48<mauke>pumpkin_: here, have some fun: http://mauke.ath.cx/stuff/haskell/fun.hs
00:44:49<Gracenotes>you might not able able to define a general Num instance, but maybe a qualified Num instance
00:44:59<pumpkin_>mauke: you already showed me that, and it was awesome
00:45:05<pumpkin_>but I had to take two showers after playing with it :P
00:45:10<mauke>huhu
00:45:27<pumpkin_>check out my abomination: http://github.com/pumpkin/folds/blob/5e28e1e13f590381d15e8bff8ef1c44716cfddcd/Folds.hs
00:45:41<roconnor>Does Haskell FM use any reactive framework?
00:45:52<Gracenotes>pumpkin_: just have "instance Eq (Fold a b)"
00:46:05<pumpkin_>Gracenotes: then it bugs me
00:46:21<pumpkin_>I guess I can define eq
00:46:25<pumpkin_>and even show
00:46:25<Gracenotes>the compiler will complain about unimplemented methods, but then you can just go right back and tell it to shut the hell up
00:46:30<pumpkin_>but I refuse to, on principle
00:46:35<Gracenotes>politely.
00:46:43<pumpkin_>"shut the fuck up GHC"
00:46:48<pumpkin_>like that?
00:46:59<Gracenotes>perhaps. You just need some practice
00:47:23<Gracenotes>compiler invective is an art, they say
00:47:43<mauke>alias ghc='ghc 2>/dev/null'
00:49:05<pumpkin_>lol
00:49:12<pumpkin_>for the confident programmer
00:49:34<gwern>@quote ghc
00:49:34<lambdabot>ghc says: Oops! Entered absent arg
00:49:51<gwern>some programmers are absent-minded; ghc is absent-arged
00:50:53<wli>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2245#a2248 <-- I still need help with this
00:52:01<wli>e.g. where do signatures come in? where do sharing constraints come in?
00:57:45<pumpkin_>oh, I can do my nasty stuff with applicative-numbers instead
00:58:52<pumpkin_>conal: how do I use applicative-numbers? :P
01:00:49<mmmulani>what is wrong with this code:
01:00:50<mmmulani>let myfilter comp (a:as) (b:bs) = if (comp a b) then (a,b):(myfilter comp as bs) else (myfilter comp as bs)
01:00:50<conal>pumpkin_: did you see the comments in the source?
01:01:00<pumpkin_>ah, nope
01:01:17<pumpkin_>ACTION looks
01:01:26<Axman6>mmmulani: looks ok to me
01:01:30<conal>pumpkin_: i better move them to the .cabal, so they'll show up on Hackage.
01:01:43<mmmulani>Axman6: ghci gives me an indentation error with it :/
01:01:47<Axman6>:t let myfilter comp (a:as) (b:bs) = if (comp a b) then (a,b):(myfilter comp as bs) else (myfilter comp as bs) in myfilter
01:01:49<lambdabot>forall t t1. (t -> t1 -> Bool) -> [t] -> [t1] -> [(t, t1)]
01:02:14<pumpkin_>I'll try it in a bit, thanks :)
01:02:29<MyCatVerbs>mmmulani: looks like you want base cases for empty lists too, though.
01:02:48<Axman6>oh yes, of course
01:02:53<mmmulani>MyCatVerbs: yeah, I have that a line before
01:03:21<Axman6>mmmulani: what's it look like?
01:03:45<mmmulani>let myfilter comp [] [] = []
01:04:16<Axman6>might want to make it myfilter comp [] bs = []
01:04:27<Axman6>and myfilter comp as [] = []
01:04:40<Axman6>:t curry
01:04:42<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
01:04:48<MyCatVerbs>> let myfilter comp l1 l2 = filter (uncurry comp) (zip l1 l2) in myfilter (\a b -> (a + b) == 0) [0,1,2,3] [1,-1,-4,-3] -- shorter version, unless I made a typo somewhere.
01:04:50<lambdabot> [(1,-1),(3,-3)]
01:05:16<mmmulani>MyCatVerbs: ouuuu
01:05:27<Axman6>:t let f comp as bs = filter (uncurry comp) . zip as $ bs in f
01:05:29<lambdabot>forall a b. (a -> b -> Bool) -> [a] -> [b] -> [(a, b)]
01:05:33<MyCatVerbs>That one handles lists of unequal lengths just by truncating the longer one (which behavoir it gets from the use of "zip").
01:07:08<duaneb>how can I enquire about the host system?
01:07:11<duaneb>i.e. endian
01:07:13<MyCatVerbs>Unless you've put in cases for when one list ends before the other does, your myfilter will hit a pattern match error at the end of the shorter list. Also, you might want to use a name like "zipAndFilter" because that's what you're doing. =)
01:07:29<mmmulani>ohhh
01:07:37<mmmulani>I still need to learn zip
01:08:22<duaneb>or even just the processor
01:09:31<mmmulani>hmmm
01:09:42<mmmulani>is there anything wrong with the following line in a .hs?
01:09:43<mmmulani>let cs = (map (\x -> ((x^2),x)) [1..500])
01:09:51<MyCatVerbs>duaneb: unless there's something on Hackage for it specifically (I haven't checked), I don't think there is anything in the standard libraries. Why do you need to know the CPU's endian-ness?
01:10:06<mmmulani>I can run and view 'cs' fine in ghci
01:10:08<duaneb>MyCatVerbs: binary io
01:10:10<MyCatVerbs>mmmulani: you don't write "let" statements at toplevel.
01:10:23<sjanssen>duaneb: there is an endianness package on hackage
01:10:30<lpsmith>mmmulani: just remove the "let" and you'll be fine
01:10:31<mmmulani>MyCatVerbs: *facepalm*
01:10:33<MyCatVerbs>duaneb: is there some reason why you can't use Data.Binary?
01:10:43<duaneb>Because that's not in the default install
01:10:44<duaneb>and I'm lazy
01:10:51<duaneb>I just want to know what endian I'm on
01:10:53<sjanssen>duaneb: lame excuse
01:11:04<duaneb>sjanssen: I shouldn't have to install 3rd party software....
01:11:05<MyCatVerbs>ACTION thwaps sjanssen with a rolled-up combinator.
01:11:18<sjanssen>duaneb: do it with Foreign.*
01:11:31<bremner>duaneb: if you care, you should be able to write a C program to check
01:11:33<MyCatVerbs>duaneb: Hackage is Haskell's equivalent of CPAN. Everything in there is fine to use.
01:11:41<dibblego>which extension allows me to load a source file with #ifdef into ghci?
01:11:50<sjanssen>but if you're too lazy to install the available packages, I'm too lazy to write your code for you
01:12:12<MyCatVerbs>duaneb: -XCPP, I think.
01:12:22<duaneb>ok
01:12:23<MyCatVerbs>Er, dibblego, not duaneb, sorry.
01:12:30<duaneb>well
01:12:32<duaneb>hrm
01:12:41<dibblego>MyCatVerbs, that got it, ta
01:12:43<duaneb>I'll look at what Data.Binary does
01:14:27<MyCatVerbs>duaneb: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary <- reasonably fast, reasonably convenient, very well supported. Lets you write combinators that produce ByteStrings, and binary IO on ByteStrings is fairly quick.
01:16:08<duaneb>ahh smart
01:16:18<duaneb>it just lets Haskell do the work for it
01:16:31<duaneb>huh
01:16:31<duaneb>ok
01:16:36<duaneb>MyCatVerbs: Actually, I will
01:16:39<duaneb>!
01:16:58<MyCatVerbs>\o/
01:17:23<alkaid>hi, I'm new to haskell and I'm having a stack overflow problem
01:17:32<alkaid>can someone help me ?
01:17:57<alkaid>exit
01:18:21<Axman6>o.O
01:18:21<MyCatVerbs>...
01:18:33<duaneb>haha
01:18:44<MyCatVerbs>I was in the middle of digging up the IMDB quote from "Demolition Man" to greet alkaid with.
01:19:02<sjanssen>kids today can't wait more than 60 seconds for help
01:19:02<lambdabot>sjanssen: You have 1 new message. '/msg lambdabot @messages' to read it.
01:19:04<MyCatVerbs>Talk about a short attention span. oO
01:19:19<sjanssen>@seen ivanm
01:19:20<lambdabot>ivanm is in #gentoo-haskell. I last heard ivanm speak 6m 19s ago.
01:20:15<sjanssen>@msg #gentoo-haskell ivanm, sjanssen is available at this time, you do not need to use me as a proxy :)
01:21:52<Axman6>alkaid: you right?
01:22:01<Axman6>didn't even wait for an answer...
01:22:25<MyCatVerbs>alkaid: Mellow greetings. What seems to be your boggle?
01:22:30<alkaid>axman
01:22:36<Axman6>hi
01:22:51<alkaid>sorry, I didn't now how to use the irc client I was using
01:23:18<Axman6>you had a stack overflow error?
01:23:20<alkaid>I'm trying to make a very, very simple factorial function and it gives a stack overflow
01:23:31<MyCatVerbs>Heh. And we were all just worried that you might've taken too many stimulants and ran off the deep end of your attention span. ;)
01:23:34<Axman6>what's the code?
01:23:37<MyCatVerbs>@where hpaste
01:23:38<lambdabot>http://hpaste.org/
01:23:40<duaneb>so how can I combine a Word8 and a Word16?
01:23:50<MyCatVerbs>Please to be hpasting your code so we can read it. ^^
01:23:53<MyCatVerbs>duaneb: combine how?
01:23:58<Axman6>duaneb: fromIntegral
01:24:19<duaneb>ahh fromIntegral
01:24:19<alkaid>the simplest I could imagine: fac 0 = 1 fac n = n*(fac n-1)
01:24:31<alkaid>(with line break)
01:24:40<sjanssen>alkaid: you mean: fac (n-1) :)
01:24:48<Axman6>and it crashes with large inputs?
01:24:49<alkaid>hum...
01:24:56<MyCatVerbs>alkaid: yep. That blows up because it builds up a long chain of, (n * (n * (n * (n ...)))
01:24:58<Axman6>uh yes, you need fac (n-1)
01:24:58<sjanssen>alkaid: what you wrote is "(fac n)-1" which is obviously an infinite loop
01:24:59<duaneb>you're actually calling n*fac(n)-1
01:25:04<duaneb>which is very different
01:25:16<alkaid>any input will give an error message except 0
01:25:19<duaneb>err (fac n)
01:25:26<alkaid>Ahhhh!!
01:25:33<MyCatVerbs>alkaid: function application binds tighter than the - operator.
01:25:41<duaneb>do this instead: fac n = n * (fac (n - 1))
01:25:59<alkaid>wow, that was a stupid mistake!
01:26:00<alkaid>hahaha
01:26:04<alkaid>thanks for your help
01:26:24<Axman6>alkaid: there's a good chance it'll crash with large inputs too
01:26:26<alkaid>I have to pay more attention to operator precedence
01:26:49<alkaid>Axman - I see.
01:26:53<MyCatVerbs>alkaid: just spam parens until you know it off by heart. :)
01:26:58<Axman6>a tail recursive one will probably be more efficient
01:27:31<MyCatVerbs>> let { fac 0 = 1 ; fac n = n * fac (n-1) } in fac 1000000
01:27:34<lambdabot> * Exception: stack overflow
01:27:41<MyCatVerbs>> let { fac 0 = 1 ; fac n = n * fac (n-1) } in fac 100
01:27:43<lambdabot> 933262154439441526816992388562667004907159682643816214685929638952175999932...
01:28:00<Axman6>let fac n = fac' n 1 where fac' 1 x = x; fac' !n !x = fac' (n-a) (x*n) in fac 10203040
01:28:01<MyCatVerbs>Works for smaller values, aye? Up to about, oh, ten thousand or something?
01:28:13<alkaid>right
01:28:19<alkaid>thanks again
01:28:24<Axman6>let fac n = fac' n 1 where fac' 1 x = x; fac' !n !x = fac' (n-a) (x*n) in fac 10203
01:28:29<MyCatVerbs>Whereas the tail-recursive one, using an accumulator, works for arbitrarily big input.
01:28:37<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' !n !x = fac' (n-a) (x*n) in fac 10203
01:28:39<lambdabot> <no location info>: Illegal bang-pattern (use -XBangPatterns)
01:28:40<alkaid>another thing: to make lambdabot evaluate an expression I just put it after a > sign?
01:28:41<Axman6>duh
01:28:53<MyCatVerbs>> "Yes, alkaid."
01:28:55<lambdabot> "Yes, alkaid."
01:28:57<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-a) (x*n) in fac 10203
01:28:59<alkaid>nice!
01:29:00<alkaid>:D
01:29:12<MyCatVerbs>It's meant to mimic bird notation. :)
01:29:13<lambdabot> thread killed
01:29:33<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-a) (x*n) in fac 1020
01:29:41<Axman6>...
01:29:46<alkaid>Axman - I'll need some time to understand this expression. Just a min.
01:29:48<lambdabot> thread killed
01:29:51<sjanssen>Axman6: maybe take this to a PM?
01:30:12<sjanssen>you can let us know when you find the limit :)
01:30:12<Axman6>well now i'm curious why it's not working :)
01:30:23<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-a) (x*n) in fac 10
01:30:24<sjanssen>Axman6: isn't fac 1020 really huge?
01:30:39<lambdabot> thread killed
01:30:39<Axman6>urgh, i now
01:30:40<Axman6>know*
01:30:45<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in fac 10
01:30:49<lambdabot> 3628800
01:30:56<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in fac 1000
01:31:00<lambdabot> 402387260077093773543702433923003985719374864210714632543799910429938512398...
01:31:16<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in length . show . fac $ 10000
01:31:20<lambdabot> 35660
01:32:01<Axman6>surprised it didn't whinge about the a in that expression
01:33:12<MyCatVerbs>sjanssen: eh, fac 100000 only takes eleven or so seconds to compute in GHCi on my machine. :)
01:33:24<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in length . show . fac $ 100000
01:33:40<lambdabot> thread killed
01:33:44<duaneb>MyCatVerbs: you have too much time on your hands
01:33:47<MyCatVerbs>Axman6: it's funny that it takes quadratic time and linear space anyway, just because the numbers being multiplied by gmp keep getting progressively larger. =)
01:34:05<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in logBase 10 . fromIntegral . fac $ 100000
01:34:21<lambdabot> thread killed
01:34:24<Axman6>> let fac n = fac' n 1 where fac' 1 x = x; fac' n x = x `seq` fac' (n-1) (x*n) in logBase 10 . fromIntegral . fac $ 10000
01:34:44<lambdabot> thread killed
01:34:52<alkaid>Axman - I think I understand your expression now, except for the `seq`
01:35:15<alkaid>is this related to threading?
01:35:18<Axman6>alkaid: it's just there to make sure that x doesn't form a huge thunk
01:35:51<alkaid>this forces an evaluation or something like that?
01:35:51<Axman6>no, seq evaluates its first argument to weak head ormal form, then returns its second argument.
01:35:55<duaneb>wait, are lists in haskell linked?
01:35:55<Axman6>yep
01:36:03<Axman6>duaneb: yep
01:36:05<duaneb>sadness.
01:36:08<Axman6>?
01:36:30<duaneb>I'm trying to make a lookup table
01:36:38<duaneb>ACTION finds an array module
01:36:43<alkaid>thanks again!!
01:36:46<sjanssen>duaneb: Data.Map is most recommended
01:36:53<Axman6>beat me to it
01:36:58<alkaid>this is a very nice channel
01:37:05<alkaid>:D
01:37:08<alkaid>bye
01:37:14<Axman6>o/
01:37:57<duaneb>hmm
01:37:58<duaneb>ok, that works
01:39:07<duaneb>wait, is map a tree or something?
01:39:13<Axman6>yes
01:39:17<duaneb>ahh
01:39:17<duaneb>ok
01:39:22<duaneb>umm
01:39:25<duaneb>how can I make one? :P
01:39:46<duaneb>I don't need much; just what might be an immutable array in c
01:39:49<duaneb>a static array
01:39:57<Axman6>fromList is one way
01:40:01<duaneb>ok
01:40:23<Axman6>(which is infact the way they're shown when you print them, fromList <the list of elements pairs>)
01:41:26<Axman6>> fromList [(1,'1'),(2,'2')]
01:41:28<lambdabot> Not in scope: `fromList'
01:41:34<Axman6>> Data.Map.fromList [(1,'1'),(2,'2')]
01:41:35<lambdabot> /tmp/3297113489689806087:70:48: Not in scope: `Data.Map.fromList'
01:41:39<Axman6>lame
01:41:46<Axman6>@hoogle fromList
01:41:46<lambdabot>Data.HashTable fromList :: Eq key => (key -> Int32) -> [(key, val)] -> IO (HashTable key val)
01:41:47<lambdabot>Data.IntMap fromList :: [(Key, a)] -> IntMap a
01:41:47<lambdabot>Data.IntSet fromList :: [Int] -> IntSet
02:20:05<dibblego>does Josef Svenningsson (author Data.Set.BKTree) hang out here?
02:22:50<Apocalisp>How about Jeff Wheeler?
02:23:13<pumpkin_>@seen jeffwheeler
02:23:13<lambdabot>I saw jeffwheeler leaving #yi 2h 1m 22s ago, and .
02:23:30<Apocalisp>thanks
02:23:58<Apocalisp>I want to submit a patch to pointedlist
02:24:18<Apocalisp>Oh, his email's on Hackage
02:24:25<Apocalisp>fancy that
02:24:32<dibblego>yeah I just emailed Josef
02:29:07<kadaver>http://www.reddit.com/r/programming/comments/8fj0p/some_misconceptions_on_tail_recursion/
02:29:17<kadaver>^^ does thta mean mergesort is O(n^2) in haskell ?
02:29:27<kadaver>haskell doesnt do proper tailrecursion right?
02:29:31<pumpkin_>:o
02:29:47<pumpkin_>sure it does
02:30:13<pumpkin_>but the waters are muddied by laziness
02:31:51<roconnor>the whole idea of tail-recursion is made so bizarre by laziness it is hardly worth talking about at all.
02:32:07<Gracenotes>laziness improves algorithmic time in many cases
02:32:41<Gracenotes>immutability rarely improves time... but I suppose having it means that you can assume certain things and make little optimizations
02:32:42<roconnor>is merge sort (in ML) really O(n^2) without TCO
02:34:51<roconnor>that strikes me as really unlikely
02:35:30<sjanssen>kadaver: where does it say mergesort is O(n^2)?
02:35:53<glguy>if Haskell didn't do tail recursion, we'd be in a world of hurt as our programs are built up of >>= s
02:36:12<pumpkin_>or tail-call optimization at least
02:36:28<glguy>yes, tail calls
02:36:32<roconnor>I don't even know that tail call means in Haskell
02:36:44<roconnor>the guts of a function are evaluated at random times
02:36:59<roconnor>a little here, a little more there
02:37:10<roconnor>some at the end, some at the beginning.
02:37:23<glguy>it means that your stack doesn't overflow when you use forever :)
02:37:39<Gracenotes>let a = a in a :o
02:37:44<mib_5674s90w>I am trying to install Tangible Values gui package and I get the follwing error: cabal: dependencies conflict: ghc-6.10.1 requires old-time ==1.0.0.2 however old-time-1.0.0.2 was excluded because ghc-6.10.1 requires old-time ==1.0.0.1 daryoush@zanjan:~$ cabal upgrade old-time
02:37:48<mib_5674s90w>any ideas>
02:37:50<roconnor>sjanssen: ``A programmer would be surprised if he had coded up a mergesort with the expected O(n log n) asymptotic time complexity but found that the actual asymptotic time complexity on his computer was O(n^2)
02:38:11<Axman6>mib_5674s90w: fun. talk to dcoutts_
02:38:18<roconnor>I don't think the author is suggesting this happens with mergesort
02:38:32<pumpkin_>mib_5674s90w: switching your nick might be helpful too :)
02:38:32<Axman6>he helped me fix it before, but i can't remember how to do it
02:38:35<sjanssen>TCO in Haskell means "let f x = g x in f x" uses no more stack than "g x"
02:38:49<wli>Is there an example of a mergesort implementation for which this happens?
02:39:08<roconnor>The author just wants to make the point that extra space complexity ought to be as surprising as extra time complexity would be, thought extra time complexity doesn't happen
02:39:58<roconnor>I don't even think of stacks when working in Haskell, so saving the stack space strikes me as bizarre
02:40:09<kadaver>ok
02:40:11<pumpkin_>save the stack!
02:40:12<kadaver>does a mergesort in haskell use a lot mroe space than in say java?
02:40:24<kadaver>stacks are the shit!
02:40:27<roconnor>I always have to work really hard to find a way of blowing the stack in Haskell without using primops.
02:40:51<roconnor>and when I do manage to find a way, I still don't understand why. :)
02:41:21<Axman6>fib n = fib (n-2) + fib (n-1)?
02:41:25<Axman6>for large n
02:41:33<Asztal>> sum [1..100000]
02:41:34<lambdabot> 5000050000
02:41:37<Asztal>bah.
02:42:08<Axman6>> let fib n | n < 2 = 1; fib n = fib (n-2) + fib (n-1) in fib 10000
02:42:20<Asztal>> sum [1..10000000]
02:42:20<roconnor>(-) is a primop
02:42:23<lambdabot> thread killed
02:42:30<roconnor>(+) is a primop
02:42:30<Asztal>I see
02:42:31<Axman6>> let fib n | n < 2 = 1; fib n = fib (n-2) + fib (n-1) in fib 1000
02:42:34<lambdabot> mueval: Prelude.read: no parse
02:42:48<pumpkin_>it isn't quite a primop is it?
02:42:49<lambdabot> thread killed
02:42:54<pumpkin_>I thought +# and -# were the primops
02:42:59<roconnor>right
02:42:59<Axman6>> let f x = f (f x) in f 1
02:43:11<roconnor>(+) reduces to a prim op in this instance
02:43:19<lambdabot> mueval: Prelude.read: no parse
02:43:21<Gracenotes>ja
02:43:27<Axman6>mwhaha
02:43:38<Axman6>> let f x = f (f x) in f x :: Expr
02:43:52<Gracenotes>ACTION listens to more MSTRKRFT :o
02:43:54<lambdabot> thread killed
02:44:01<Axman6>> let g x = f (g x) in f x :: Expr
02:44:10<roconnor>Axman6: does that cause a stack overflow
02:44:11<lambdabot> f x
02:44:16<Gracenotes>wat
02:44:21<Axman6>> let g x = f (g x) in g x :: Expr
02:44:24<lambdabot> f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (f (...
02:44:39<Axman6>roconnor: no idea actually, but i was hoping it would :)
02:44:43<roconnor>I'd test it but I need to find out how to limit my memory first
02:44:47<roconnor>how do I use ulimit?
02:45:38<roconnor>Axman6: I think that runs in constant space
02:46:06<sjanssen>kadaver: merge sort doesn't use any more memory in Haskell than something else
02:46:13<roconnor>Actually, I'd love to hear an explain of when non-prim ops push a stack frame in GHC.
02:46:16<sjanssen>kadaver: I think you're drawing bizarre conclusions from this blog
02:46:22<myname>lambdabot
02:46:24<myname>eixt
02:46:36<Axman6>...
02:47:14<sjanssen>roconnor: case expressions on thunks will push a new stack frame
02:47:57<roconnor>sjanssen: ah
02:48:14<sjanssen>I think that's basically it
02:48:33<Asztal>> fix tail
02:48:33<roconnor>which also shows how stack allocations are more or less unrelated to function calls
02:48:33<sjanssen>or things that are semantically like case, +#, etc.
02:48:34<lambdabot> * Exception: stack overflow
02:49:03<roconnor>Asztal: nice
02:49:41<roconnor>@src tail
02:49:42<lambdabot>tail (_:xs) = xs
02:49:42<lambdabot>tail [] = undefined
02:50:40<maurer> /join #cslounge
02:50:57<roconnor>and since stack allocations are unrelated to function calls, then the whole idea of TCO doesn't really have meaning anymore
02:51:02<roconnor>I think ...
02:51:34<alkaid>> tail []
02:51:36<lambdabot> * Exception: Prelude.tail: empty list
02:51:44<alkaid>hum
02:52:02<alkaid>undefined really means undefined
02:52:09<roconnor>sjanssen++
02:52:15<alkaid>it's not a special exception variable
02:52:19<Axman6>yeah, lambdabot's definitions aren't the ones that are actually used
02:52:35<Axman6>tail [] = error "empty tail"
02:52:43<alkaid>hummmm
02:52:52<wli>I'm not getting stack overflow from fix tail.
02:52:54<roconnor>the actually source for tail [] is implemention specific, but must be of the form error "something"
02:53:35<roconnor>wli: what version of GHC?
02:53:49<wli>6.10.2
02:53:57<wli>It just silently loops.
02:53:59<roconnor>ACTION gets a stack overflow is 6.8.2's ghci
02:54:12<roconnor>wli: I guess 6.10 has TCO :P
02:54:52<Asztal>my windows ghci (6.10.1) actually crashes...
02:54:59<roconnor>...
02:55:15<Axman6>@src fix
02:55:16<lambdabot>fix f = let x = f x in x
02:56:07<Axman6>hmm, running fix tail in my ghci makes ghci use 0% cpu...\
02:56:54<dolio>It should get caught by black hole analysis, but it can't throw exceptions from that in ghci for reasons I can't recall.
02:58:16<dolio>> [1,2] \\ [2..]
02:58:32<lambdabot> thread killed
03:00:05<dolio>> [1,2] \\ [2..1000000]
03:00:13<lambdabot> [1* Exception: stack overflow
03:00:15<dolio>Boom.
03:00:48<sjanssen>roconnor: I think TCO still applies
03:00:56<scriptdevil>Is literate haskell a recommended practice?
03:01:15<wli>ACTION ponders what there might need to be tutorials about that he can actually write stuff for.
03:01:28<sjanssen>roconnor: it's just that every function call in Haskell is essentially a "tail call"
03:01:47<wli>(or, for that matter, what I can write code for at all0
03:01:52<sjanssen>roconnor: also, function calls might make a heap allocation rather than a stack allocation
03:05:55<roconnor>sjanssen: oh yes, I usually think of everything being allocated on the heap
03:06:08<roconnor>in fact, the stack probably only contains pointers.
03:06:42<roconnor>sjanssen: but I don't see why you think that TCO applies
03:07:22<kw317>what is wrong with this code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4235#a4235? GHC complains about type of "x div y" in line 17
03:07:36<roconnor>sjanssen: since function calls have nothing to do with stack allocations.
03:07:45<glguy>1``
03:07:46<sjanssen>roconnor: yes, exactly
03:08:05<sjanssen>TCO asks that tail calls don't make a stack allocation. In Haskell, tail calls don't make a stack allocation
03:08:30<roconnor>now you are just being silly
03:08:39<tsLight>I am reading http://www.haskell.org/onlinereport/decls.html#sect4.5.4, and I am confused when it says "In an environment where x has type a, the type of g's definition is a ->b ->([a],b)". Why is that?
03:08:54<sjanssen>I don't think so. If a newbie comes to #haskell and asks "does Haskell support TCO?", we should say yes
03:09:11<roconnor>Definitely not
03:09:19<roconnor>we should say the concept is not applicable.
03:09:22<sjanssen>well, rather GHC
03:09:28<roconnor>to GHC
03:09:34<sjanssen>roconnor: sure, if you want to spend 10 minutes explaining
03:09:43<sjanssen>one of those long answer/short answer things
03:09:55<roconnor>sjanssen: it's a terrible short answer
03:10:10<roconnor>the newbie will go away and write tail recursive functions
03:10:16<roconnor>and then come back with stack overflows!!!
03:12:00<roconnor>kw317: x `div` y
03:12:09<kw317>*sigh*
03:12:25<kw317>maybe I shouldn't be trying to comprehend any code at 4am in the morning LOL
03:12:29<kw317>roconnor: thanks!
03:12:43<roconnor>roconnor++ is thanks enough
03:12:53<Cale>roconnor: We should say "Yes, but since functions tend to be evaluated before their parameters, tail recursive functions tend to build large expressions which cause stack overflows."
03:13:20<roconnor>But but ...
03:13:33<roconnor>stack allocation has nothing to do with function calls
03:13:40<Berengal>Also, some non-tail-recursive functions work just fine
03:13:41<Cale>Right.
03:13:52<roconnor>and TCO is all about preemtively removing a stack at the end of a function call
03:14:18<roconnor>so, the whole idea of TCO presumes that functions entry/exit is pushing/popping a stack.
03:14:25<roconnor>which just isn't true in GHC
03:14:50<roconnor>I can probably safely say it isn't true in Haskell.
03:15:33<scriptdevil>roconnor: You might put this in some online page and then whenever someone asks, point them to the explanation
03:16:33<roconnor>scriptdevil: that seems much better
03:17:05<roconnor>scriptdevil: I'll first try explaining it a few times to newbies until I get it right.
03:17:19<scriptdevil>roconnor: :)
03:17:21<Berengal>"Is Hask
03:17:24<Berengal>Bah...
03:17:46<Berengal>"Does Haskell have TCO?" "Short answer: Doesn't matter"
03:17:57<Cale>I find it's easiest just to explain a reasonable model of Haskell evaluation in terms of rewriting expressions. The question about TCO is a bit misguided, yeah.
03:18:20<roconnor>that's how I usually imagine haskell
03:18:40<roconnor>which is why I found it so hard to understand when GHC pushes a stack at all.
03:18:50<tsLight>can anyone take 5 seconds to help me with the question I posted? :P
03:19:05<Axman6>tsLight: not if you don't ask it ;)
03:19:15<tsLight>I am reading http://www.haskell.org/onlinereport/decls.html#sect4.5.4, and I am confused when it says "In an environment where x has type a, the type of g's definition is a ->b ->([a],b)". Why is that?
03:19:20<tsLight>that was it
03:19:27<Cale>He did ask it :)
03:19:37<Axman6>yeah, but not on my screen :P
03:20:30<Cale>tsLight: It's because since x :: a is an element of it, [x,y] :: [a], and so y :: a, and then z can have any type at all.
03:20:43<Cale>(say b)
03:21:04<Cale>and so then g takes parameters of type a and b, and produces something of type ([a],b)
03:21:22<tsLight>I dont understand
03:21:26<tsLight>how can [x,y] :: [a]
03:21:28<tsLight>if x,y is a pair
03:21:33<roconnor>tsLight: basically you cannot generalize over type variables that come from "outside" the subexpression.
03:21:36<Berengal>It's not a pair, it's a list
03:21:36<Cale>[x,y] is a list of two elements
03:21:42<tsLight>ah right
03:21:43<Berengal>And lists must all have the same element
03:21:43<Cale>Its type is [a]
03:21:52<Berengal>same type of element*
03:21:57<tsLight>I messed up
03:21:57<tsLight>:P
03:22:02<Cale>just as [1,2,3] :: [Integer], say
03:22:05<tsLight>yeah
03:22:11<tsLight>thanks
03:22:35<roconnor>oh god, tsLight is about to read the dreaded section 4.5.5
03:22:43<Cale>But the thing which the report is trying to point out is that while g accepts *any* type b, there's a *specific* type a which is required.
03:23:27<Cale>(it's the same type as x, which is already in scope)
03:23:32<tsLight>"only b can be universally quantified because a occurs in the type environment"
03:23:35<tsLight>what does that mean?
03:23:47<Cale>That's sort of what I just explained...
03:23:49<tsLight>by specific type a you mean, the type of x?
03:23:53<Cale>yes
03:23:57<Berengal>That the type of a is already bound to a spesific type
03:24:00<tsLight>ah
03:24:03<tsLight>I get it
03:24:22<Cale>Now, the type 'a' might later be generalised, but it'll be in the type of f which it's polymorphic
03:24:44<scriptdevil>ACTION goes into a dormant state
03:25:09<Berengal>ACTION wonders if it could be possible to reimplement prolog in the typesystem
03:25:18<tsLight>so haskell cannot guess it
03:25:21<tsLight>unless you tell it explicitely
03:25:29<Cale>Cannot guess what?
03:25:43<tsLight>x's type
03:26:07<Cale>If it can't guess the type of x, generally that will mean that x can be any type at all, and it will get forall'd too.
03:26:14<Cale>For example...
03:26:36<Cale>If that '...' in the definition is something like, say, g x x
03:26:57<Cale>then the inferred type of f will be f :: forall a. a -> ([a],a)
03:27:18<tsLight>right
03:27:22<Cale>which we normally write without the forall as f :: a -> ([a],a)
03:27:34<Cale>(because it's implied)
03:27:40<tsLight>I am reading this to understand why the following functions give different inferred types
03:27:48<tsLight>miAddUp ns = (map (+ 1) . filter (>0)) ns
03:27:53<tsLight>miAddUp3 = (map (+ 1) . filter (>0))
03:28:07<Berengal>First guess: MR
03:28:11<tsLight>miAddUp :: (Num a, Ord a) => [a] -> [a] but miAddUp3 :: [Integer] -> [Integer]
03:28:12<Cale>oh, that's the monomorphism restriction, described in the following section
03:28:19<Berengal>Yeah, MR
03:28:25<Cale>I normally turn that off as soon as I notice it.
03:28:26<tsLight>yes, thats why I was reading the introduction to Monomorphism :P
03:28:33<tsLight>you turn what off?
03:28:40<Berengal>You can give both an explicit type to override it
03:28:45<Cale>You can add {-# LANGUAGE NoMonomorphismRestriction #-} to the top of your module
03:28:56<Cale>and it'll stop overspecialising the type
03:29:04<tsLight>ah
03:29:07<tsLight>but its not a problem really
03:29:11<tsLight>I just wanted to understand why it does
03:29:13<Berengal>If you give miAddUp3 the type (Num a, Ord a) => [a] -> [a] it won't complain
03:29:41<Cale>There's no *good* reason for it to do so in the case of functions
03:29:56<Cale>But for non-function polymorphic values, there's sort of a good reason
03:30:02<Berengal>Consider you have a function expensiveFunction (Num a) => Foo -> a
03:30:12<Cale>For example, myConstant = product [1..10000]
03:30:18<Cale>It looks like a constant
03:30:25<Cale>so you might expect it to be computed once
03:30:37<Cale>However, it's really polymorphic, the inferred type is
03:30:43<Cale>myConstant :: (Num a) => a
03:30:56<Cale>and hence it's really a function of the Num instance which is supplied
03:31:18<Cale>So if it were to remain polymorphic, it might be recomputed many times.
03:31:26<Cale>(every time it is used)
03:31:51<tsLight>what do you mean by "it's really a function of the Num instance which is supplied"?
03:31:56<tsLight>isnt there only 1 Num instance?
03:32:04<tsLight>unless I re define it or something
03:32:04<Berengal>?instances Num
03:32:05<lambdabot>Double, Float, Int, Integer
03:32:08<Cale>I mean that if you treat it as an Integer, it will be compute it as an Integer
03:32:08<tsLight>ahh
03:32:17<tsLight>I was confusing with Num class :P
03:32:18<Cale>if you treat it as a Double, it'll be recomputed as a Double
03:32:26<Cale>I'm referring to the Num class
03:32:44<tsLight>I mean when I said "only 1 Num instance"
03:32:47<tsLight>I meant class
03:33:02<alkaid>hi
03:33:04<Cale>ah
03:33:16<Cale>Only one Num class, many instances :)
03:33:24<tsLight>and how do I treat that function as Double, Integer or whatever?
03:33:30<tsLight>using it from another function that expects that type?
03:33:30<alkaid>would anyone help me clarify what Just and Maybe do?
03:33:33<Cale>and it won't even generally be cached on a per-instance basis
03:33:43<Cale>tsLight: yes
03:33:57<tsLight>good
03:34:01<Berengal>alkaid: Maybe is a type constructor. Just is a value constructor constructing a value of type Maybe a
03:34:30<Berengal>@type Just
03:34:31<lambdabot>forall a. a -> Maybe a
03:34:43<alkaid>hum
03:34:44<Cale>alkaid: A value of type Maybe t is either the value Nothing, or it is a value of the form Just x where x is of type t
03:35:01<Cale>alkaid: So it's a way of representing cases where something might fail to produce a value.
03:35:13<Cale>alkaid: Are you familiar with any other languages?
03:35:27<Cale>(I might be able to relate it to something you already know)
03:35:31<alkaid> I've been programming in C and Python for a while.
03:35:49<alkaid>I'm not a computer scientist though
03:35:53<Berengal>((Go go null pointer analogy!))
03:35:54<Cale>okay
03:36:04<alkaid>I
03:36:21<alkaid>(i'm really just a physicist who likes computer science. :P)
03:36:39<Cale>So yeah, in C, if a function wants to be able to fail to produce a result in some cases, it often returns a pointer to a value, and gives a null pointer if there was no result
03:36:55<alkaid>right
03:37:04<alkaid>this analogy really makes it clear
03:37:06<Cale>So, Nothing acts like a safer version of a null pointer
03:37:10<alkaid>clearer
03:37:23<Berengal>A type of Maybe Int is sort of like saying "It's an Int, but it can also be Nothing/null if something went wrong"
03:37:33<Cale>For example...
03:37:35<Berengal>Anything that isn't Maybe cannot be null
03:37:48<glguy>Maybe Cat is like a box , but you don't know if it has a Cat in it until you look...
03:37:50<Cale>> lookup 3 (zip [1..] (words "here are some words"))
03:37:53<lambdabot> Just "some"
03:37:58<Cale>> lookup 7 (zip [1..] (words "here are some words"))
03:38:01<lambdabot> Nothing
03:38:08<dmehrtash_>testing
03:38:16<Cale>dmehrtash_: We hear you :)
03:38:28<QtPlaty[HireMe]>:t lookup
03:38:30<lambdabot>forall a b. (Eq a) => a -> [(a, b)] -> Maybe b
03:38:57<alkaid>humm
03:39:09<Cale>> zip [1..] (words "here are some words")
03:39:11<lambdabot> [(1,"here"),(2,"are"),(3,"some"),(4,"words")]
03:39:22<Cale>Just so you can see what that looks like before the lookup :)
03:39:33<alkaid>got it
03:39:55<alkaid>so if there isn't anything to lookup, I get a Nothing
03:40:02<Cale>lookup looks for a pair whose first component matches the supplied value, and if it finds one, returns Just applied to the second component, and if it doesn't, it returns Nothing
03:40:05<Cale>yeah
03:40:13<alkaid>nice
03:40:17<Berengal>Not only is Maybe a safe null-pointer, it's pretty much awesome all around in ways you wouldn't think of in C...
03:40:44<Berengal>ACTION is thinking of among other things the monad instance of Maybe
03:40:57<Cale>Yeah, the monad instance is nice when it works out for you.
03:41:03<alkaid>you mean safer cause we don't have the danger of accidentaly allocating a null pointer
03:41:08<Cale>alkaid: right
03:41:15<Berengal>Or dereferencing it
03:41:18<Cale>alkaid: Dereferencing a null pointer is rather bad
03:41:21<alkaid>ahaha
03:41:21<Berengal>Well, you can...
03:41:27<alkaid>I do it all the time
03:41:32<alkaid>Damn seg faults
03:41:40<Cale>You can fail to pattern match all the cases in a case expression, but that's a little safer.
03:41:44<alkaid>I'm not a very good programmer, you see?
03:41:48<Cale>(it will result in an exception though)
03:41:49<Berengal>Won't happen in haskell. When there's a chance you might get a Nothing, you'll know
03:41:53<QtPlaty[HireMe]>alkaid:
03:41:55<Cale>But it's harder to forget.
03:42:16<QtPlaty[HireMe]>alkaid: No one is a goodprogrammer
03:42:20<glguy>fortunately you can write let Just x = Nothing
03:42:33<dibblego>I think the fromMaybe function is a little more appealing to people coming from C (e.g. C# calls it ??)
03:42:36<Cale>> case lookup 3 (zip [1..] (words "here are some words")) of Nothing -> 0; Just xs -> length xs
03:42:37<lambdabot> 4
03:42:58<Cale>> case lookup 7 (zip [1..] (words "here are some words")) of Nothing -> 0; Just xs -> length xs
03:42:59<lambdabot> 0
03:43:32<Cale>Because you tend to decompose Maybe-values with pattern matches, it's hard to forget to pattern match both cases.
03:43:52<alkaid>hummm
03:43:59<alkaid>oh this is very nice!
03:44:20<alkaid>it's very easy to verify if something returned nothing
03:44:36<Cale>yeah
03:44:41<alkaid>it's just a simple pattern matching
03:44:57<Cale>Or, perhaps it's just hard not to do it :)
03:45:13<Berengal>@type isJust
03:45:14<alkaid>I've been told that haskell was difficult language
03:45:15<lambdabot>forall a. Maybe a -> Bool
03:45:16<Berengal>@type isNothing
03:45:18<lambdabot>forall a. Maybe a -> Bool
03:45:26<Berengal>> isJust Nothing
03:45:28<lambdabot> False
03:45:29<alkaid>it is conceptually difficult
03:45:35<Berengal>> isJust (Just 5)
03:45:35<alkaid>of course it is
03:45:36<lambdabot> True
03:45:54<Cale>In C, when something returns a pointer, it's not always clear whether or not it'll ever be null.
03:46:01<Cale>And a lot of people forget to check.
03:46:14<alkaid>a lot of people: o/
03:46:25<Berengal>Haskell will melt your brain, but in a good way :)
03:46:26<Axman6>o/
03:46:28<Cale>But when it's Maybe, you can pretty much assume that in some cases it will be Nothing
03:46:48<Cale>and that you basically have to check
03:47:01<alkaid>if you don't check
03:47:04<Cale>There is a way to fail to check though.
03:47:05<alkaid>you have an incomplete pattern
03:47:08<Cale>right
03:47:12<Cale>> fromJust (Just 5)
03:47:13<lambdabot> 5
03:47:14<alkaid>and the compiler will complain about it
03:47:17<Cale>> fromJust Nothing
03:47:18<glguy>no
03:47:18<lambdabot> * Exception: Maybe.fromJust: Nothing
03:47:25<Cale>Well, it might complain...
03:47:36<Cale>But it'll just be a warning at most.
03:47:39<alkaid>if you use the right flag, I mean
03:47:42<Cale>yeah
03:47:47<glguy>20:47 < lambdabot> * Exception: Maybe.fromJust: Nothing
03:47:53<glguy>or a runtime error
03:47:54<Berengal>It's not like it's easy to forget about Maybe either...
03:47:57<Cale>There's fromJust, like I showed, which is not so safe to use.
03:47:57<glguy>async exception
03:48:21<alkaid>it just removes Just?
03:48:25<Cale>yeah
03:48:34<Cale>fromJust (Just x) = x
03:48:43<alkaid>right
03:48:46<Cale>fromJust Nothing = error "fromJust: Nothing"
03:49:08<alkaid>and this last line is what is unsafe about it, right?
03:49:11<Cale>yeah
03:49:19<ryanakca>Could someone help me with http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4236#a4236 please? (Code and question, from RWH, p.69, #2) ... I'm not sure if it's the best way to code it either...
03:49:22<alkaid>it makes an exception when I could check for Nothing
03:49:23<Cale>This sort of exception is not the sort you want to have to catch.
03:49:29<Berengal>> let foo m = do {a <- lookup 2 m; b <- lookup 1 m; return (a ++ ' ':b)} in foo (zip [1..] (words "Here are some words"))
03:49:31<lambdabot> Just "are Here"
03:49:58<glguy>alkaid, these exceptions will then arise at unexpected times due to laziness
03:50:09<alkaid>humm
03:50:18<Cale>So, it's best to try to avoid using fromJust entirely :)
03:50:36<alkaid>got it
03:50:52<alkaid>Now it's clearer
03:50:55<Cale>It's like a way of saying "I'm *really* sure that it'll be a Just"
03:51:02<glguy>similarly for head and tail
03:51:07<glguy>and other partial functions
03:51:20<alkaid>humm...
03:51:21<glguy>usually you were sure at the time you used it
03:51:22<tsLight>ryanakca, can't you use pattern matching? It would be much more natural to use primitive recursion to define length
03:51:23<glguy>and then things change
03:51:27<Cale>yeah, pattern matching is always better than head and tail because you don't tend to forget to handle the empty list case that way
03:51:36<alkaid>right
03:51:39<Cale>also, more readable
03:51:56<ryanakca>ACTION nods, thanks
03:52:32<Berengal>Best of all is to use functions that handle the empty case themselves just fine, like the folds...
03:52:40<Cale>ryanakca: yeah, comparing a list with [] using == is basically always something to avoid.
03:52:42<Berengal>Not everything can fit into that though
03:53:09<Cale>ryanakca: Mostly just style-wise, but also, as you can see from that error message, it introduces the need for Eq
03:53:22<glguy>:t null
03:53:24<lambdabot>forall a. [a] -> Bool
03:53:24<Cale>There is also a function 'null'
03:53:26<Cale>yeah
03:53:42<Cale>Which is defined like:
03:53:45<Cale>null [] = True
03:53:49<Cale>null (x:xs) = False
03:53:56<alkaid>It's difficult to abandon the imperative style of doind code. The first compulsion is always to use lots of ifs
03:53:59<Cale>and that doesn't require Eq that way
03:54:16<Cale>alkaid: and ifs without elses :)
03:54:26<Berengal>ACTION wants the if-then-else construct removed...
03:54:28<Cale>(which the compiler won't let you get away with :)
03:54:37<Cale>I like the if-then-else
03:54:43<Cale>It has its place
03:54:47<alkaid>oh yes, I already runned into it
03:54:48<alkaid>:P
03:54:51<glguy>so you'll end up using lots of "when" instead
03:54:54<Berengal>It's fine, I just don't have a use for it and want its keywords :P
03:56:10<Cale>It's one of those things which I suppose if it wasn't there, it might not be something I'd petition for, but it's something which I use anyway.
03:56:44<Berengal>Yeah, I use it as well from time to time, but often enough I just use an "if'" function
03:56:48<Cale>It's a bit nicer than using case/of
03:57:10<Cale>and the 'then' and 'else' help delineate the branches better than an if function does
03:57:21<alkaid>I just have this feeling that, although there are very difficult concepts and a very steep learning curve, Haskell is more easily used by a not very skilled programmer like me.
03:57:56<alkaid>cause even if I'm not able to come up with the amazing code ppl often do in haskell
03:57:56<Berengal>An if function can be given around like any other first-class member though
03:58:11<alkaid>I still have a very clean code
03:58:14<Asztal>I'd like an 'mcase' or something like that, for cases like: do x <- ...; case x of ...
03:58:27<alkaid>with some litle tricks that are really useful and easy to emply
03:58:33<alkaid>employ
03:59:08<Cale>alkaid: and it's nicer to have the compiler catch things than to try to debug code which is running
03:59:42<Cale>Berengal: that's true
04:00:06<alkaid>Cale - I often spend hours in gdb trying to catch some small glitch
04:00:22<Berengal>until' done iter = if' <$> done <*> id <*> until' done iter . iter
04:00:37<alkaid>and my codes are rarely greater than 100 lines
04:00:55<alkaid>well
04:01:02<alkaid>thanks for your help
04:01:06<ryanakca>ttp://hpaste.org/fastcgi/hpaste.fcgi/view?id=4237#a4237 works, but how is it style wise?
04:01:07<Cale>no problem
04:01:27<alkaid>I was twice very well served with very nice answers for trivial questions today
04:01:28<alkaid>:D
04:01:40<Berengal>We like trivial questions
04:01:42<ryanakca>s/.*/h&/
04:01:44<Cale>We like answering beginner questions, yeah :)
04:01:52<Axman6>alkaid: it's what this channel's best at
04:01:54<alkaid>I am studying this book ''Real World Haskell''
04:01:58<ryanakca>ACTION has noticed, incredibly helpful people in hear
04:01:59<Cale>Axman6: :]
04:02:15<ryanakca>alkaid: Haha, so am I, you don't say! ;)
04:02:16<alkaid>so I guess I'll return to the book
04:02:38<alkaid>ryanacka - hahaha the book is very good
04:02:43<Axman6>ryanakca: ... i don't like that code style wise :(
04:03:07<alkaid>so, thanks again
04:03:07<Cale>At a beginner level like that, not tuning for performance, I would go with:
04:03:09<Cale>length [] = 0
04:03:14<Cale>length (x:xs) = 1 + length xs
04:03:21<alkaid>see you in my next trivial question
04:03:23<alkaid>:P
04:03:24<Cale>:)
04:03:32<ryanakca>alkaid: Yes, my only quirk with it so far is that they always say ``We'll tell you about it in Chapter X, until then, take us on faith''... but oh well... Have fun
04:03:42<Axman6>ryanakca: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4237#a4238 is more common
04:03:56<Axman6>except that the alignment is messed up now, oh well
04:05:00<Axman6>ryanakca: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4237#a4239 with proper indentation... almost (the second mL needs another space)
04:05:34<Cale>If you're going to go with the helper function, you shouldn't pattern match
04:05:48<Cale>(The helper should patter match the list)
04:05:51<Cale>pattern*
04:05:52<Berengal>length = foldl' (fmap (+1) . const) 0
04:06:45<ryanakca>Axman6: So, just move mL 0 (x:xs) up to the previous line?
04:06:50<Cale>Why not just const (+1) ?
04:06:54<Axman6>yeah
04:07:06<Cale>oh
04:07:08<ryanakca>Cale: Ah, that's interesting too. *tries*
04:07:13<Cale>Needs flipping :P
04:07:19<dolio>const . (+1)
04:07:28<ryanakca>const? foldl? fmap?
04:07:29<ryanakca>:)
04:07:44<Cale>:t let length = foldl' (const . (+1)) 0 in length
04:07:45<lambdabot>forall b a. (Num a) => [b] -> a
04:07:48<Cale>yeah
04:07:58<ryanakca>Don't worry, I'm about to go to bed, I'll surely read about it in RWH tomorrow
04:08:03<Berengal>let length = foldl' (const . (+1)) 0 in length [1..10]
04:08:07<Cale>ACTION is too used to foldr :)
04:08:13<Berengal>> let length = foldl' (const . (+1)) 0 in length [1..10]
04:08:15<lambdabot> 10
04:08:22<Gracenotes>improbable!!
04:08:32<Cale>> let length = foldl' (const . (+1)) 0 in length "hello"
04:08:33<lambdabot> 5
04:08:52<Gracenotes>> let length = foldl' (const . (+1)) 0 in length [1..(10^7)]
04:08:56<lambdabot> 10000000
04:09:04<Cale>> let length = foldl (const . (+1)) 0 in length [1..(10^7)]
04:09:12<Berengal>I must admitt, I first thought about using foldr for this, but then I realized this was the perfect case for foldl'
04:09:14<lambdabot> mueval: Prelude.read: no parse
04:09:18<Cale>...
04:09:23<Asztal>@src genericLength
04:09:23<alkaid>:t foldl
04:09:23<lambdabot>genericLength [] = 0
04:09:23<lambdabot>genericLength (_:l) = 1 + genericLength l
04:09:24<Cale>no parse?
04:09:26<lambdabot>forall a b. (a -> b -> a) -> a -> [b] -> a
04:09:28<Cale>heh
04:10:03<Cale>alkaid: foldr is easier to explain than foldl
04:10:19<Gracenotes>Cale: 10^7 is a value that tends to cause stack overflow
04:10:19<alkaid>:P
04:10:21<Berengal>I had a tougher time with foldr than foldl...
04:10:21<Cale>alkaid: foldr f z is a function which replaces each (:) in the list with f and the [] at the end with z
04:10:22<Gracenotes>s
04:10:32<alkaid>I just saw this function being used in a comment in the book
04:10:45<Cale>Gracenotes: I know, I just figured we'd see a better error message :P
04:10:54<Berengal>I used foldr all the time when I first started out, but thought it meant "fold rightwards", or in other words, the way foldl folds
04:10:56<Cale>Berengal: Does that description of it help?
04:11:08<Gracenotes>foldr is interesting because it can be completely evaluated before the entire list is traversed
04:11:12<ryanakca>Cale: How would you use it? foldr f z $ list ?
04:11:14<Gracenotes>"lazy semantics" you might say
04:11:18<Cale>ryanakca: yeah
04:11:27<Cale>ryanakca: or without the $ even :)
04:11:34<Berengal>Cale: The replacement? Yeah, that's kind of how I see it now
04:11:34<Gracenotes>however, if the folding function is strict, then it does behave very much like simply folding rightwards
04:11:46<ryanakca>and foldl would?
04:12:00<alkaid>Cale - let me think a bit about the description you gave.. 1 mn
04:12:01<Cale>> foldr (\x xs -> concat ["(f ",show x," ",xs,")"]) "z" [1,2,3,4,5]
04:12:04<lambdabot> "(f 1 (f 2 (f 3 (f 4 (f 5 z)))))"
04:12:11<Berengal>foldr takes an operator and inserts that operator inbetween the elements of a list in a right-associative manner
04:12:23<Cale>Berengal: I don't like that description as much.
04:12:37<copumpkin>> foldr f 0 [1..5]
04:12:39<lambdabot> Add a type signature
04:12:41<copumpkin>> foldr f 0 [1..5] :: Expr
04:12:43<lambdabot> f 1 (f 2 (f 3 (f 4 (f 5 0))))
04:12:52<Cale>But it does make the relationship with foldl easier to see :)
04:13:12<tsLight>is there a way to make Hugs do that?
04:13:17<tsLight>the foldr f 0 [1..5] :: Expr
04:13:18<Berengal>Cale: Yeah, the relationship with foldl was the point of that description, not so much their operation itself
04:13:22<Cale>> foldr (\acc x -> concat ["(f ",acc," ",show x,")"]) "z" [1,2,3,4,5]
04:13:23<copumpkin>I don't think there's anything GHC-specific to that trick
04:13:23<lambdabot> No instance for (Num [Char])
04:13:23<lambdabot> arising from the literal `1' at <in...
04:13:23<Gracenotes>depending on f, "f 5 0" might never get evaluated
04:13:25<Cale>er
04:13:35<Berengal>foldr and foldl overrides the associativity of the operators, if they have any...
04:13:45<Cale>> foldl (\acc x -> concat ["(f ",acc," ",show x,")"]) "z" [1,2,3,4,5]
04:13:46<lambdabot> "(f (f (f (f (f z 1) 2) 3) 4) 5)"
04:13:56<Cale>Right, forgot to change the r to l :P
04:14:08<alkaid>Cale - I think I got it. This is something I can't imagine how to do in C.
04:14:17<Gracenotes>> foldr (&&) True $ (replicate 10 True) ++ (repeat False)
04:14:18<Cale>alkaid: So for instance...
04:14:19<lambdabot> False
04:14:24<Cale>> foldr (+) 0 [1..5]
04:14:26<lambdabot> 15
04:14:37<copumpkin>> foldr (+) 0 [1..5] :: Expr
04:14:38<lambdabot> 1 + (2 + (3 + (4 + (5 + 0))))
04:14:41<Gracenotes>foldr can work nicely for infinite lists. foldl, not so much.
04:14:42<Cale>> foldr (++) "" ["here", "are", "some", "strings"]
04:14:43<lambdabot> "herearesomestrings"
04:14:52<Cale>> foldr (*) 1 [1..10]
04:14:53<lambdabot> 3628800
04:14:58<Berengal>> foldl (\acc x -> concat ["(acc," `f` ",show x,")"]) "z" [1,2,3,4,5]
04:15:00<lambdabot> <no location info>: parse error on input `)'
04:15:33<alkaid>so
04:15:52<alkaid>(\ n-> foldr (*) 1 [1..n])
04:15:57<alkaid>is the factorial function
04:15:59<Cale>yes
04:16:16<alkaid>this is a very elegant way of doing it
04:16:27<Berengal>> foldl (\acc x -> concat ["(",acc," `f` ",show x,")"]) "z" [1,2,3,4,5]
04:16:28<lambdabot> "(((((z `f` 1) `f` 2) `f` 3) `f` 4) `f` 5)"
04:16:31<Asztal>the foldl thing would look nicer if it supported operators
04:16:39<Cale>Asztal: it does?
04:16:40<alkaid>and the performance is better than the plain recursion, right?
04:16:56<Cale>alkaid: No...
04:16:58<alkaid>it creates the final expression we want evaluate at once...
04:17:00<Berengal>alkaid: It is plain recursion
04:17:00<alkaid>no?
04:17:06<Cale>alkaid: They're not primitives.
04:17:11<Cale>alkaid: Just library functions.
04:17:16<Asztal>Cale: oh, so it does
04:17:16<alkaid>Oh, I see
04:17:20<Cale>alkaid: They're implemented with recursion :)
04:17:26<Berengal>?src foldr
04:17:27<lambdabot>foldr f z [] = z
04:17:27<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
04:17:27<alkaid>I see
04:17:44<alkaid>(this lambdabot is something, isn't it?)
04:18:08<alkaid>I see
04:18:13<Cale>alkaid: foldl' has a clever implementation though, in that it evaluates the function applications strictly, which can save on space in some cases, but left folds can't be used on infinite lists, and certainly not strict ones
04:18:28<Cale>(that is, with the extra 'prime' like that)
04:18:34<Berengal>?src foldl
04:18:34<lambdabot>foldl f z [] = z
04:18:34<lambdabot>foldl f z (x:xs) = foldl f (f z x) xs
04:18:36<Berengal>?src foldl'
04:18:36<lambdabot>foldl' f a [] = a
04:18:37<lambdabot>foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs
04:19:05<Cale>foldl' evaluates the f a x before continuing to recurse
04:19:06<alkaid>humm
04:19:13<alkaid>I see
04:19:19<Cale>whereas foldl just builds up a large expression, recursing immediately
04:19:31<Cale>This can matter if the lists are very large.
04:19:39<Cale>> foldl (+) 0 [1..10000000]
04:19:52<lambdabot> mueval: Prelude.read: no parse
04:19:53<Cale>(probably an error message...)
04:19:56<Cale>> foldl' (+) 0 [1..10000000]
04:20:00<lambdabot> 50000005000000
04:20:05<alkaid>:O
04:20:08<Cale>Normally the error message would mention the stack.
04:20:12<Berengal>> maximum [1..10^6]
04:20:14<lambdabot> * Exception: stack overflow
04:20:18<Berengal>?src maximum
04:20:19<lambdabot>maximum [] = undefined
04:20:19<lambdabot>maximum xs = foldl1 max xs
04:20:35<Berengal>There :)
04:20:44<Cale>> foldl1' max [1..10^6]
04:20:45<lambdabot> 1000000
04:20:56<Cale>So sometimes, strictness really does matter
04:21:12<alkaid>I see
04:21:14<Cale>Thankfully, most of the cases where you really want strictness also happen to be left folds.
04:21:23<Berengal>When you foldl you'll want to foldl'
04:21:37<Cale>I could explain this better...
04:21:46<Berengal>There are some cases where they're not equal, but most of the time they are
04:22:25<Cale>alkaid: Do you know how lazy evaluation works?
04:22:37<alkaid>a bit
04:22:58<Cale>alkaid: It always proceeds by evaluating the outermost function first, substituting the parameters into the body of the function (with a small additional optimisation)
04:23:06<alkaid>the expressions aren't evaluated until we need a value, right?
04:23:17<Cale>That is, it doesn't evaluate the parameters before substituting.
04:23:26<alkaid>hum
04:23:30<Cale>An example I like to give is with this function:
04:23:30<alkaid>if the parameter is an expression
04:23:37<Cale>double x = x + x
04:23:47<alkaid>right
04:23:55<Cale>We can look at various ways of evaluating double (double 5)
04:24:22<Cale>Under strict evaluation, like C and most imperative languages use, it goes:
04:24:25<Cale>double (double 5)
04:24:28<Cale>-> double (5 + 5)
04:24:31<Cale>-> double 10
04:24:34<Cale>-> 10 + 10
04:24:35<Cale>-> 20
04:24:42<Cale>Nothing surprising there.
04:24:45<alkaid>right
04:25:12<Cale>Under plain outermost-first evaluation, also called "normal order evaluation" despite not being very common, it goes like:
04:25:15<Cale>double (double 5)
04:25:21<Cale>-> double 5 + double 5
04:25:26<Cale>-> (5 + 5) + double 5
04:25:30<Cale>-> 10 + double 5
04:25:33<Cale>-> 10 + (5 + 5)
04:25:35<Cale>-> 10 + 10
04:25:37<Cale>-> 20
04:25:59<Cale>But you might notice something here. It wasted work, computing double 5 twice.
04:26:14<alkaid>so in this case you evaluate first the outer double
04:26:18<Cale>yeah
04:26:25<Axman6>Cale: you know what, you need to write a library that can do these expansaions and evaluations stepwise for you, you're so good at them :)
04:26:42<Cale>Axman6: hehe
04:26:50<Axman6>i know that simple-reflect has something like it though
04:26:56<Cale>alkaid: So lazy evaluation does one extra optimisation
04:26:57<Axman6>@hoogle Expr
04:26:58<lambdabot>module Text.Parsec.Expr
04:26:58<lambdabot>module Text.ParserCombinators.Parsec.Expr
04:26:58<lambdabot>Distribution.Simple.Program alexProgram :: Program
04:27:10<Axman6>@hoogle Expr -> [Expr]
04:27:11<lambdabot>Warning: Unknown type Expr
04:27:11<lambdabot>Prelude repeat :: a -> [a]
04:27:11<lambdabot>Data.List repeat :: a -> [a]
04:27:16<Axman6>bah
04:27:23<Berengal>> foldl' (flip (:) [] [1..10]
04:27:24<lambdabot> <no location info>: parse error on input `;'
04:27:33<Cale>alkaid: If a parameter to a function occurs more than once in the body, work on evaluating that parameter is shared between the copies.
04:27:34<Berengal>> foldl' (flip (:)) [] [1..10]
04:27:35<lambdabot> [10,9,8,7,6,5,4,3,2,1]
04:27:56<Cale>Berengal: That's the one case where I'd say foldl is better.
04:28:01<Axman6>> let double x = x + x in reduction (double (double 5))
04:28:02<lambdabot> Not in scope: `reduction'
04:28:06<Cale>heh
04:28:18<Cale>I'd love to have something like that
04:28:20<Axman6>, let double x = x + x in reduction (double (double 5))
04:28:20<Cale>alkaid: So...
04:28:22<lunabot> luna: Not in scope: `reduction'
04:28:31<Axman6>> let double x = x + x in Debug.SimpleReflect.Expr.reduction (double (double 5))
04:28:32<lambdabot> Failed to load interface for `Debug.SimpleReflect.Expr':
04:28:33<lambdabot> Use -v ...
04:28:36<Axman6>gah
04:28:38<Cale>Axman6: What are you doing?
04:28:43<Axman6>i've seen it used here
04:28:44<Berengal>Cale: Why? Memory?
04:28:48<Asztal>it's probably version 0.1 of SimpleReflect
04:28:53<Cale>Berengal: why does it share work?
04:29:24<Axman6>> let double x = x + x in iterate reduce (double (double 5))
04:29:25<lambdabot> [5 + 5 + (5 + 5),10 + (5 + 5),10 + 10,20,20,20,20,20,20,20,20,20,20,20,20,2...
04:29:31<Axman6>there we go :)
04:29:41<alkaid> Cale - I'm listening
04:29:49<Cale>Berengal: Note that the outermost-first reduction of double (double 5) took more steps than the innermost-first one
04:29:53<Axman6>iterate reduce -- the Cale function
04:29:57<Cale>Berengal: because it evaluated double 5 twice
04:30:18<Cale>alkaid: okay, so if you'll allow me to use let ... in ... to represent the sharing, it looks like this:
04:30:22<Cale>double (double 5)
04:30:27<Cale>-> let x = double 5 in x + x
04:30:35<Cale>(so we still expand the outer double first)
04:30:43<Gracenotes>Axman6: I thought I came up with it :( independently, anyway
04:30:45<Cale>-> let x = 5 + 5 in x + x
04:30:50<Cale>-> let x = 10 in x + x
04:30:54<Cale>-> 20
04:31:03<Gracenotes>Axman6: what is all this credit-stealing nowadays! Really!
04:31:10<Axman6>eh?
04:31:10<alkaid>hum
04:31:14<Gracenotes>:P
04:31:23<Axman6>ACTION is tehfused
04:31:25<alkaid>so it just calculates the double 5 once
04:31:28<Cale>right
04:31:36<Cale>and shares it between the copies
04:31:54<Gracenotes>>_>
04:32:11<Cale>But, since it's still outermost-first, if the function were different, and part of the result was available before we needed x, then we might never have to compute x
04:32:17<Axman6>Gracenotes: i know i've seen it used in here before, if it wsd yours, then nice work :)
04:32:37<Cale>(but since it's just addition, we inevitably have to compute it to get a result)
04:33:08<Cale>(+) on integers will demand the evaluation of both its parameters before it gives anything
04:33:37<alkaid>I see. If we had a case where the result doesn't depend on x, it would be able to give the result without evaluating it
04:33:45<Cale>You can think of it as being because (+) pattern matches, even though in the real implementation, it's primitive.
04:33:58<Cale>Pattern matching is what forces evaluation to proceed.
04:34:18<Cale>and things are only evaluated until they match a pattern
04:34:27<Gracenotes>simple-reflect is a bit basic, though. To see a better representation of what gets shared in computation, try Debug.Traced
04:34:40<Cale>alkaid: right
04:34:41<Gracenotes>in ghci, "import Debug.Traced" and "showAsExp . reShare $ let double x = x + x in double (double 5)"
04:35:22<Berengal>There's also vacuum...
04:35:24<Gracenotes>> let _1 = 5 + 5; _0 = _1 + _1; in _0 -- this is the result of the above snippet
04:35:26<lambdabot> 20
04:35:37<Gracenotes>right, although vaccum seems to be more for data structures
04:35:52<Cale>Gracenotes: Hehe, you kids and your fancy evaluation tracers! In my day, we wrote out evaluation traces by hand on a blackboard, and we liked it that way!
04:36:10<Berengal>Gracenotes: Well, yes, it doesn't show expressions...
04:36:16<Gracenotes>> let _2 = 2 * 2; _1 = _2 * _2; _3 = _2 * 2; _0 = _1 * _3; in _0 -- output for 2^7
04:36:18<lambdabot> 128
04:36:22<Gracenotes>Cale: hehe :)
04:36:43<alkaid>thanks again Cale
04:36:43<alkaid>and everybody else
04:36:55<Cale>Seriously though, writing out some evaluation traces by hand can really help gain some intuition.
04:37:19<Cale>The effect of lazy evaluation on performance takes quite a bit of getting used to
04:37:23<BMeph>Cale: Have you mentioned finding the length of lists with undefined elements as an example? :)
04:37:33<Cale>oh, right, we can do that :)
04:37:42<Cale>> length [undefined, undefined, undefined]
04:37:43<lambdabot> 3
04:37:46<Cale>> undefined
04:37:47<lambdabot> * Exception: Prelude.undefined
04:37:59<Cale>(if undefined is evaluated, it throws an exception)
04:38:01<Berengal>> length [12,2,3,4,5/0,6,7]
04:38:03<lambdabot> 7
04:38:24<Cale>> let x = x+1 in x
04:38:25<Berengal>> 5/0
04:38:26<lambdabot> Infinity
04:38:39<lambdabot> thread killed
04:38:49<Berengal>Oh, and don't forget fix ;)
04:38:51<Berengal>@type fix
04:38:52<lambdabot>forall a. (a -> a) -> a
04:38:54<Cale>> let x = x+1 in length [x,x,x]
04:38:55<lambdabot> 3
04:39:09<Cale>> fix (1:)
04:39:10<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
04:39:25<Cale>> let x = 1:x in x
04:39:27<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
04:39:42<Berengal>Hmm... loeb?
04:39:44<Berengal>@type loeb
04:39:46<lambdabot>Not in scope: `loeb'
04:39:48<Berengal>:O
04:39:54<alkaid>this is a list of infinite many 1?
04:40:00<Cale>The reason it works is because only a finite amount of the list is needed to print the initial part of the result.
04:40:02<Cale>yeah
04:40:24<Berengal>@type let loeb x = fmap (\a -> a (loeb x)) x in loeb
04:40:26<lambdabot>forall (f :: * -> *) b. (Functor f) => f (f b -> b) -> f b
04:40:58<Berengal>> cycle [1..10]
04:41:00<lambdabot> [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6...
04:41:11<alkaid>:O
04:41:15<Berengal>A cycled list takes up less space than a non-cycled one
04:41:18<Cale>> let primes = 2 : filter isPrime [3,5..]; isPrime n = all (\p -> n `mod` p /= 0) . takeWhile (\p -> p^2 <= n) $ primes in primes
04:41:19<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...
04:41:26<Cale>^^ infinite list of primes
04:41:41<alkaid>oh, now you are kidding!!
04:41:53<Berengal>> let fibs = 0:1:zipWith (+) fibs (tail fibs) in fibs
04:41:54<lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946...
04:42:00<alkaid>ahahaha
04:42:03<Berengal>Fibonacci
04:42:22<copumpkin>> fix ((0:) . scanl (+) 1)
04:42:24<lambdabot> [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946...
04:42:45<Cale>I love the way that particular version of the primes works.
04:42:59<Cale>Note the mutual recursion.
04:43:05<copumpkin>it's pretty hot :)
04:43:23<alkaid>I understood Berengal's fibonacci
04:43:23<Berengal>My version of primes has mutual recursion on primes, isPrime and factorize...
04:43:41<copumpkin>my e-penis is even bigger! but I haven't thought how yet
04:43:43<alkaid>the other two I couldn't
04:43:55<Cale>The fix version is sneaky.
04:44:03<Berengal>Fix itself is very sneaky...
04:44:06<Berengal>?src fix
04:44:07<lambdabot>fix f = let x = f x in x
04:44:15<copumpkin>it does the mutual recursion for you! :D
04:44:19<Cale>fix finds the least-defined fixed point of a function
04:44:37<Cale>(so if undefined is a fixed point, that's what you'll get :)
04:44:39<Berengal>> fix (const 6)
04:44:41<lambdabot> 6
04:44:46<Cale>> fix sin
04:44:48<lambdabot> * Exception: stack overflow
04:44:59<tsLight>is there a way to open Hugs interpreter and be able to work with list functions, just like I do with Prelude?
04:45:00<alkaid>hum
04:45:00<Cale>(doesn't do any analysis ;)
04:45:04<Cale>> fix (1:)
04:45:06<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
04:45:09<tsLight>I mean without opening a .hs file that says Import List
04:45:12<copumpkin>lol
04:45:20<alkaid>> fix (\ x-> x*(1-x) )
04:45:31<Cale>> fix (\fac n -> if n == 0 then 1 else n * fac (n-1)) 10
04:45:33<lambdabot> 3628800
04:45:36<lambdabot> thread killed
04:45:53<copumpkin>the killed one was the first one :P
04:45:59<copumpkin>lambabot should respond with your nick
04:46:08<Cale>That's a good idea, it should
04:46:10<Berengal>That would be nice
04:46:59<alkaid>I still don't know if I got fix
04:47:09<Cale>alkaid: another definition is fix f = f (fix f)
04:47:12<copumpkin>it isn't an intuitive function :)
04:47:17<alkaid>> fix (\ x-> x)
04:47:20<Cale>So fix f = f (f (f (f ...)))
04:47:30<alkaid>it will crash again
04:47:32<Cale>yeah
04:47:32<lambdabot> thread killed
04:47:38<copumpkin>it's a good way to make those FFFFFFFFFUUUUUUUU ugly comics
04:47:46<alkaid>humm
04:47:53<DOKKA>gah
04:47:57<DOKKA>hello
04:47:58<copumpkin>except you never get to the U
04:48:00<Berengal>> let loeb x = fmap (\a -> a (loeb x)) x in loeb (const 1:const 1:[(\l -> (l!!i)+(l!!(i+1)))| i <- [0..]]
04:48:02<lambdabot> <no location info>: parse error on input `;'
04:48:02<alkaid>humm
04:48:03<copumpkin>hello DOKKA
04:48:06<MyCatVerbs>Cale: stupid question, but does fix f = f (fix f) have the same space usage characteristics as fix f = let x = f x in x?
04:48:14<kadaver>> foldl (++) "" $ intercalate " " ["My","wife","is","a","milf"]
04:48:15<copumpkin>no
04:48:16<lambdabot> Couldn't match expected type `[Char]' against inferred type `Char'
04:48:17<Cale>MyCatVerbs: no
04:48:23<kadaver>> foldl (++) "" $ intersperse " " ["My","wife","is","a","milf"]
04:48:25<lambdabot> "My wife is a milf"
04:48:36<Cale>alkaid: Part of the result of f must be available without looking at the parameter, or else you will just get an infinite loop
04:49:09<MyCatVerbs>kadaver: one would hope so, for the sake of your marriage.
04:49:14<copumpkin>> let fix f = f (fix f) in fix (1:) -- should work
04:49:17<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
04:49:18<alkaid>I got it
04:49:19<Cale>alkaid: Note that 1 : undefined is not the same thing as undefined
04:49:21<MyCatVerbs>Cale: thanks.
04:49:25<Cale>because, for instance
04:49:30<alkaid>I was thinking imperatively again
04:49:31<Cale>> head (1 : undefined)
04:49:31<copumpkin>but in other cases it won't work
04:49:33<lambdabot> 1
04:50:04<Cale>So, since undefined is not a fixed point of (1:)
04:50:13<Cale>fix (1:) cannot be undefined
04:50:34<Cale>So it's got to be something more defined than that :)
04:50:45<alkaid>ahahaha
04:51:05<Berengal>Lazy evaluation is funny in that it has several levels of definedness. Strict evaluation has only two
04:51:12<Cale>Whereas, everything is a fixed point of (\x -> x), and in particular, a nonterminating computation like undefined is, so fix (\x -> x) will be undefined.
04:51:32<alkaid>oh, I got it!
04:51:39<Cale>fix always gives you the *least defined* fixed point
04:51:39<alkaid>the least defined fixed point
04:51:43<Cale>right
04:52:02<copumpkin>so if undefined is a fix point, it'll give you that :P
04:52:20<copumpkin>meaning that most of the things you throw at fix are going to fail epicly :P
04:52:22<alkaid>when you talked about fixed points I was thinking numerically
04:52:31<alkaid>hahahha
04:52:37<Cale>btw, we tend to equate all sorts of async exceptions and nontermination and such when talking about values like this
04:52:51<Cale>alkaid: Well, it is sort of in the same sense.
04:53:11<Berengal>undefined == bottom == _|_ == 1/0 == infinite loop
04:53:21<Cale>in that if u = fix f, then u = f u
04:53:24<copumpkin>you mean 1 `div` 0 :P
04:53:24<Cale>In fact...
04:53:34<alkaid>yes, but I can see undefined will be a fixed point of most numerical functions I can think of
04:53:35<Cale>@src fix
04:53:36<lambdabot>fix f = let x = f x in x
04:53:42<Berengal>Right, 1/0 == infinity...
04:53:50<Cale>alkaid: yeah :)
04:53:53<Berengal>> (1/0, 1 `div` 0)
04:53:55<lambdabot> (Infinity,* Exception: divide by zero
04:53:56<QtPlaty[HireMe]>Berengal: Not quite.
04:54:17<copumpkin>1/x gets unboundedly large as x approaches 0 :P
04:54:18<copumpkin>how bout that
04:54:20<QtPlaty[HireMe]>Berengal: Lim x -> 0 1/x == infinity
04:54:21<Cale>alkaid: Because most numeric types are strict datastructures -- you don't have partially defined numbers.
04:54:28<Berengal>> 1/0
04:54:30<lambdabot> Infinity
04:54:35<Berengal>^^ See?
04:54:36<copumpkin>that's an actual value, though
04:54:38<copumpkin>you can work with it
04:54:40<copumpkin>it's not bottom
04:54:45<Gracenotes>> (1/0) / (1/0)
04:54:47<lambdabot> NaN
04:54:52<Gracenotes>but
04:54:55<Gracenotes>> 1/0 :: CReal
04:55:05<copumpkin>yeah, that fails
04:55:11<lambdabot> thread killed
04:55:16<copumpkin>only IEEE floats are made of win
04:55:30<copumpkin>l33tsauce, even
04:55:36<Cale>It would be nice to have a CReal type which was practical.
04:55:48<Cale>I hate IEEE floats.
04:55:51<copumpkin>me too
04:55:57<Berengal>Floats are ugly...
04:55:58<copumpkin>they're an insult to math :o
04:56:08<Gracenotes>CReals have teh pr3c1sion and accU5ac7
04:56:22<copumpkin>doesn't GMP provide arbitrary precision decimal numbers too?
04:56:33<Berengal>ACTION likes his rationals
04:56:38<Gracenotes>hm, I feel that was a 1337 failure
04:56:44<Gracenotes>@elite precision and accuracy
04:56:45<lambdabot>PRE(IzioN and ACCURacY
04:56:45<Cale>Gracenotes: I was about to say...
04:56:47<copumpkin>Gracenotes: you fail, clearly I'm l33ter than you
04:56:48<QtPlaty[HireMe]>Well your never going to have a way of doing real maths on a church/turing computer.
04:56:53<Gracenotes>@elite precision and accuracy
04:56:54<lambdabot>PREcI$ION 4nD accuRa(Y
04:57:01<Cale>Gracenotes: 5 is not an acceptable r ;)
04:57:17<Gracenotes>maybe if you're not leet enough!
04:57:43<QtPlaty[HireMe]>Its just an inaccurate r
04:57:55<Cale>"threeleet"
04:58:19<copumpkin>so yeah, it looks like gmp has decimals
04:58:30<copumpkin>can't we provide primops to that?
04:58:51<Cale>copumpkin: Arbitrary precision decimals isn't *quite* the same as computable reals, but it would also be good.
04:58:58<copumpkin>true
04:59:17<Cale>Is it really decimal?
04:59:21<copumpkin>I was going to dig in and provide a modexp primop too
04:59:24<Cale>(not binary?)
04:59:30<QtPlaty[HireMe]>ACTION ponders dealing with reals as functions (Natural -> Rational)
04:59:32<copumpkin>oh I meant decimal in the very informal sense
04:59:40<Cale>ah
04:59:47<copumpkin>"High-level floating-point arithmetic functions (mpf). This is the GMP function category to use if the C type `double' doesn't give enough precision for an application. There are about 65 functions in this category."
05:00:00<copumpkin>they also have fast rationals
05:00:09<copumpkin>maybe I'll stuff a bunch of GMP primops in
05:04:16<Cale>Hehe, by 6.12, we'll have arbitrary-precision floating point numbers in base :)
05:04:32<copumpkin>really?
05:04:43<Berengal>I wouldn't be sad if that happened...
05:04:44<copumpkin>or do you mean because I plan on sticking the primops in? :P
05:04:52<dolio>You could probably make a separate library out of the floating point/rational stuff.
05:04:52<Cale>copumpkin: just that
05:05:08<copumpkin>yeah, my main objective at first was just to stick modexp in
05:05:13<copumpkin>and dolio wanted something too, but I forgot what :P
05:06:01<dolio>The only reason I think you can't do Integer stuff like that easily is that GHC does fancy stuff with the GMP representation to get its internal representation of Integers.
05:06:13<dolio>And I don't know how to work with that via the FFI.
05:07:06<alkaid>ok ppl... It's 2 a.m. here in Brazil and I have a seminar to watch in a few hours
05:07:10<dolio>If it were just wrapping a ForeignPtr or something it'd be clearer (though probably slower).
05:07:14<alkaid>so, good bye
05:07:17<Cale>alkaid: see you around!
05:07:23<alkaid>see ya
05:09:01<lpsmith>Cale: why not exact real arithmetic as well? :-P
05:09:42<lpsmith>Is the GMP exact real, or arbitrary precision, in the sense that you can choose the precision needed for the computation beforehand?
05:10:07<dolio>If I recall correctly, you choose the precision beforehand.
05:10:10<Cale>lpsmith: I would like exact real, but GMP's implementation is only arbitrary precision, I think.
05:10:17<lpsmith>ahh
05:10:22<lpsmith>still useful :-)
05:10:40<c_wraith>exact real is an... *interesting*... concept. :)
05:11:17<copumpkin>what percentage of all reals are computable? ;)
05:11:36<DOKKA>hey yall, so anyways I'm a bit of a noob
05:11:39<c_wraith>There are an uncountable number of reals without any finite representation. :)
05:11:40<dolio>0
05:11:47<DOKKA>and I have a program for yall to look at
05:12:05<DOKKA>http://www.scuffmark.tk/listLen.txt
05:12:05<lpsmith>lol, yes, 0
05:12:18<copumpkin>so that's useless! :P
05:12:31<lpsmith>Almost every real exists only as the limit of a infinite random process
05:12:35<DOKKA>it's rediculously simple, yet it won't run
05:12:57<lpsmith>copumpkin: at least the computable reals are dense :-P
05:13:04<copumpkin>so am I
05:13:29<c_wraith>I claim the real numbers are too big of a set to be really useful. >_>
05:13:47<roconnor>DOKKA: are you trying to run it in GHCi?
05:14:05<DOKKA>yes
05:14:23<lpsmith>c_wraith: sometimes I agree. I go back and forth. Unfortunately real analysis isn't my strong suit. :)
05:14:45<DOKKA>I am trying to make a function that finds the length of a list
05:15:16<QtPlaty[HireMe]>DOKKA: Rather then using the built in lenght function?
05:15:18<DOKKA>it does load
05:15:34<DOKKA>it's an excersize from the book
05:15:36<lpsmith>two problems with the LHS of your definitions:
05:15:37<QtPlaty[HireMe]>*length
05:15:39<lpsmith>well
05:15:40<lpsmith>three
05:15:42<roconnor>*Main> listlen [1,2,3]
05:15:44<roconnor>2
05:15:53<roconnor>DOKKA: runs for me
05:16:04<lpsmith>oh
05:16:04<roconnor>$ ghci /tmp/foo.hs
05:16:25<roconnor>what's the question about exact real arithmetic?
05:16:43<DOKKA>hmm
05:16:55<DOKKA>what's a LHS?
05:16:59<lpsmith>right, you are defining two different functions. Heh, read that as one definition. :-D
05:17:03<Berengal>left hand side
05:17:03<lpsmith>Left hand side
05:17:10<DOKKA>ah
05:17:11<QtPlaty[HireMe]>DOKKA: What should the lenght of [] be?
05:17:22<DOKKA>oh crap I see it now
05:17:53<lpsmith>roconner: I'm not sure there was a question about exact real arithmetic, other than clarifying that's not what the GMP will be adding
05:18:07<lpsmith>roconner: but feel free to expound on it, by all means :-)
05:18:22<roconnor>GMP only does integer arithmetic, right?
05:18:25<DOKKA>it should be 0
05:18:39<copumpkin>no
05:19:02<copumpkin>it does int, rational, and "float"
05:19:06<lpsmith>According to Cale, the GMP will be adding arbitrary precision reals sometime soonish.
05:19:07<QtPlaty[HireMe]>DOKKA: So would 'listlen [] = 0' work as your base case?
05:19:08<roconnor>ah
05:19:14<roconnor>copumpkin: I didn't know that
05:19:31<Cale>lpsmith: Um, according to copumpkin, it already has them?
05:19:39<DOKKA>I guess it would
05:19:50<lpsmith>I dunno, this is the first I heard of such things!
05:19:57<Cale>lpsmith: (I was trusting copumpkin)
05:20:09<QtPlaty[HireMe]>DOKKA: What would the lenght of (x:xs) be?
05:20:20<dolio>It's also according to the documentation. :)
05:20:21<DOKKA> QtPlaty[HireMe]: 2
05:20:28<mauke>QtPlaty[HireMe]: at least you're consistent :-)
05:20:34<Cale>DOKKA: Remember that xs is another list.
05:20:36<QtPlaty[HireMe]>DOKKA: Not quite?
05:20:39<Mortomes>DOKKA: Out of curiousity, have you programmed in Prolog before?
05:20:51<Cale>DOKKA: It might even be the empty list
05:21:00<mauke>> length (42 : [])
05:21:03<lambdabot> 1
05:21:05<copumpkin> that's cause I hacked their site and rewrote their documentation to further my own mysterious agenda
05:21:06<DOKKA>nope, just java and
05:21:08<Cale>DOKKA: However, you can express the length of (x:xs) in terms of the length of xs
05:21:10<DOKKA>pythin
05:21:31<Berengal>DOKKA: Also, tail calls in Haskell... don't do what you seem think they do
05:21:49<DOKKA>ah, yeah
05:21:57<QtPlaty[HireMe]>DOKKA: If you knew the length of xs could you work out the lenght of (x:xs) ?
05:22:01<Cale>DOKKA: It's just one more element, right?
05:22:16<DOKKA>right
05:22:27<Cale>DOKKA: So what's the equation? :)
05:22:33<QtPlaty[HireMe]>DOKKA: Can you write that as a haskell function?
05:22:44<lpsmith>Berengal: yes and no. Tail calls work a little bit differently, but they are still an important concept in Haskell
05:22:51<DOKKA>hmm
05:23:15<DOKKA>could this be done with recursion?
05:23:23<QtPlaty[HireMe]>DOKKA: Yes
05:23:32<lpsmith>DOKKA: you are using recursion!
05:23:37<Berengal>lpsmith: I wouldn't say "just a bit". They're different enough that you need to know exactly how they work
05:23:40<tsLight>DOKKA, this is called primitive recursion =)
05:23:40<DOKKA>I know
05:23:47<mauke>it has to be done with recursion; [] is a recursive type :-)
05:23:53<Cale>DOKKA: Basically, if you just write down "the length of (x:xs) is 1 more than the length of xs" in Haskell notation, you'll be done :)
05:24:17<lpsmith>Berengal: how so?
05:24:26<QtPlaty[HireMe]>DOKKA: As long as you have the base case there already
05:24:27<DOKKA>but how do I return the answer?
05:24:35<lpsmith>tsLight: DOKKA's code as is is not primitive recursive.
05:24:46<lpsmith>It uses an accumulator
05:24:51<tsLight>lpsmith, I am talking about using [] as base case and then x:xs as the recursive step
05:24:52<Cale>DOKKA: the right hand side of the equation is the answer
05:25:01<QtPlaty[HireMe]>DOKKA: The stuff on the right hand side is returned
05:25:44<DOKKA>right
05:25:56<Berengal>lpsmith: Well, tail calls can overflow the stack. non-tail-recursive recursion can run in constant stack...
05:26:29<p_l>... wasn't it the other way around?
05:26:34<Cale>DOKKA: So, to summarize, it's just length [] = 0; length (x:xs) = 1 + length xs
05:26:53<QtPlaty[HireMe]>p_l: Lazyness screws around with that.
05:27:08<Berengal>p_l: "Can", not "has to".
05:27:13<mauke>abstract class List { int length(); } class Nil extends List { int length() { return 0; } } class Cons extends List { Object head; List tail; int length() { return 1 + tail.length(); } }
05:27:31<DOKKA>Cale: wow you can do that?
05:27:31<MyCatVerbs>p_l: if you tail call to a constructor, then you can run in constant stack.
05:27:32<Cale>Berengal: Even saying that is a bit misleading, since the stack's purpose is entirely different in GHC.
05:27:38<Cale>DOKKA: yep
05:27:44<lpsmith>tsLight: Ahh you are right, I was getting primitive recursion mixed up with natural recursion.
05:28:00<dolio>copumpkin: One issue with the floating point numbers is how you decide on a precision. Presumably with the type, but type-level naturals (for representing the size) are currently kind of a pain.
05:28:03<kerlo>DOKKA: is there any reason in particular you would expect to not be able to do that?
05:28:14<p_l>ok, so it's because lazyness makes such stuff interesting :D
05:28:16<MyCatVerbs>p_l: e.g. map f (a:as) = (f a) : map f as -- in this case, you're tail-calling (:) on (f a) and (map f as).
05:28:18<Berengal>Cale: Well, yes... Haskell code doesn't really have a concept of stack, at least not directly
05:28:20<copumpkin>dolio: oh yeah, we need that PhD that was advertised on -cafe :P
05:28:32<Gracenotes>mauke: you definition has made me a bit nauseous >_<
05:28:33<tsLight>DOKKA, read on "pattern matching"
05:28:34<Gracenotes>r
05:28:35<lpsmith>Natural recursion might not have a precise definition, but I've heard several FP gurus use the term. Using an accumulator isn't "natural"
05:28:36<MyCatVerbs>p_l: and you end up with a list cell where the car is (f a) and the cdr is (map f as). ^^
05:28:36<tsLight>its really useful
05:28:44<DOKKA>returning 1+listLen is just kinda strange
05:29:01<kerlo>ACTION shrugs
05:29:04<tsLight>DOKKA, the thing is you are applying the function to a "smaller list"
05:29:06<DOKKA>I wouldn'rt expect it to know what to do with the integer
05:29:08<QtPlaty[HireMe]>DOKKA: You will get used to it.
05:29:13<tsLight>so it will eventually reach the base case and finish
05:29:28<QtPlaty[HireMe]>DOKKA: Why wouldn't you expect it?
05:29:34<mauke>DOKKA: does my pseudo java code look more natural to you?
05:29:43<Cale>DOKKA: well, length xs is a legitimate integer.
05:29:48<DOKKA>because it has no arguments
05:29:59<lpsmith>Berengal: I haven't quite figured out how GHC's stacks work, though I have a pretty good sense about how to make code run fast. If you use tail calls, you often need to make sure things are strict; then they really are tail calls like in ML.
05:30:16<DOKKA>so it just ads the +1's and returns them
05:30:16<QtPlaty[HireMe]>DOKKA: 1 + (listLen xs)
05:30:22<Cale>DOKKA: The only important thing to realise is that since xs is going to be shorter than (x:xs) each time, eventually you will reach length [], which will finally give 0
05:30:50<DOKKA>right, because that is used to deconstruct the list
05:30:55<QtPlaty[HireMe]>DOKKA: More or less.
05:31:00<Cale>DOKKA: and so it won't just keep recursing forever, unless the list happens to be infinitely long
05:31:05<Berengal>lpsmith: map isn't tail-recursive, yet runs in constant stack.
05:31:09<Gracenotes>DOKKA: it evaluates something like this: length "hello" ... 1 + length "ello" ... 2 + length "llo" ... 3 + length "lo" ... 4 + length "o" ... 5 + length "" ... 5 + 0 = 5
05:31:12<MyCatVerbs>> sum . map (const 1) $ [1..1000]
05:31:15<lambdabot> 1000
05:31:41<Cale>map is better than tail-recursive, it always produces a constructor application.
05:31:42<Gracenotes>(Haskell being lazy changes it a bit, but that's what's going on)
05:31:46<DOKKA>Gracenotes: that makes sense
05:31:50<lpsmith>Berengal: because it's constantly allocating thunks on the heap instead :-P
05:31:50<Cale>So in some sense it's constant time ;)
05:31:57<MyCatVerbs>> foldl (\a _ -> a+1) 0 [1..1000]
05:32:00<lambdabot> 1000
05:32:08<Baughn>lpsmith: The stack is used to evaluate thunks. Sometimes you need to recursively evaluate more thunks before you can finish the first one; that is when you can get stack overflows.
05:32:28<Cale>(of course, it's really constant time per list element)
05:32:32<MyCatVerbs>Cale: it tail-calls a constructor. ^_^
05:32:52<DOKKA>like a fork bomb
05:33:13<Berengal>lpsmith: And that's sort of the point...
05:33:19<Gracenotes>DOKKA: except, on every recursive call, you're waiting for the results of the next call
05:33:27<Cale>Gracenotes: That's not quite right, because you made use of the associativity of (+), and the compiler doesn't.
05:33:28<DOKKA>righ
05:33:55<lpsmith>Ahh, depth of thunks, that makes sense. Well, you definitely don't want to use the "natural recursive" definition of length then, because it will blow the stack.
05:34:09<MyCatVerbs>@pl \a _ -> succ a
05:34:10<lambdabot>const . succ
05:34:12<DOKKA>so the way that I wrote this program, would it work at all? -just curious
05:34:12<Gracenotes>Cale: yeah. Easier than writing 1 + 1 + 1 + ...
05:34:23<Baughn>lpsmith: Yep
05:35:01<Cale>It's really like length "hello" -> 1 + length "ello" -> 1 + (1 + length "llo") -> 1 + (1 + (1 + length "lo")) -> 1 + (1 + (1 + (1 + length "o"))) -> 1 + (1 + (1 + (1 + (1 + length "")))) -> 1 + (1 + (1 + (1 + (1 + 0))))
05:35:43<Cale>-> 1 + (1 + (1 + (1 + 1))) -> 1 + (1 + (1 + 2)) -> 1 + (1 + 3) -> 1 + 4 -> 5
05:36:18<Berengal>> let len xs = execState (forM xs (const $ do get >>= put . (+1))) 0 in len [1..10]
05:36:20<lambdabot> 10
05:36:21<Cale>DOKKA: You can use an accumulating parameter and a helper function if it suits you
05:36:27<Cale>DOKKA: like:
05:36:36<Cale>length xs = length' 0 xs
05:36:42<Cale>length' n [] = n
05:36:52<Cale>length' n (x:xs) = length' (n+1) xs
05:37:52<Baughn>lpsmith: The return value of map, meanwhile, doesn't have that problem because the first thunk (the first list value) can be evaluated without knowing the value of the others
05:38:08<Baughn>lpsmith: ..technically, you can figure that out by looking for constructors in the definition
05:38:14<DOKKA>ok
05:40:00<QtPlaty[HireMe]>Baughn: Can't you find the nth value of map without evaluating the other n?
05:40:29<DOKKA>Well, thanks yall! I guess I'm gonna do some more reading
05:40:32<lpsmith>QtPlaty[HireMe]: Yes
05:40:32<Cale>DOKKA: Normally, we'd also stick the length' definition inside of a 'where'
05:40:51<Berengal>QtPlaty[HireMe]: Well, you need to evaluate the others to whnf...
05:40:57<DOKKA>what is the ' for?
05:41:08<QtPlaty[HireMe]>expn whnf?
05:41:09<lpsmith>QtPlaty[HireMe]: but at the cost of allocating a bunch of thunks, which isn't a win for small computations.
05:41:27<Cale>DOKKA: just a convention for modifying a name of something to name something related to it
05:41:47<DOKKA>ah
05:41:57<Cale>DOKKA: In this case, length and length' are separate functions, but length' only serves to help us write length
05:42:34<DOKKA>ok, I guess I haven't gotten that far in the book
05:42:42<Cale>Sometimes it indicates a version of a function which is stricter
05:42:53<DOKKA>oh
05:42:59<Cale>Like in the case of foldl and foldl'
05:43:03<QtPlaty[HireMe]>DOKKA: Alot of learning is unlearning.
05:43:05<mauke>> let x = 1; x' = succ x; x'' = succ x' in (x, x', x'')
05:43:07<lambdabot> (1,2,3)
05:43:11<Cale>but in this case, it just indicates a variation
05:43:20<monochrom>> (map id [undefined, undefined, 'c']) !! 2
05:43:21<lambdabot> 'c'
05:43:30<Baughn>QtPlaty[HireMe]: No
05:43:40<monochrom>My example is for your discussion.
05:43:44<Cale>DOKKA: (it's just a naming convention, an apostrophe is a valid character in variable names)
05:43:48<Baughn>QtPlaty[HireMe]: By "values", here, I meant the spine of the list
05:43:49<DOKKA>ok, I think i get it
05:44:13<DOKKA>and yeah I am having to do a lot of unlearning
05:44:22<Cale>Normally if you read it aloud, you say the ' as "prime"
05:44:25<QtPlaty[HireMe]>Baughn: So you mean the pairs of thunks.
05:44:33<Cale>It's a convention stolen from mathematics and physics.
05:44:35<lpsmith>Yep, apostrophes customarily come at the end, but you can put them in the middle
05:44:37<lpsmith>like
05:44:45<Baughn>QtPlaty[HireMe]: The list spine.
05:44:49<lpsmith>cale's_function is a legitimate identifier
05:45:13<DOKKA>i see
05:45:18<QtPlaty[HireMe]>Baughn: Can you explain what you mean by the list spine?
05:45:19<monochrom>Oleg always writes like zip'iterator
05:45:22<mauke>> let don't _ = () in don't (error "!")
05:45:24<lambdabot> ()
05:45:50<Baughn>QtPlaty[HireMe]: If you take a list, and change its type to [()], the spine is what is left of its structure
05:46:12<lpsmith>monochrom: hmm, I almost like that better than camelCase or ugly_underscores.
05:46:19<Berengal>Basically, the spine of a list is it's cons cells...
05:46:24<DOKKA>it is a very interesting language
05:46:27<monochrom>Yes, it's refreshing.
05:46:27<lpsmith>Honestly I wish hyphenated identifiers were legal.
05:46:42<mauke>lpsmith: I agree
05:46:47<DOKKA>and it causes you to think about how to write it before you write anything
05:47:03<QtPlaty[HireMe]>lpsmith: Though it makes doing things like 2-1 interesting.
05:47:18<Cale>DOKKA: Well, especially so when you're not used to writing things in a functional style
05:47:22<mauke>DOKKA: I think that depends on how familiar you are with it
05:47:46<DOKKA>true, this is my first week
05:47:50<Cale>Eventually, it becomes a chore to figure out how to express your program imperatively, and the functional way is the first thing you think of.
05:47:59<Cale>(at least, that's the case with me)
05:48:02<Berengal>Haskell really starts to become fun when you can juggle folds, fmaps and flips like it was second nature
05:48:14<DOKKA>that's what I'm looking for
05:48:18<Berengal>Okay, that was badly worded...
05:48:30<mauke>I cank think in Haskell and Perl and I have no problems with either
05:48:41<mauke>but OCaml sits at exactly the wrong spot :-)
05:48:48<Baughn>Haskell really starts to become fun when the arrow syntax makes sense to you and seems useful. ;)
05:48:58<DOKKA>I want to be able to write shorter code that does more
05:49:02<Berengal>I can still program Java just fine, except I now have a burning hatred for it's type system...
05:49:22<mauke>Berengal: see, that's something Haskell and Perl programmers have in common :-)
05:49:54<Berengal>mauke: Not surprised
05:49:58<lpsmith>Berengal: I have a burning hatred of pretty much all OO type systems. At least the ones that aren't dynamic.
05:49:58<mikm>I think anybody who has programmed in a different languages feels that way
05:50:01<DOKKA>I don't really care for java, mainly because of all the objects you have to create to get a basic program running
05:50:58<DOKKA>*gui program running
05:51:06<Gracenotes>but see also Python's type system, where types are essentially tags with little other meaning
05:51:13<Gracenotes>well, at least it stays out of your way
05:51:47<QtPlaty[HireMe]>@pl l x = x
05:51:47<lambdabot>l = id
05:51:59<tsLight>data Rational = Integer : / Integer deriving Eq -> what does the : / stand for?
05:52:21<QtPlaty[HireMe]>@pl l x = case x of {[]->0;(_:xs) -> 1 + l xs}
05:52:22<lambdabot>(line 1, column 17):
05:52:22<lambdabot>unexpected "{"
05:52:22<lambdabot>expecting variable, "(", operator or end of input
05:52:22<mauke>tsLight: it's actually :/
05:52:32<lpsmith>Gracenotes: yep. With a dynamic type system like Python's, I can pretend I'm programming in HM (most of the time, unless I see good reason not to) and the illusion works.
05:52:44<mauke>tsLight: the ':' is an uppercase symbol. it's used to start infix constructor
05:52:45<Gracenotes>Rational is :% incidentally
05:52:53<Berengal>Gracenotes: I sort of like python's type system... Python generally discourages typed programming, letting the objects themselves take care of their types, which is how dynamic typing works best
05:52:58<Gracenotes>maybe you're seeing it as :o/o
05:53:05<Gracenotes>or something :x
05:53:05<mauke>tsLight: it's equivalent to data Rational = R Integer Integer deriving Eq
05:53:15<tsLight>ah
05:53:24<mauke>Gracenotes: Rational is actually a 'type', not a 'data' :-)
05:53:34<Gracenotes>yeah. the constructor, though
05:53:42<copumpkin>Ratio
05:53:45<Gracenotes>which I assumed we are all talkin' bout! come on nao.
05:53:47<Gracenotes>:)
05:53:51<tsLight>so 4 :/ 5 would be equivalent to 4 `R` 5 ?
05:53:53<mauke>I don't think this is the Data.Ratio version
05:53:57<mauke>tsLight: exactly
05:54:03<QtPlaty[HireMe]>lpsmith: With type inference like in Haskell I can pretend I'm programing with a dynamtically typed language.
05:54:05<Gracenotes>oh, I see
05:54:12<tsLight>and the "/" can be anything I want?
05:54:20<mauke>tsLight: well, any operator
05:54:25<tsLight>":Joe" wouldnt work?
05:54:26<tsLight>:P
05:54:30<mauke>:+??+ is valid, for example
05:54:45<Gracenotes>anything that's a valid infix symbol is a valid infix constructor, with a : tacked on
05:54:53<Gracenotes>as far as I know :o
05:55:24<Gracenotes>and of course the most famous infix constructor of them all, :
05:55:32<Berengal>data Emoticon = :) | :( | :$ | :/
05:56:07<tsLight>lol that works?
05:56:11<mauke>no
05:56:14<tsLight>haha
05:56:23<Berengal>No parenthesis unfortunately
05:56:31<mauke>first of all, you're missing operands for the infix constructors
05:56:55<Berengal>That too
05:57:43<tsLight>and if I "string" them
05:57:51<tsLight>data Emoticon = ":)" | ":(" | ":$" | ":/"
05:57:51<Gracenotes>let (:|) = ":|" in (:|)
05:57:52<Berengal>kweztshun = CanHas cheezbagah :) Lol
05:57:56<Gracenotes>> let (:|) = ":|" in (:|)
05:57:57<lambdabot> Not in scope: data constructor `:|'Not in scope: data constructor `:|'
05:57:57<tsLight>that would be an enumerated type?
05:58:12<mauke>you can't string symbols
05:58:13<Gracenotes>oh... I did not know that ":" was an exclusive data constructor
05:58:34<tsLight>so how could I write that an emoticon is any of those strings
05:58:40<tsLight>list them?
05:58:42<Berengal>Gracenotes: It's like capital letters in regular identifiers
05:58:54<Gracenotes>perverted. but cool
05:58:54<tsLight>not declaring an algebraic type :P
05:58:55<Cale>tsLight: Haskell doesn't have subtyping.
05:59:13<tsLight>ah
05:59:33<Cale>tsLight: So you could say data Emoticon = Smile | Frown | DollarMouth | Disappointed
05:59:41<Cale>But you can't make them actual strings
05:59:47<tsLight>but I can define show for them :)
05:59:54<Gracenotes>> text . unwords $ sequence [":;", "-", ")($/"]
05:59:55<lambdabot> :-) :-( :-$ :-/ ;-) ;-( ;-$ ;-/
06:00:08<copumpkin>what about P ?
06:00:18<copumpkin>no smiley is complete without the P
06:00:22<Gracenotes>your command is my sequence!
06:00:28<copumpkin>lol
06:00:37<mauke>·_·
06:00:55<monochrom>data Emoticon = Int :> Bool | Bool :< Int
06:00:58<Gracenotes>your cosequence is my cocommand
06:01:00<Asztal>> let (・∀・) = (+) in x ・∀・y -- doesn't work :(
06:01:01<lambdabot> <no location info>: lexical error at character '\12539'
06:01:05<copumpkin>¬_¬
06:01:28<mauke>your cosequence is my mmand
06:01:35<Berengal>·_˙
06:01:35<copumpkin>lol
06:01:52<copumpkin>ACTION wants to use ContraFunctors
06:02:03<Gracenotes>your comonad is my functor
06:02:08<Gracenotes>allegedly
06:02:20<mauke>ContraFungi
06:02:30<Berengal>So what's a ContraFunctor?
06:02:54<Berengal>funmap :: (f a -> f b) -> a -> b?
06:03:07<monochrom>(a->b) -> (f b -> f a)
06:03:08<copumpkin>(a -> b) -> f b -> f a
06:03:10<Gracenotes>looks dangerous :o
06:03:16<copumpkin>:P
06:03:42<Gracenotes>and .. unusable
06:03:46<Berengal>Isn't that just regular functors though?
06:03:49<copumpkin>no
06:03:53<copumpkin>:t fmap
06:03:55<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
06:04:02<Gracenotes>what are some instances?
06:04:04<copumpkin>notice that the b and a got reversed on the way out
06:04:15<Berengal>Oh, right, didn't notice the flipped arguments
06:04:29<Berengal>So how would that work anyway?
06:04:31<copumpkin>the only instance I've been able to think of is a fold, but I'm sure there are others
06:04:51<copumpkin>Berengal: it's got to do with you having (c ->) as the ContraFunctor instance
06:04:56<copumpkin>I mean
06:05:00<copumpkin>(-> c)
06:05:06<Gracenotes>oh, yes, that came to mind
06:05:22<Gracenotes>newtyped though >_>
06:05:25<copumpkin>it has to be
06:05:31<Gracenotes>no kind-fu
06:06:51<copumpkin>I'm not sure what the right way to define an instance of ContraFunctor is though
06:07:42<sw2wolf>I am haskell newbie, I want to know to write [[1,2,3,4,5],[6,7,8,9,10]] to file and read it back later
06:08:22<Gracenotes>@type let cfmap :: (a -> b) -> f b -> f a; u = undefined in cfmap . cfmap
06:08:24<lambdabot>Not in scope: `cfmap'
06:08:24<lambdabot>Not in scope: `cfmap'
06:08:24<lambdabot>Not in scope: `cfmap'
06:08:31<Gracenotes>@type let cfmap :: (a -> b) -> f b -> f a; cfmap = undefined in cfmap . cfmap
06:08:32<lambdabot>forall (f :: * -> *) a b (f1 :: * -> *). (a -> b) -> f (f1 a) -> f (f1 b)
06:08:37<Gracenotes>ah.
06:08:51<copumpkin>contramap
06:09:01<copumpkin>is what edwardk called it
06:09:21<Gracenotes>sw2wolf: well, a basic way to do it is to just "show" it and "read" it back again. read . show is supposed to be an identity.
06:09:57<Gracenotes>for storing data in files, Data.Binary is essentially the Haskell pickling/serialization module
06:10:08<Gracenotes>it's just a straightforward encoding to binary
06:10:42<Gracenotes>@hackage binary
06:10:43<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary
06:11:21<sw2wolf>thank you
06:11:28<Gracenotes>> read "[[1,2,3,4,5],[6,7,8,9,10]]" :: [[Int]]
06:11:29<lambdabot> [[1,2,3,4,5],[6,7,8,9,10]]
06:11:39<copumpkin>newtype ContraFold a b = ContraFold { runContraFold :: Fold b a }
06:11:40<Gracenotes>^ less efficient, but definitely less work
06:11:51<copumpkin>ACTION feels l33t
06:12:01<copumpkin>even though the newtype is too much of a pain to deal with
06:12:11<copumpkin>so I'm just going to leave the instance there and not do anything with it
06:13:39<Gracenotes>afaik Data.Binary isn't amazingly speedy either, but that's strings for you
06:14:16<mmorrow>if anyone wants to try this out, it's in a working-but-i-still-want-to-tweak-it-plus-clean-the-code-up state http://moonpatio.com/repos/vacuum-gl/
06:14:17<lambdabot>mmorrow: You have 1 new message. '/msg lambdabot @messages' to read it.
06:14:29<monochrom>The easiest examples of cofunctors come from comonads.
06:15:33<mmorrow>lots of hair-ripping-out happened before i finally learned that OpenGL uses thread-local state, so you need to forkOS and make sure you stay in that os thread...
06:15:43<copumpkin>ew
06:16:06<mmorrow>i was segfaulting like crazy with forkIO + -threaded ;)
06:16:30<mmorrow>(since the rts migrates threads between os threads at will)
06:16:37<copumpkin>yeah
06:16:43<copumpkin>mmorrow: I got the epic foldage working nicely
06:16:56<mmorrow>copumpkin: ooh yay, link?
06:17:16<mmorrow>ah, you mean with uvector stuff?
06:17:21<copumpkin>well, in general
06:17:28<mmorrow>cool
06:17:48<copumpkin>http://github.com/pumpkin/folds/blob/6392dccfa870473364bfe5d9d5b1c2240b347f02/Folds.hs
06:17:54<copumpkin>I abandoned the GADT
06:17:58<mmorrow>heh
06:18:02<copumpkin>I had it working with GADT, but it wouldn't fuse
06:18:22<copumpkin>the flattening of the GADT was getting in the way, as far I could see
06:18:56<mmorrow>yeah, i realized later that the GADT would make it impossible to fuse, since the compiler doesn't have access to the "final product", since it gets built at runtime
06:19:02<copumpkin>yeah
06:19:09<copumpkin>it'd be nice if it did
06:19:11<copumpkin>they're constants
06:19:25<copumpkin>it can work with other constants at compile time can't it?
06:19:26<mmorrow>yeah, TH (or equiv) would be needed
06:19:35<copumpkin>yeah, I've been thinking of trying this all in TH next
06:19:43<copumpkin>because I still have a major problem with it
06:20:08<copumpkin>namely that I can't share across parallel folds
06:20:20<mmorrow>copumpkin: there's this one paper on using TH to optimize edsl's
06:20:26<copumpkin>ooh
06:20:28<mmorrow>you might find it relevant/interesting
06:20:29<copumpkin>that could be helpful
06:20:45<copumpkin>mmorrow: take a look at the ugly linregF beast btw :P
06:20:59<mmorrow>http://haskell.org/th/papers/th-pan.ps
06:21:10<mmorrow>heh
06:21:12<copumpkin>that's the main reason I defined a Num instance for the folds, because all the infix-applicative stuff was getting ridiculous
06:21:19<copumpkin>thanks :)
06:22:19<copumpkin>but in the linregF, although I do it in one pass over the list
06:22:26<copumpkin>a lot of stuff is recomputed unnecessarily
06:22:39<mmorrow>copumpkin: i'm not sure the impact it would have, but maybe ! the intermediate thunks built up in the where (e.g. "beta = (n * sXY - sX * sY) / (n * sXX - sX * sX)")
06:22:56<copumpkin>well, this is only building up the function itself
06:23:11<mmorrow>hmm
06:23:19<copumpkin>so the output of that is just a Fold
06:23:24<copumpkin>with a monstrously complicated folding function
06:23:42<mmorrow>but wouldn't those thunks start to accumulate?
06:23:48<mmorrow>(as you fold)
06:23:58<copumpkin>hmm
06:24:10<copumpkin>I didn't think so, all the folds are strict by default
06:24:21<copumpkin>the way I do them, at least
06:24:28<mmorrow>, foldl' (\(a,b) c -> (a+c,b+c)) (0,0) [0..10000000]
06:24:32<lunabot> luna: out of memory (requested 1048576 bytes)
06:24:38<mmorrow>, foldl' (\(!a,!b) c -> (a+c,b+c)) (0,0) [0..10000000]
06:24:44<lunabot> Killed.
06:24:45<copumpkin>oh, but I'm using strict pairs
06:24:46<mmorrow>bah
06:24:55<copumpkin>for doing all the parallel stuff
06:25:07<mmorrow>, foldl' (\(!a,!b) c -> (a+c+c+c+c+c,b+c+c+c+c+c)) (0,0) [0..1000000]
06:25:10<copumpkin>lol
06:25:13<lunabot> Killed.
06:25:17<mmorrow>gah
06:25:20<mmorrow>, foldl' (\(!a,!b) c -> (a+c+c+c+c+c,b+c+c+c+c+c)) (0,0) [0..100000]
06:25:21<lunabot> (25000250000,25000250000)
06:25:24<mmorrow>, foldl' (\(!a,!b) c -> (a+c+c+c+c+c,b+c+c+c+c+c)) (0,0) [0..1000000]
06:25:30<lunabot> Killed.
06:25:58<mmorrow>, foldl' (\(!a,!b) c -> let !d = c+c; !e = d + d in (a+e,b+e)) (0,0) [0..1000000]
06:26:01<lunabot> (2000002000000,2000002000000)
06:26:08<mmorrow>, foldl' (\(!a,!b) c -> let d = c+c; e = d + d in (a+e,b+e)) (0,0) [0..1000000]
06:26:12<lunabot> (2000002000000,2000002000000)
06:26:18<mmorrow>hmm, inconclusive
06:26:23<copumpkin>but I'm not using regular pairs
06:26:37<mmorrow>yeah, but that's only take care of the top level
06:26:56<mmorrow>a regular pair with bangs is == to a strict pair (i believe)
06:27:02<copumpkin>oh, I see what you mean
06:27:09<mmorrow>(modulo ghc unpacking)
06:27:11<copumpkin>so if someone was building a listi n the pairs
06:27:18<copumpkin>you'd only force the head?
06:27:23<mmorrow>yes
06:27:29<copumpkin>hmm
06:27:57<copumpkin>I still managed to convince myself I didn't need any strictness annotations here
06:27:59<copumpkin>but maybe I do
06:28:19<mmorrow>yeah, i'm not sure if it would or wouldn't have an impact
06:28:31<mmorrow>i guess testing is the only way to know
06:28:39<copumpkin>I've tested it on big data
06:28:43<mmorrow>nice
06:28:43<copumpkin>but I'm not sure it's big enough
06:28:50<copumpkin>I was trying to compare to hstats
06:28:59<copumpkin>but hstats just overflows its stack
06:29:03<copumpkin>:/
06:29:14<mmorrow>yeah, hstats needs to s/foldr/foldl'/ bigtime
06:29:31<mmorrow>(if you do that, it runs ok)
06:29:36<copumpkin>ah
06:29:45<copumpkin>I wonder if my linreg is any faster than hstats with foldl'
06:29:52<copumpkin>I translated it directly
06:30:02<mmorrow>oh nice, that'd be interesting to see
06:30:04<copumpkin>from the hstats one, which does several passes over the lists
06:30:53<copumpkin>I'll convert its folds and try
06:31:19<copumpkin>does cabal-install compile with -O2 by default?
06:31:31<copumpkin>I think even the sum calls are failing because it's defined in terms of foldl
06:32:09<mmorrow>ok, i got an example
06:32:11<mmorrow>, foldl' (\(!a,!b) c -> let d = c + c + c + c; e = d + d + d + d; f = e + e + e + e + e in (a+f,b+f)) (0,0) [0..1000000]
06:32:17<lunabot> Killed.
06:32:19<mmorrow>, foldl' (\(!a,!b) c -> let !d = c + c + c + c; !e = d + d + d + d; !f = e + e + e + e + e in (a+f,b+f)) (0,0) [0..1000000]
06:32:25<lunabot> Killed.
06:32:28<mmorrow>grrr
06:32:29<mmorrow>, foldl' (\(!a,!b) c -> let !d = c + c + c + c; !e = d + d + d + d; !f = e + e + e + e + e in (a+f,b+f)) (0,0) [0..1000000]
06:32:35<lunabot> Killed.
06:32:43<mmorrow>it worked in /msg, i swear ;)
06:33:03<copumpkin>riiiight ;)
06:33:04<mmorrow>, foldl' (\(!a,!b) c -> let !d = c + c + c + c; !e = d + d + d + d; !f = e + e + e + e + e in (a+f,b+f)) (0,0) [0..1000000]
06:33:11<lunabot> (40000040000000,40000040000000)
06:33:14<mmorrow>woohoo
06:35:38<copumpkin>:)
06:37:22<mmorrow>, foldl' (\(!a,!b) c -> let !d = c + c; !dd = d + d; !e = dd + dd; !f = e + e; !g = f + f; !h = g + e; !i = h + h in (a+i,b+i)) (0,0) [0..1000000]
06:37:26<lunabot> (40000040000000,40000040000000)
06:37:28<mmorrow>hehe
06:38:04<mmorrow>(this is bytecode too, though... so no optims)
06:39:03<Nafai>nominolo_: So did you get much done with Scion at the Hackathon?
06:39:09<mmorrow>copumpkin: i like that Fold code, i'm gonna play with it
06:39:23<copumpkin>mmorrow: :) couple of warnings
06:39:32<copumpkin>it relies on an unreleased version of uvector for no real reason :P
06:39:44<copumpkin>and I think the latest on I pushed doesn't compile due to a failed liftA2 (==)
06:39:53<mmorrow>noted x2
06:41:34<YMan>Is this where Eddy Haskel chats ?
06:42:01<voker57__>how to insert value at certain position in list?
06:42:43<mmorrow>voker57__: if you're doing that a lot, then lists aren't what you want.... but that being said, you can use splitAt
06:43:14<voker57__>ok
06:44:00<sjanssen>YMan: no
06:44:04<mmorrow>, insertAt n x xs = let (ys,zs) = splitAt n xs in ys ++ [x] ++ zs in insertAt 9 42 [0..20]
06:44:05<lunabot> luna: parse error on input `='
06:44:10<mmorrow>, let insertAt n x xs = let (ys,zs) = splitAt n xs in ys ++ [x] ++ zs in insertAt 9 42 [0..20]
06:44:11<lunabot> [0,1,2,3,4,5,6,7,8,42,9,10,11,12,13,14,15,16,17,18,19,20]
06:44:46<Gracenotes>a foldr might work there, too
06:45:08<mmorrow>voker57__: check out Data.Sequence maybe
06:45:29<hotaru2k3>if i have a list like [1,2,3,4,5], is there an easy way to split it into ([1,2,3], [3,4,5])?
06:45:35<mmorrow>voker57__: (or Data.IntMap)
06:45:55<mmorrow>hotaru2k3: use splitAt and a case
06:46:01<voker57__>mmorrow: that was just a one-time... and i've already found out that i don't really need it.
06:46:12<mmorrow>voker57__: cool
06:46:19<voker57__>but thanks for pointers anyway
06:46:26<mmorrow>voker57__: (if you ever do though, Sequence or IntMap is the way to go)
06:46:33<mmorrow>voker57__: np
06:47:35<copumpkin>mmorrow: onoes, my single fold linreg is slower than the foldl'-multipass linreg in hstats
06:47:42<copumpkin>being beaten in performance by hstats is rough
06:47:46<copumpkin>ACTION cries to himself
06:47:48<mmorrow>, let split' n x xs = case splitAt n xs of (ys,z:zs) -> ys ++ z:z:zs; _ -> xs in split' 4 [0..9]
06:47:49<lunabot> luna: No instance for (GHC.Show.Show ([a] -> [a]))
06:47:57<mmorrow>, let split' n xs = case splitAt n xs of (ys,z:zs) -> ys ++ z:z:zs; _ -> xs in split' 4 [0..9]
06:47:58<lunabot> [0,1,2,3,4,4,5,6,7,8,9]
06:48:02<mmorrow>oops
06:48:11<sjanssen>copumpkin: you just have to start doing it wrong
06:48:17<hotaru2k3>mmorrow: i mean where it'd split [1,2,3,4,5] into ([1,2,3], [3,4,5]), and [2,3,4,5,6,7,8] into ([2,3], [3,4,5,6,7,8])...
06:48:20<sjanssen>copumpkin: in fact, do it cowrong
06:48:24<copumpkin>lol
06:48:26<mmorrow>, let split' n x xs = case splitAt n xs of (ys,z:zs) -> (ys++[z],z:zs); _ -> (ys,[]) in split' 4 [0..9]
06:48:27<lunabot> luna: Not in scope: `ys'
06:48:29<mmorrow>gah
06:49:06<sjanssen>I actually meant to type "stop doing it wrong", but the other way is funnier
06:49:08<mmorrow>hotaru2k3: so where you want to split is determined by the value to split on?
06:49:18<hotaru2k3>yeah
06:50:12<mmorrow>, let split' p xs = case break p xs of (ys,z:zs) -> (ys++[z],z:zs); _ -> (xs,[]) in split' (==4) [0..9]
06:50:13<lunabot> ([0,1,2,3,4],[4,5,6,7,8,9])
06:50:15<mmorrow>span/break
06:50:18<copumpkin>mmorrow: how easy is it for me to do transformations on the AST in a qq using haskell-source(-exts) ?
06:50:18<mmorrow>@src span
06:50:19<lambdabot>Source not found. Where did you learn to type?
06:50:22<mmorrow>@src break
06:50:23<lambdabot>break p = span (not . p)
06:50:42<copumpkin>[$fuse| lots of haskell code here |] would be fun
06:50:43<mmorrow>copumpkin: hmm, harder than doing them on the TH ast
06:51:00<mmorrow>copumpkin: yeah, that would. do you need stuff that TH doesn't have?
06:51:08<copumpkin>don't think so?
06:51:11<mmorrow>because the haskell-src-exts AST is way more complex
06:51:12<copumpkin>I'm still TH-clueless
06:51:25<copumpkin>how would I do it in regular TH?
06:51:47<copumpkin>I mean, what would the syntax look like?
06:51:55<mmorrow>copumpkin: so what's something (the most basic/simple example you can think of) that you'd want to do?
06:52:46<copumpkin>mmorrow: take someone who wrote mean xs = sum xs / genericLength xs, build the folds like I did earlier, and output a "fused" fold
06:52:50<hotaru2k3>> let n = 3 in (takeWhile (<= n) &&& dropWhile (< n)) [1,2,3,4,5]
06:52:52<lambdabot> ([1,2,3],[3,4,5])
06:53:17<copumpkin>mmorrow: obviously with knowledge that sum and genericLength can be expressed as folds
06:53:28<mmorrow>copumpkin: ok, cool. so what would be the result of fusing, in regular haskell syntax?
06:54:10<copumpkin>uncurry (/) . foldl ((+) *** const . (+1)) (0, 0)
06:54:12<copumpkin>or something like that
06:54:24<copumpkin>minus the arrow dependency
06:54:35<copumpkin>basically what the folds thing is already doing
06:54:44<copumpkin>but without the applicative
06:55:31<copumpkin>the benefit of the TH approach being that people can write their folds freeform, and that I can eventually reason about common subexpressions in the fold function
06:55:40<copumpkin>and (I think safely) factor them out
06:56:16<copumpkin>unlike the more general CSE issues that GHC avoids
06:57:26<mmorrow>ok, thinking..
06:57:57<copumpkin>so I'd basically be doing a restricted form of the simplifier in GHC, with more flexible rewrite rules
06:58:10<copumpkin>and a lambdabot-like list of stdlib folds
06:59:58<copumpkin>but maybe I should wait for BSP to finish his plugins
07:00:03<copumpkin>and try writing this where it belongs
07:00:14<copumpkin>as there's all sorts of painful stuff I'd need to be doing
07:00:36<copumpkin>things like propagating let/where definitions, simplifying them, and so on
07:00:47<hotaru2k3>> let n = 3 in (fst &&& (uncurry (:) . first last)) $ (span (<= n)) [1..5]
07:00:49<lambdabot> ([1,2,3],[3,4,5])
07:04:26<Gracenotes>@type last
07:04:28<lambdabot>forall a. [a] -> a
07:04:38<Gracenotes>oh, duh
07:08:59<copumpkin>mmorrow: did you see that the new GHC build system got merged in today?
07:09:08<mmorrow>copumpkin: no, nice
07:09:54<thoughtpolice>copumpkin: once hc-bootstrapping is in, ghc will hopefully be on 64-bit osx soon enough :)
07:09:59<copumpkin>yeah :)
07:10:02<copumpkin>and iphone :D
07:10:08<ivanm>@seen sjanssen
07:10:09<lambdabot>sjanssen is in #haskell-in-depth, #haskell-overflow, #haskell-blah, #xmonad and #haskell. I last heard sjanssen speak 21m 2s ago.
07:10:11<voker57__>how to split list into N parts with equal (or less than equal for last part) number of elements?
07:10:25<copumpkin>and then BSP can merge in his ghc plugins stuff, and I'll be very happy
07:10:42<ivanm>sjanssen: how can I then use that monoid to find the first list of maximum size?
07:11:18<copumpkin>ivanm: which monoid?
07:11:46<ivanm>copumpkin: one that sjanssen @told me about for use in a fingertree ;-)
07:11:50<coolsner>haha, my dual is "cool" :P
07:11:52<copumpkin>ah
07:12:12<dolio>Sounds like a brand of beer.
07:12:19<sjanssen>ivanm: you use the split function
07:12:24<copumpkin>voker57__: you could takeWhile (not . null) . map (take n) . iterate (drop n)
07:12:29<dolio>After a hard day's work, crack open an ice cold coolsner.
07:13:06<copumpkin>voker57__: where n in my case is the number of elements in each list, not the number of parts
07:13:15<ivanm>sjanssen: but that won't tell me what the maximum length _is_
07:13:23<ivanm>just that if I know what it is, I can split it
07:13:32<sjanssen>ivanm: you use 'measure' to find what the maximum value is
07:13:37<sjanssen>FingerTree caches that value
07:13:52<ivanm>sjanssen: oh, so I can do "measure tree" ?
07:14:02<ivanm>_that_ was what I couldn't work out!
07:17:31<ivanm>sjanssen: is there then any easy way of converting a fingertree to a Sequence? I after finding the maximum list, I need to append the rest of them onto another "list" of lists, which I have to replace a sublist which == another list :s
07:18:26<sjanssen>ivanm: I don't know of anything other than fromList . toList
07:19:27<glguy>FingerTrees get toList from Foldable
07:19:58<sjanssen>ivanm: could this other "list" be a FingerTree too?
07:20:09<sjanssen>I guess I don't know what operations you need on that data
07:20:29<ivanm>sjanssen: it can be
07:20:51<guenni>how can I encapsulate a non IO Error, ie. a "read" error for instance?
07:20:53<ivanm>but I would need to split it on (== someOtherList)
07:21:06<ivanm>guenni: using Maybe or Either String ?
07:21:09<glguy>guenni, make it an IO eror with readIO
07:21:27<mmorrow>pumpkin: something like this http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2250#a2250
07:21:29<guenni>thx
07:21:42<mmorrow>pumpkin: (which is the minimal skeleton i think)
07:21:53<glguy>guenni, There is a can of worms that you can open called "asynchronous exceptions"
07:21:53<mmorrow>copumpkin: i mean copumpkin
07:21:54<copumpkin>oh wow, thanks
07:22:01<glguy>but that is really just after your last resort
07:22:10<glguy>:t reads
07:22:12<lambdabot>forall a. (Read a) => String -> [(a, String)]
07:22:22<ivanm>sjanssen: my main problem with FingerTree is that it seems you can't do anything that isn't covered by the monoid
07:22:22<sjanssen>ivanm: oh, on equality, eh?
07:22:26<ivanm>yup
07:22:27<glguy>another way to safely use read
07:22:28<sjanssen>ivanm: does the order you insert in matter?
07:22:31<mmorrow>copumpkin: i've thought about this before, but never wrote anything down. i'm interested to hear how it does
07:22:39<ivanm>so unless I make the monoid List (Int, [a])
07:22:43<ivanm>sjanssen: yes
07:22:49<copumpkin>mmorrow: I'd still eventually like to dip into the ghc plugins for this
07:22:55<sjanssen>ivanm: that's what you'd do
07:23:03<ivanm>*nod*
07:23:04<copumpkin>as it seems like a more appropriate place to try it, but I'll play with TH in the mean time
07:23:14<glguy>ivanm, you should newtype your custom measure, rather than adding a weird instance to a standard type
07:23:28<ivanm>sjanssen: so "measure" is the overall mappend'd value?
07:23:28<sjanssen>ivanm: you *must* do that unless you want O(n) lookup
07:23:35<mmorrow>copumpkin: so in there, i tried to show (1) pprinting *abstract* syn, (2) pprinting *real* syn, and (3) splicing of ExpQ's into [|.... $(..here..) ...|]
07:23:38<ivanm>glguy: yes, I realise this ;-)
07:23:40<mmorrow>copumpkin: (3) is key
07:23:50<sjanssen>ivanm: 'measure x' is the summarized value of x
07:23:59<mmorrow>copumpkin: that's what took me the longest to figure out with TH
07:24:05<sjanssen>ivanm: in the case of FingerTree, that is mconcat (allthevalues)
07:24:17<ivanm>sjanssen: *nod*
07:24:25<guenni>ivanm: using Maybe or Either how?
07:24:26<copumpkin>mmorrow: so your meanFT is explicitly keeping the folds around as pairs?
07:24:35<ivanm>guenni: depends on what you mean by "read error"
07:24:55<guenni>ivanm: read "a" :: Int
07:25:02<ivanm>oh
07:25:08<mmorrow>copumpkin: ah, yeah so the "FuseTemplate" takes a combiner function, and a list of pairs of (iteratee, initial val)
07:25:10<glguy>guenni, to catch errors in "read", you'll either use "readIO" or "reads"
07:25:15<ivanm>@type reads
07:25:16<copumpkin>mmorrow: I see
07:25:16<lambdabot>forall a. (Read a) => String -> [(a, String)]
07:25:39<ivanm>> reads "2a" :: [(Int,String)]
07:25:40<lambdabot> [(2,"a")]
07:25:50<ivanm>isn't there a Maybe version of reads?
07:25:50<mmorrow>copumpkin: and then "fuseIt" just does the strategy of tupling stuff up, and then using the combiner at the end
07:26:17<glguy>ivanm, not in the Prelude
07:26:17<copumpkin>mmorrow: so what I'd need on top of that is something that takes haskell, pulls out the folds from it, builds that structure, keeps track of the combinations, and outputs the final fold?
07:26:44<glguy>read isn't really useful for anything bigger than an example program
07:26:50<glguy>and in those you can assume good input
07:27:06<mmorrow>copumpkin: hmm, yeah that could be interesting. i was thinking of the "user" supplying the FoldTemplate, but that would be even nicer
07:27:20<mmorrow>(sounds possibly a lot of work though)
07:27:22<copumpkin>mmorrow: that's what I was talking about when I said I was afraid of the complexity
07:27:23<copumpkin>yeah :P
07:27:30<copumpkin>because the folds may not be directly visible
07:27:37<copumpkin>they may be hidden in a where/let
07:28:13<mmorrow>yeah, taking arbitrary haskell code and extracting fusible fold automagically would be epic
07:28:21<copumpkin>yeah :P
07:28:31<mmorrow>(but awesome)
07:28:39<copumpkin>that's why it feels more appropriate to be doing this at an early stage of the simplifier, using the ghc plugins arch
07:28:55<copumpkin>there are fewer cases to be catching
07:29:05<mmorrow>that's be cool
07:29:11<mmorrow>*that'd
07:29:14<copumpkin>but the ghc plugins thing isn't ready yet :P
07:29:21<copumpkin>and this looks like fun so I'll play with it instead
07:29:33<mmorrow>copumpkin: lemme know how it goes
07:29:42<copumpkin>but I look forward to being able to supply plugins for specific optimizations
07:29:47<copumpkin>sure thing!
07:29:56<mmorrow>copumpkin: oh oops, this comment should've been deleted "- if TypeQ is @a@, then ExpQ :: (a -> a -> a)"
07:30:15<mmorrow>(it's talking about something that doesn't exist anymore)
07:31:38<copumpkin>ah :) ok
07:31:39<ivanm>@seen matthew-_
07:31:39<lambdabot>matthew-_ is in #haskell-blah, #ghc and #haskell. I last heard matthew-_ speak 18h 45m 15s ago.
07:31:58<ivanm>@ask matthew-_ did you send out the emails about my taking over graphviz?
07:31:58<lambdabot>Consider it noted.
07:36:06<Berengal>ACTION is having fun with applicative parsers
07:36:35<voker57__>doesn't map work with IO functions? what's the alternative?
07:36:45<voker57__>like 'map (print) [1,2,3]
07:36:55<Berengal>voker57__: Use fmap
07:37:03<Berengal>Wait
07:37:08<Berengal>Use mapM
07:37:17<Berengal>You could use map though...
07:37:24<Berengal>@type map print [1,2,3]
07:37:25<lambdabot>[IO ()]
07:37:34<Berengal>But it's probably not what you wanted
07:37:42<dolio>For that, you actually want mapM_.
07:37:42<Berengal>@type mapM_ print [1,2,3]
07:37:43<lambdabot>IO ()
07:38:09<Berengal>@type mapM readFile ["fileA", "fileB", "fileC"]
07:38:10<lambdabot>IO [String]
07:39:24<Cale>voker57__: See, map print [1,2,3] gives you a list of actions, whereas you probably want to actually *run* those actions in turn.
07:39:42<Cale>(which is what mapM/mapM_ are for)
07:40:45<voker57__>ok, understood
07:40:50<Berengal>Or you could use sequence...
07:40:52<Berengal>@type sequence
07:40:53<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m [a]
07:40:55<Berengal>@type sequence_
07:40:56<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m ()
07:41:06<Berengal>That's what mapM uses internally anyway
07:41:10<voker57__>i needed to run actions and get values
07:41:39<Berengal>Is the action always the same, just with different parameters?
07:42:12<voker57__>yes
07:42:21<Berengal>That's what mapM is for them
07:42:24<Berengal>then*
07:42:26<Berengal>@type mapM
07:42:27<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m [b]
07:42:28<voker57__>so it works :)
07:42:56<Berengal>Yeah, it takes a function to a monad and a list of values and gives you a monad of a list of values
08:16:13<Berengal>Yay, primitive interpreter now complete!
08:16:56<cothoughtpolice>for what?
08:17:17<Berengal>A very simple non-turing-complete language
08:17:34<Hunner>hq9+ ?
08:17:46<Berengal>Not quite that simple
08:18:44<Berengal>One of the first things I did in haskell was to write an interpreter for this language for an assignment. I decided to try writing a new one now to see how much I had improved
08:18:46<ivanm>Berengal: how non-turing-complete?
08:18:54<ivanm>and have you improved? :p
08:19:23<ivanm>(though I fail to see how increased knowledge/familiarity with a programming language can indicate whether you as a person have improved...)
08:19:24<Berengal>let (Right e) = parse expr "" "funlet F(x) = x in F(let y=3 in y)" in evalExpr e -- Just 3
08:19:28<ivanm>;-)
08:19:38<Berengal>The above shows all it's features
08:19:42<Berengal>And yes, I have improved
08:19:58<Berengal>This one's about a third in size
08:20:09<Berengal>And I could probably reduce it even further, but I was curious about existentials...
08:20:28<Berengal>Instead of pattern matching on lists, I now use parsec for parsing
08:21:11<Berengal>And I use a ReaderT Environment Maybe Int to evaluate the thing...
08:23:13<Axman6>> fun "I'm a variable!" (var "i'm a function!)"
08:23:14<lambdabot> <no location info>: parse error on input `;'
08:23:20<Axman6>> fun "I'm a variable!" (var "i'm a function!")
08:23:21<lambdabot> Ambiguous occurrence `var'
08:23:21<lambdabot> It could refer to either `Data.Number.S...
08:23:34<Axman6>bah
08:29:20<DrSyzygyFR>What's a good way to conditionally import ModuleA or ModuleB dependent on a compilation flag?
08:29:27<DrSyzygyFR>I have the whole Cabal scaffolding in place...
08:29:46<ivanm>DrSyzygyFR: use cpp
08:30:19<DrSyzygyFR>Aight.
08:30:31<DrSyzygyFR>And just #ifdef FLAG and stuff
08:48:33<necroforest>What's wrong with this?
08:48:37<necroforest>main = do
08:48:37<necroforest> args <- getArgs
08:48:37<necroforest> firstOne <- read (head args)::Integer
08:48:53<necroforest>I get " Couldn't match expected type `IO t' against inferred type `Integer'"
08:50:32<C-Keen>:t read
08:50:33<lambdabot>forall a. (Read a) => String -> a
08:50:55<mlesniak>Does a function [[x1,y1,...], [x2,y2,...], ...] -> [[x1,x2,...], [y1,y2,...], ...] exist? I have the vague feeling that I overlook some obvious functional pattern here...
08:51:07<copumpkin>:t transpose
08:51:08<lambdabot>forall a. [[a]] -> [[a]]
08:51:13<copumpkin>:)
08:51:15<mlesniak>:D
08:51:42<mlesniak>Sometimes it's so obvious it hurts mentally ;-)
08:51:43<glguy>necroforest, read (head args) doesn't have a type of (IO _) which is required to use it with the <- syntax
08:51:51<glguy>try: let firstOne = read (head args)
08:51:55<necroforest>ah ok
08:51:59<glguy>when you want to simply label a value
08:54:10<DrSyzygyFR>Another basic question.
08:54:19<DrSyzygyFR>I've broken up my program into 3-4 different modules.
08:54:31<DrSyzygyFR>Now I want the single line import OperadGB to automatically also provide all the submodules.
08:54:35<DrSyzygyFR>How do I do that?
08:54:54<glguy>You can add modules to a modules export list
08:55:08<glguy>so you'd have a OperadGB module that reexports all of the others
08:55:19<swiert>da
08:55:34<copumpkin>mn
08:55:40<DrSyzygyFR>Ooooh.
08:55:53<swiert>sorry. Some window stole my focus.
08:55:59<copumpkin>:)
08:56:27<glguy>DrSyzygyFR, this is what Control.Concurrent does, for example: http://hackage.haskell.org/packages/archive/base/4.1.0.0/doc/html/src/Control-Concurrent.html
08:57:23<DrSyzygyFR>So if I want to export everything from OperadGB too, but write an export list, can I just include OperadGB in its own list?
08:57:54<swiert>Is there a way to let cabal configurations fail gracefully? Like if (test) then doSomething else fail.
08:58:19<dcoutts>swiert: sort of, you can use buildable: False
08:58:19<lambdabot>dcoutts: You have 1 new message. '/msg lambdabot @messages' to read it.
08:58:30<swiert>dcoutts: Great - thanks.
08:58:41<dcoutts>swiert: but the error messages are not better, they're worse
08:58:45<koeien_>DrSyzygyFR: no, 'module OperadGB'
08:59:42<dcoutts>swiert: you might like to add yourself to the cc list of this ticket: http://hackage.haskell.org/trac/hackage/ticket/231
09:00:35<swiert>dcoutts: It's not a big deal: the AppleScript package should only build on MacOS.
09:00:54<swiert>It the build has a error in the Hackage build log.
09:01:10<swiert>But it's a fairly simple check.
09:02:31<DrSyzygyFR>koeien_: But if I write module OperadGB (SubModule1, SubModule2) where ...
09:02:39<DrSyzygyFR>will I actually get anything from OperadGB out of it??
09:04:23<koeien_>DrSyzygyFR: no, you will need to add any functions of the module OperadGB itself as well
09:05:08<DrSyzygyFR>koeien_: Oh _joy_. :-/
09:05:45<J-roen>Loading package Cabal-1.6.0.3 ... linking ... done.
09:05:46<J-roen>*** Exception: 'parseField' called on a non-field. Consider this a bug.
09:05:49<koeien_>DrSyzygyFR: you could avoid it by creating a separate file and importing that besides SubModule{1,2}
09:05:50<J-roen>Should I indeed consider it a bug?
09:06:57<koeien_>DrSyzygyFR: although i consider explicit export lists a Good Thing[tm] while annoying while developing
09:07:30<J-roen>Forgot to mention: I get this when I call readHookedBuildInfo.
09:08:20<DrSyzygyFR>Hahaha!
09:08:43<DrSyzygyFR>koeien_: Didn't read your answer until I had already gone and created the wrapper.
09:08:58<DrSyzygyFR>I agree, in principle, that explicit export lists are a good thing, and in the end certainly SHOULD be used here.
09:09:12<DrSyzygyFR>However, I'm still enough in flux with development that I don't need one more hazzle.
09:09:48<koeien_>DrSyzygyFR: but you need 'module Submodule1' instead of just 'Submodule1'
09:09:54<koeien_>(in the export list)
09:16:50<matthew-_>@tell ivanm no, not yet
09:16:51<lambdabot>Consider it noted.
09:21:02<SubStack>category theory is JUST A THEORY
09:21:14<sjanssen>oh jeez
09:21:30<SubStack>that is all
09:21:36<DrSyzygyFR>As is all mathematics. So what?
09:21:49<DrSyzygyFR>The "just" in "just a theory" very seldom is so just...
09:22:09<sjanssen>DrSyzygyFR: sounds like creationist rhetoric
09:22:37<DrSyzygyFR>What I said, or what SubStack said?
09:22:37<SubStack>ACTION is coming up with secondary titles, many of which involve haskell in some fashion
09:22:38<Berengal>categoryTheory = Just Theory
09:22:43<Berengal>Could be Nothing
09:22:43<SubStack>heh
09:22:54<SubStack>Berengal++ for the excellent punning?
09:23:08<ray>category theory is a theory, not a fact, regarding collections of objects and morphisms between them
09:23:28<ray>it should be approached with an open mind, studied carefully, and critically considered
09:26:30<quicksilver>ACTION peers around doubtfully.
09:27:03<quicksilver>Berengal: if we know it's Just Theory, then we know it isn't Nothing ;)
09:27:17<SubStack>Maybe
09:27:37<bremner>ACTION supports teaching of all of the alternative theories about categories in elementary school
09:27:57<bremner>then some 8 year old can explain it to me
09:28:08<Berengal>quicksilver: Could have been Nothing then ;)
09:28:37<Berengal>My parser overflows the stack when parsing "3 + 5" :(
09:29:20<SubStack>bremner: like the ones under which things are related because some intelligent actor willed it to be so?
09:32:26<bremner>SubStack: well, if that is what the "scientific" community comes up with.
09:35:37<xrfang>I would like to write a flatten function which does: [[1,2], [3, 4]] -> [1, 2, 3, 4]
09:35:44<xrfang>I wrote:
09:35:48<ray>look at the elegant way functors map every object and morphism in a category perfectly to another one
09:35:51<xrfang>flatten [] = []
09:35:52<ray>how can you not see a designer
09:35:53<xrfang>flatten (x:xs)
09:35:53<ivanm>matthew-_: well, hurry up and do so! :p
09:35:54<lambdabot>ivanm: You have 1 new message. '/msg lambdabot @messages' to read it.
09:35:54<xrfang> |[x] = (flatten x) : (flatten xs)
09:35:56<xrfang> |otherwise = x : (flatten xs)
09:36:02<xrfang>but [x] does not work in guard :(
09:36:39<ray>i think there might be a library function for that
09:36:49<Ferdirand>:t concat
09:36:50<ray>@hoogle [[a]] -> [a]
09:36:50<lambdabot>Prelude concat :: [[a]] -> [a]
09:36:51<lambdabot>Data.List concat :: [[a]] -> [a]
09:36:51<lambdabot>Data.List intercalate :: [a] -> [[a]] -> [a]
09:36:51<lambdabot>forall a. [[a]] -> [a]
09:36:59<xrfang>ray: I am practicing and won't use lib functions :)
09:37:13<sjanssen>xrfang: what is this function supposed to do?
09:37:17<xrfang>also I want to flatten any level of nested list to one level
09:37:23<xrfang>no matter how many level is nested
09:37:24<C-Keen>@hoogle [a] -> Bool
09:37:25<lambdabot>Prelude null :: [a] -> Bool
09:37:25<lambdabot>Data.List null :: [a] -> Bool
09:37:25<lambdabot>Prelude all :: (a -> Bool) -> [a] -> Bool
09:37:31<sjanssen>xrfang: ah, this is actually rather difficult in Haskell
09:37:33<Ferdirand>you cannot have arbitrary nesting
09:37:58<Ferdirand>well, at least not heterogeneous nesting levels
09:37:59<xrfang>I just want the Haskell version of Ruby's Array#flatten
09:38:07<xrfang>Ruby's list is not tat strict
09:38:22<xrfang>ok, for the code I wrote, what if I want to test if x is a list or not?
09:38:29<QtPlaty[HireMe]> concat
09:38:31<sjanssen>xrfang: you can't do that in Haskell
09:38:35<Ferdirand>but you do not test for it
09:38:35<koeien_>Haskell is statically typed, you cannot do that
09:38:40<Berengal>xrfang: There's no need to test that. You know at compile time
09:38:42<Ferdirand>the type is known at compile time
09:38:58<C-Keen>xrfang: in your example you have explicitly a list of lists. and your functions signature is [[a]] -> [a] which is the same as [a] -> a
09:39:00<bremner>ACTION watches the clash of mental models with interest
09:39:18<xrfang>hm...
09:39:19<QtPlaty[HireMe]>:t concat
09:39:20<lambdabot>forall a. [[a]] -> [a]
09:39:21<quicksilver>multi-level flatten isn't difficult, given a model of multi-level list.
09:39:31<Ferdirand>you could have a custom data type that is either an item, or a sublist (a n-tree basically). then you can match on the constructors.
09:39:32<quicksilver>once you design the type, the function writes itself.
09:39:33<xrfang>no dynamics of any?
09:39:34<koeien_>you need some advanced type hackery for it
09:39:35<matthew-_>ivanm: ok, at work right now, will deal with it tonight
09:39:35<lambdabot>matthew-_: You have 1 new message. '/msg lambdabot @messages' to read it.
09:39:46<ivanm>matthew-_: good-o
09:40:27<Jedai>xrfang: You don't need it, since the list are homogenous and you know their type at compile time
09:40:40<xrfang>say I pass x to a function, this function handles Maybe a,
09:40:57<DrSyzygyFR>Ehm.... WHERE in my Cabal-file do I put extension: CPP ??
09:40:58<xrfang>in the function I want to test if x is Nothing or Just a, I need to write a case
09:41:08<BONUS>maybe you can do a multi level list ith Data.Dynamic
09:41:23<xrfang>anyway, what I am thinking is "to test or find out the data type of x".
09:41:34<Jedai>BONUS: You can use HList if you want an heterogenous list
09:41:45<BONUS>yeah or that even better
09:41:48<Ferdirand>xrfang: but you already did. You have an implicit case matching either [] or (x:xy)
09:42:00<sjanssen>xrfang: right, Haskell doesn't have anything like that. We can't ask for the type, but the type is statically known by the compiler
09:42:05<Jedai>xrfang: You can use typeOf but you don't need to (very probably)
09:42:24<bremner>@hoogle HList
09:42:24<lambdabot>package HList
09:42:43<Berengal>Matching types is nonsensical. Matching constructors on the other hand makes perfect sense, but it's not the same
09:42:46<BONUS>every type is known at compile time, so there's no need to see if some value is of some type
09:42:56<sjanssen>let's stay away from Typeable, Dynamic and HList for now, xrfang is asking more basic questions
09:42:59<Jedai>sjanssen: Except for Typeable instances (I agree that xrfang don't need that here but it's good to know that it exists)
09:43:03<xrfang>ok, as my question comes out of an imaginery exercise I hope that won't happen in Real world programming tasks...
09:43:17<BONUS>what is the exercise
09:43:21<sjanssen>(also, HList, for a newbie? Srlsly guyz)
09:43:25<Jedai>xrfang: What was the imaginary exercise)
09:43:50<BONUS>i hope it's not "find out the type of some value at run-time" hehe
09:43:54<ivanm>sjanssen: is there some magic way of knowing which index something is at in a FingerTree?
09:44:02<sjanssen>ivanm: no
09:44:11<ivanm>or is it more for using like a Map replacement?
09:44:12<xrfang>sjanseen: yes, I only want the basics to fully understand type and typeclass. I learned erlang before, and feel lambda, high order functions etc quite understandable, but type/typeclass is hard to understand
09:44:15<sjanssen>ivanm: you can, of course, provide a Monoid that facilitates that
09:44:15<Jedai>xrfang: I'm pretty sure that either it's a situation that don't arise in real Haskell program or you can find a solution without type matching
09:44:17<ivanm>s/Map/Array/
09:44:20<ivanm>sjanssen: *nod*
09:44:31<ivanm>not that big a deal... I'll just split, alter, join
09:44:55<xrfang>Jedal, that's what I conclude from here. thanks
09:45:12<xrfang>but
09:45:23<xrfang>still some newbie comments...
09:45:31<sjanssen>sure, go ahead
09:45:36<xrfang>Delphi (pascal) is statically typed
09:45:41<BONUS>what did you say the exercise was again?
09:45:49<xrfang>I often do type checking in delphi, also in java...
09:45:53<QtPlaty[HireMe]>data MLlist x = Mlist [Either x (MLlist x)]
09:46:06<xrfang>BONUS, the execise is simple, just to implement Ruby's flatten in haskell
09:46:18<ivanm>xrfang: Haskell's type (pun! :p ) of static typing is different from Pascal's or Java's
09:46:35<ivanm>hmmm... is there any non-functional lang that has a typing system similar to Haskell's?
09:46:35<sjanssen>xrfang: you mean the "instanceof" keyword in Java?
09:46:46<xrfang>sjanssen: exactly!
09:46:49<Jedai>xrfang: Haskell type system is much more expressive than Java's or Delphi's
09:46:51<xrfang>isn't that type checking?
09:47:03<BONUS>oh that. i'd suggest picking a different one though, since this one isn't really idiomatic :) like asking how you would do air conditioning in space
09:47:09<BONUS>there's no air in space, etc.
09:47:16<xrfang>Jedal: any newbie-understandable example of what do you mean by "expressive"?
09:47:18<sjanssen>xrfang: well, "type checking" as a phrase has a specific meaning in the jargon, so let's not call it that
09:47:22<xrfang>vs. java etc.
09:47:23<Berengal>In Haskell there's no need for instanceof since there's no subtyping
09:47:31<ivanm>BONUS: sure there is
09:47:34<ivanm>it's just very, very diffuse
09:47:42<sjanssen>xrfang: what it really is is type introspection of a sort
09:47:49<xrfang>ok, no subtyping, but here we have "typeclass" which is "super-typing"?
09:47:50<BONUS>hmm i've never been there yeah so i wouldn't really know
09:47:50<Jedai>xrfang: typechecking is a technical term that doesn't mean what you're speaking about, so use type matching or something like that
09:48:09<ivanm>xrfang: "type-checking" in Haskell means "hmmm... what type does this function have? I'll use :t in ghci to work it out!"
09:48:11<Adamant>ivanm: Ada has probably the strongest type system for imperative languages
09:48:15<BONUS>xrfang: typeclasses are nothing like the classes in java
09:48:17<ivanm>Adamant: *nod*
09:48:32<xrfang>ok, Jedal, so, we don't call it type checking, but type matching...
09:48:34<Adamant>SPARK extends it further, I think
09:48:44<Berengal>Well, typeclasses are somewhat like interfaces, except you always know what class they're off
09:48:50<xrfang>does that make sense if my haskell "flatten" to try "type matching"?
09:48:54<Berengal>(Unless you delve into existentials, but that way be dragons)
09:49:04<DrSyzygyFR>Is haskell.org unhappy? I'm getting insane load times. :-/
09:49:12<quicksilver>xrfang: what makes sense is to first consider the type the function has.
09:49:12<bremner>DrSyzygyFR: same here
09:49:20<xrfang>i.e. if flatten is defined as: flatten :: [[a]] -> a
09:49:22<quicksilver>xrfang: and to note that all haskell functions have a type.
09:49:26<xrfang>then we DO NOT need type matching
09:49:36<quicksilver>xrfang: [[a]] -> [a] makes sense - that's a one-level flatten.
09:49:43<xrfang>but without the signature,
09:49:44<Jedai>xrfang: Your flatten could probably be expressed with overlapping instances
09:49:58<xrfang>e.g. imagine flatten takes literally any parameter
09:49:59<quicksilver>xrfang: if you were to design "MultiLevelList a" then "MultiLevelList a -> [a]" would probably also make sense
09:50:07<xrfang>flatten [[a]] -> a
09:50:11<quicksilver>xrfang: (and be pretty easy to to write once you'd defined the type)
09:50:13<xrfang>flatten any -> any
09:50:29<quicksilver>typically we call 'MultiLevelList', 'Tree', though.
09:51:02<BONUS>haskell is statically typed, you can't have any -> any
09:51:07<BONUS>that would defeat the whole purpose
09:51:14<ivanm>ACTION wished it was possible for modules that have a lot of overlap with the prelude to have two import lists... custom symbols, operators, etc. and everything
09:51:14<xrfang>ok, say, a function is sort of "polymorphic"...
09:51:22<Berengal>@type id
09:51:23<lambdabot>forall a. a -> a
09:51:25<Berengal>@type unsafeCoerce
09:51:26<lambdabot>Not in scope: `unsafeCoerce'
09:51:29<BONUS>i'd say let go of this problem (for now) and move on to more productive things instead of trying to write ruby in haskell
09:51:30<Berengal>Hmm...
09:51:31<xrfang>func [a] = "a list a"
09:51:42<xrfang>func (a) = "a tuple a"
09:51:44<xrfang>blah blah
09:51:54<xrfang>now func takes many types right?
09:51:54<ivanm>BONUS: well, you started it by porting a ruby-style tutorial to haskell :p
09:52:01<BONUS>haha :D
09:52:05<ivanm>s/ruby-style tutorial/ruby's tutorial style/
09:52:06<quicksilver>xrfang: No. YOu can't do that.
09:52:13<quicksilver>xrfang: functions have a single type.
09:52:17<xrfang>oops.
09:52:23<BONUS>oh god what have i done :]
09:52:32<ivanm>the closest thing to having arbitrary number of arguments of different types is by having optional arguments in a record
09:52:34<quicksilver>xrfang: that's a very important lesson.
09:52:44<ivanm>which IIRC, ndm made "popular"
09:52:46<xrfang>indeed
09:53:02<Berengal>ivanm: Well, typeclasses sort of provide the type as an argument
09:53:20<quicksilver>ivanm: In systems which need that, I prefer the combinator approch which most of the GUI librarys have taken.
09:53:21<xrfang>I hope to finish LYAH within 2 days. I think after Typeclass 102, I will know more ... :) thanks all
09:53:23<ErhardtMundt>jour
09:53:24<ivanm>Berengal: hmmm...
09:53:31<ivanm>quicksilver: oh? like what?
09:53:36<quicksilver>openNewWindow [ size := (400,400), colour := red]
09:53:39<quicksilver>that kind of thing.
09:53:44<ivanm>*shudder*
09:53:51<quicksilver>why shudder?
09:53:57<quicksilver>it's strongly typed + expressive.
09:54:16<ivanm>I thought augustss putting C and Basic into Haskell was bad enough, without introducing Pascal into it ;-)
09:54:26<ivanm>quicksilver: how does that type-check? through the magic of the := operator?
09:54:29<ivanm>@type (:=)
09:54:30<lambdabot>forall a b. a -> b -> Assoc a b
09:54:40<quicksilver>it's not magic.
09:54:41<ivanm>@src Assoc
09:54:41<quicksilver>But yes.
09:54:42<lambdabot>Source not found. I've seen penguins that can type better than that.
09:54:43<xrfang>@src Complex
09:54:44<lambdabot>data (RealFloat a) => Complex a = !a :+ !a
09:54:46<ivanm>what's Assoc?
09:54:51<quicksilver>I just made up (:=)
09:54:55<quicksilver>the name doesn't matter.
09:54:56<ivanm>quicksilver: heh
09:54:57<quicksilver>it's the idea.
09:54:59<sjanssen>ivanm: it type checks via overloading on the property names, 'size' and 'colour' will be classes
09:55:03<ivanm>well, lambdabot knew what you were talking about :p
09:55:09<ivanm>sjanssen: *nod*
09:55:23<QtPlaty[HireMe]>:infor (:=)
09:55:31<quicksilver>you might have size :: Property (Int,Int)
09:55:33<ivanm>but what voodoo type magic is required to have it not complain about different types in a list, even if they're in the same typeclass?
09:55:34<QtPlaty[HireMe]>:info (:=)
09:55:51<quicksilver>and then have (:=) :: Property a -> a -> Assignment
09:55:52<ivanm>QtPlaty[HireMe]: I don't think lambdabot knows that ghci option :(
09:55:53<quicksilver>or something like that.
09:56:00<ivanm>@hoogle Assoc
09:56:00<lambdabot>Control.Parallel.Strategies data Assoc a b
09:56:00<lambdabot>Text.Parsec.Expr data Assoc
09:56:00<lambdabot>Text.ParserCombinators.Parsec.Expr data Assoc
09:56:05<ivanm>ahhhh
09:56:07<quicksilver>and then openNewWindow :: [Assignment] -> IO ().
09:56:09<quicksilver>it's not magic.
09:56:12<ivanm>actually, which one?
09:56:13<quicksilver>it's just a type system :P
09:56:21<sjanssen>ivanm: not very much magic at all
09:56:30<quicksilver>it doesn't even need type classes.
09:56:35<ivanm>ahhh
09:56:39<quicksilver>although it probably needs an existential.
09:56:48<quicksilver>and you might *choose* type classes to extend it in clever ways.
09:56:50<sjanssen>using := for several different properties is the biggest hurdle
09:57:07<xrfang>how do I know all available lambdabot tricks e.g. hoogle??
09:57:14<ivanm>@list
09:57:14<lambdabot>http://code.haskell.org/lambdabot/COMMANDS
09:57:17<ivanm>^^ xrfang
09:58:01<xrfang>@list
09:58:02<lambdabot>http://code.haskell.org/lambdabot/COMMANDS
09:58:06<xrfang>thanks ;)
09:58:10<xrfang>^^ xrfang?
09:58:27<Berengal>
09:58:39<Jedai>xrfang: That's just IRC jargon for look at what I just said
09:58:44<ivanm>Berengal: show off ;-)
09:58:48<Berengal>3↑↑↑3 = ???
09:58:49<DrSyzygyFR>I'm getting compilation errors when trying to write quickcheck properties.
09:59:05<ivanm>Berengal: isn't that 3^(3^(3^3))) or something?
09:59:22<xrfang>Berngal, thanks
09:59:32<DrSyzygyFR>I'm following the model in the quickcheck manual, where you write something like prop foo = bar x y z where _ = x :: Type1; ...
09:59:38<Berengal>ivanm: I think it's 3^(3^(3^3)) ↑ 3 actually
09:59:40<sjanssen>quicksilver: that style would be very convenient if we had OCamls variants
09:59:45<DrSyzygyFR>And I keep getting parse errors.
09:59:55<ivanm>isn't ↑ == ^ ?
10:00:06<ivanm>sjanssen: oh? what are they?
10:00:19<DrSyzygyFR>Anyone able to point me towards a better way to do it?
10:00:27<sjanssen>ivanm: extensible sum types
10:00:40<Berengal>ivanm: 3↑3 is 3^3, 3↑↑3 is 3^(3^(3^3))
10:01:05<Hunner>ACTION uses ^^ as eyes.
10:01:17<ivanm>Berengal: oh, that's right, ↑n means to the power of n n times
10:01:26<Berengal>^_O ← monocle
10:01:30<quicksilver>sjanssen: you mean extensible variants? they're a can of worms arne't they?
10:01:42<Berengal>ivanm: I can't really remember. It's been a while since I've used them
10:01:49<Jedai>DrSyzygyFR: If you're getting parse errors, there's a syntax problem, which means you really have to pate your code if you want help
10:01:53<Berengal>And I never used them for anything real...
10:01:55<sjanssen>quicksilver: they probably are, but they'd certainly be handy at times
10:02:41<sjanssen>quicksilver: have you looked at an implementation for any of the property systems? I wonder if there is a trick to avoid all this boilerplate
10:03:10<quicksilver>sjanssen: well I wrote something simplistic along these lines for openGL
10:03:31<quicksilver>sjanssen: but it's only a single use case, it doesn't need to restrict properties for different calls
10:03:38<DrSyzygyFR>Jedai: I found the issue.
10:03:52<DrSyzygyFR>I had an unfinished start of an attempt to write an Arbitrary instance. And that was what screwed it all up.
10:04:16<sjanssen>quicksilver: ie. it sidesteps the tricky part :)
10:04:44<DrSyzygyFR>However....
10:04:44<DrSyzygyFR>-- All shuffles are shuffles
10:04:44<DrSyzygyFR>prop_shufflesareshuffles = all isShuffle (allShuffles i j)
10:04:44<DrSyzygyFR> where _ = i :: Int
10:04:44<DrSyzygyFR> _ = j :: Int
10:04:52<quicksilver>sjanssen: yes. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4242
10:05:02<DrSyzygyFR>Why do I get "Not in scope: i" and "Not in scope j" on this??
10:05:50<dolio>Because there's no i and j declared anywhere in it or elsewhere in the file?
10:05:54<ivanm>DrSyzygyFR: without even looking at it, because you're using variables that don't exist
10:06:23<DrSyzygyFR>In that case, what makes it different from this:
10:06:23<DrSyzygyFR>prop_RevRev xs = reverse (reverse xs) == xs where _ = xs :: [Int]
10:06:24<ivanm>"where _ = i" ?
10:06:26<DrSyzygyFR>??
10:06:37<ivanm>DrSyzygyFR: I don't even think that's legitimate
10:06:42<DrSyzygyFR>ivanm: Adapted straight out of the QuickCheck documentation.
10:06:42<ivanm>saying "where foo _ = xs" is
10:06:50<ivanm>saying "where _ = xs" isn't AFAIK
10:06:59<ivanm>DrSyzygyFR: and that example defines what xs is
10:07:05<ivanm>yours doesn't define i and j
10:07:05<DrSyzygyFR>Ahhhhhh
10:07:10<DrSyzygyFR>Now I get it!
10:07:22<Berengal>ivanm: It's allowed
10:07:23<ivanm>> (_ = 1)
10:07:24<lambdabot> <no location info>: parse error on input `='
10:07:28<ivanm>Berengal: it is? wtf does it do?
10:07:35<ivanm>> (_ = 1) 2
10:07:36<lambdabot> <no location info>: parse error on input `='
10:07:38<Berengal>ivanm: In this case: define the type
10:07:39<sjanssen>quicksilver: ah, I hadn't even thought about inheritance yet
10:07:50<Berengal>Otherwise it's useless I guess...
10:07:51<ivanm>Berengal: of what? xs?
10:08:02<ivanm>everything is xs? :s
10:08:03<sjanssen>quicksilver: I suppose one could just cheat and append the properties to a list, and make the implementation take the last
10:08:14<Berengal>ivanm: Looking at his function it says "where _ = i :: Int"
10:08:31<ivanm>yes
10:08:41<ivanm>so how does that get read/parsed? everything equals i? :s
10:09:04<Berengal>Well... there's a variable, which name we don't care about, that equals i, and i is of type Int
10:09:40<Berengal>@type foo bar = bar where _ = bar :: Int
10:09:41<lambdabot>parse error on input `='
10:10:12<Berengal>@type let foo bar = let _ = bar :: Int in bar in foo
10:10:14<lambdabot>Int -> Int
10:10:20<ivanm>Berengal: that's the thing, to me it looks like "I don't know what this is, I'll look through the where clause... oh, the _ matches what I'm looking up, it must be what I want!"
10:10:45<Berengal>ivanm: _ doesn't match any name
10:10:58<Berengal>Can't look up something you don't know the name of...
10:12:17<Berengal>It's an alternative to lhs type signatures I guess...
10:12:23<sjanssen>quicksilver: one thing this model doesn't really address are default arguments -- one can't access the defaults programmatically
10:16:35<ivanm>sjanssen: is there anything like mapAccumL for FingerTrees? or just write a fold using the Foldable instance?
10:16:41<ivanm>ACTION guesses the latter
10:17:11<ivanm>oh, and isn't mapAccumL actually a right fold? :s
10:17:11<sjanssen>ivanm: be aware that maps on FingerTrees are going to be a bit more expensive than lists
10:17:22<sjanssen>the cached measurements have to be recalculated
10:17:32<ivanm>sjanssen: yeah...
10:18:25<ivanm>I'm wondering whether I should go back and forth from lists (OK, I'm only going from list to FingerTree in the middle) and by "replacing" a value with a list "in-situ" just concat'ing the map...
10:18:36<ivanm>or try and do _everything_ with finger trees :s
10:18:42<dibblego>haskell.org is grindingly slow
10:18:51<ivanm>dibblego: it has been said already
10:18:56<ivanm>so no, you're not special :p
10:19:04<sjanssen>ivanm: I'd say only use FingerTree when you benefit from measurement or split
10:19:11<ivanm>*nod*
10:19:14<ivanm>OK, I'll do that then
10:20:10<DrSyzygyFR>Hmmm. With break-on-error but without running with :trace - what kind of information can I gather at all about the stack overflow I'm running into?
10:20:17<ivanm>oh, wait, damn, I can't use (second concat) . mapAccumL ... I _do_ have to use the new values when recursing :(
10:20:50<ivanm>and there doesn't seem to be a mapExpandAccumL function :p
10:29:20<dibblego>@hoogle FilePath -> IO Bool
10:29:21<lambdabot>System.Directory doesDirectoryExist :: FilePath -> IO Bool
10:29:21<lambdabot>System.Directory doesFileExist :: FilePath -> IO Bool
10:29:21<lambdabot>System.FilePath.Posix hasDrive :: FilePath -> Bool
10:29:26<dibblego>@hoogle FilePath -> IO ()
10:29:27<lambdabot>System.Directory createDirectory :: FilePath -> IO ()
10:29:27<lambdabot>System.Directory removeDirectory :: FilePath -> IO ()
10:29:27<lambdabot>System.Directory removeDirectoryRecursive :: FilePath -> IO ()
10:29:50<dibblego>how do I delete a file?
10:30:08<Berengal>@hoogle removeFile
10:30:09<lambdabot>System.Directory removeFile :: FilePath -> IO ()
10:30:32<dibblego>ta
10:45:09<eden>Hi folks, anyone experienced with parsec in today? I've used it myself, but have got kinda stuck...
10:45:35<byorgey>eden: what's the problem?
10:47:18<eden>I'm trying to write a java style unicode preprocessor before the parsing proper, but want errors to have to the column number as it was before preprocessing
10:48:13<byorgey>yikes, that sounds complicated =)
10:49:41<SamB>or at least fantastically inefficient
10:50:06<SamB>eden: what are you doing with ... tabs?
10:50:10<eden>it's why I'm stuck. Apparently haskell does this kind of preprocessing as well as java.
10:50:39<SamB>first I've heard of it!
10:51:53<eden>says so in the report under lexical structure. I'm going to use IndentParser, which handles the tabs.
10:52:12<SamB>oh, that
10:52:45<SamB>... what does that have to do with Unicode ?
10:54:45<eden>since I'm trying to make a preprocessor to convert \uXXXX into ordinary characters, it has nothing at all to do with tabs.
10:55:15<SamB>I just meant with regards to the column numbers
10:56:06<SamB>if you have "\t\\uDEAD\\uBEEF" as input, what column do you say that \uBEEF is in ?
10:56:41<SamB>another question is: how do you parse \\?
10:56:49<SamB>:t (\\)
10:56:50<lambdabot>forall a. (Eq a) => [a] -> [a] -> [a]
10:57:04<SamB>did you say you were doing this for Haskell?
10:57:23<SamB>or that you are parsing some other language
10:57:47<eden>No, I'm toying with some language ideas of my own.
10:58:07<SamB>okay, because it would be kind of awkward to have to type \\\\ to get that operator ;-P
10:58:45<SamB>(and plus it would be a real pain to tack your preprocessor onto an actual compiler ;-)
10:59:35<sior|oifig>@src foldr
10:59:35<lambdabot>foldr f z [] = z
10:59:35<lambdabot>foldr f z (x:xs) = f x (foldr f z xs)
11:00:00<pozic>Why doesn't :i Testlike work in a module where import Test.Framework is done?
11:00:18<SamB>pozic: is it spelled TestLike ?
11:00:28<pozic>SamB: not according to the documentation
11:00:38<SamB>pozic: okay, haven't used that
11:00:45<pozic>http://hackage.haskell.org/packages/archive/test-framework/0.2.1/doc/html/Test-Framework.html#t%3ATestlike
11:01:03<SamB>but I've run into problems where I use the wrong capitalization before, so I thought it was worth checking ;-)
11:01:44<pozic>It seems the class is not exported, although it is visible in the documentation.
11:01:54<SamB>now that's wierd!
11:02:06<eden>That's exactly why I'm stuck. I could try to parse (Int, Char) lists, but that would be horrible, both stylisticlly and effeincy
11:02:20<pozic>In ghci import Test.Framework :browse
11:02:53<SamB>eden: not TOO much worse than String itself
11:02:56<SamB>lets see ...
11:03:16<SamB>how many words does a (,) take, and how many does an Int take?
11:03:38<SamB>does (,) take 3 and Int take 2?
11:03:47<SamB>(in the nursery)
11:04:59<SamB>eden: maybe you should just include the handling at the low level of your lexer somehow
11:07:21<eden>This was my original idea, but it's hard to know how to correctly parse identifiers (for example) that contain \\uXXXX, which when converted are legitimate.
11:07:48<eden>I mean \uXXXX
11:08:06<SamB>eden: that's why I say at the low level
11:08:55<eden>okay, what sort of low level do you mean?
11:09:21<ivanm>the bit under the high level ;-)
11:09:57<SamB>well, you could write your own AlexInput, alexGetChar, and alexInputPrevChar
11:10:46<SamB>http://haskell.org/alex/doc/html/api.html
11:12:13<eden>right. I assume there's a way of hooking these into parsec. gives me something to look at anyway.
11:14:57<eden>might make indentation based stuff hard, but I suppose I could copy Python's idea of inserting INDENT, NEWLINE and DEDENT tokens into the stream.
11:16:24<SamB>eden: I'd not suggest using Parsec for anything this complicated, personally
11:22:47<eden>it's very possible that you've got the right idea.
11:24:12<trofi>@pl map (\((a,n), k) -> (a, n*k)) xs
11:24:13<lambdabot>map (uncurry (uncurry ((. (*)) . (.) . (,)))) xs
11:24:54<SamB>Parsec needs a ton of hand-holding if you use CharParsers, and a lot of it's functions only work for CharParsers :-(
11:26:14<SamB>but don't feel like "argh! I might as well have used any language as Haskell, if I don't get to use a combinator library but have to use a lexer-generator and parser-generator!"
11:26:57<SamB>because it's not true -- most of those require you to deal with a ton of messy state
11:27:30<SamB>whereas Alex and Happy let you deal in essentially as much or as little state as you like
11:28:33<SamB>hmm, interesting haskell.org favicon
11:29:12<SamB>ACTION wonders if the voting page(s) included favicon-sized renditions of the choices
11:29:22<mmorrow>unfortunately alex doesn't do unicode directly, but iirc there's a way around that
11:29:43<SamB>hmm.
11:29:58<mmorrow>i think it's referred to as a "hack" ;) :/
11:30:21<SamB>ACTION wonders if there are any PhD or masters theses in that
11:32:42<Berengal>Is there a way to make parsec parse not just streams of characters but streams of other types?
11:32:53<byorgey>Berengal: yup.
11:32:59<Berengal>How?
11:33:10<byorgey>the parser type is polymorphic in the type of elements of the stream.
11:33:39<Berengal>Are there any primitive polymorphic characters as well?
11:33:44<Berengal>parsers*
11:34:04<byorgey>Berengal: almost all of the primitives are polymorphic.
11:34:07<byorgey>except 'char' and 'string'.
11:34:32<Berengal>What's the analogous parser to those two then?
11:35:38<Berengal>ACTION currently has an ugly parser dealing with lots of whitespace and would like to tokenize
11:35:49<quicksilver>"token"
11:36:22<quicksilver>and friends.
11:36:42<Berengal>I'll have to look into it
11:36:47<Berengal>This made me very happy
11:38:01<quicksilver>I always tokenise
11:38:19<quicksilver>for anything except the most trivial cases
11:39:26<Berengal>Parsec really is awesome...
11:41:17<quicksilver>I don't like parsec.
11:41:36<ivanm>ACTION has never played that game
11:43:09<Berengal>It beats writing your own parser or bringing out the big guns found in other languages
11:43:32<ivanm>Berengal: Parsec-the-parser isn't a big gun?
11:43:43<quicksilver>Berengal: I prefer other parser combinator librarys.
11:43:49<quicksilver>Like one I might write myself in 10 minutes.
11:43:52<quicksilver>or polyparse.
11:43:53<QtPlaty[HireMe]>How does parsec parse?
11:44:10<DrSyzygyFR>Combinatorially. :-P
11:44:42<Berengal>I pretty much just imported parsec and wrote a parser for my (admittedly minimal) language in less than an hour
11:44:52<Berengal>Having very little experience with it before
11:44:56<Berengal>That makes it lightweight
11:45:05<QtPlaty[HireMe]>I mean bottem up or bottem down? Or is that just irrelevent
11:45:17<QtPlaty[HireMe]>?
11:46:04<Berengal>Top-down I'd say
11:47:25<Berengal>I, at least, just started with expr = try letExpr <|> try varExpr <|> try primOp ... and went from there
11:47:28<QtPlaty[HireMe]>Has there been any work at building a bottem up combernational parser.
11:49:36<wli>X-SAIGA
11:50:43<eden>
11:52:02<trofi>@src iterate
11:52:08<lambdabot>iterate f x = x : iterate f (f x)
11:57:35<wli>let iterate f x = let ys = x : map f ys in ys?
11:58:05<ivanm>wli: need an extra "in" there...
11:58:33<EvilTerran>"iterate f x = ys where ys = x : map f ys"
11:58:33<ivanm>but the definition given above is better
11:58:39<wli>I didn't mean to put the first one in in the first place.
11:58:42<ivanm>yours you manually apply f multiple times to each value
11:59:01<ivanm>whereas iterate just keeps applying it one extra time for the next value
11:59:20<eden>SamB: Having had a quick peruse of alex, I think it leaves me with much the same problem.
11:59:56<wli>ivanm: I'm not actually sure which one you said was better.
12:00:07<ivanm>wli: the one actually defined
12:00:47<ivanm>for the one you said, it comes down to being [x, f x, f (f x), f (f (f x)), ...] <-- how it is actually defined
12:01:04<ivanm>whereas by doing x : iterate f (f x), it "shares" previous defs
12:01:50<wli>i.e. the list is counterproductive?
12:02:20<ivanm>ummmm.... I wouldn't say that
12:02:21<dolio>ys = x : map f ys is something like O(n^2), where n is the number of elements you demand.
12:02:31<ivanm>and iterate is O(n)
12:03:11<ivanm>or maybe O(n log n)...
12:03:38<wli>I don't seem to get quadratic behavior.
12:04:26<dolio>Hmm, I may be wrong about that.
12:05:08<dolio>Now I'm conflicted.
12:05:35<uccus>in fact, I'm reading Bird & Wadler at the moment, and they seem to claim wli's version is better indeed due to sharing. I think the src version is better due to tail recursion. any thoughts?
12:05:49<ivanm>wli: for index i, you're applying f i times
12:06:08<ivanm>with iterate, index i only calls f one more time than (i-1)
12:06:34<dolio>It isn't calling f i times, though, actually.
12:06:53<jlaire>uccus: what tail recursion?
12:07:02<ivanm>dolio: wli's map version
12:07:18<dolio>Because the first time you get to an element, it gets memoized.
12:07:19<uccus>jlaire: tail rec modulo cons? :D
12:07:20<dolio>Right.
12:07:38<ivanm>dolio: ummm.... I thought Haskell didn't have memoization?
12:07:48<dolio>It does when values are shared.
12:07:58<ivanm>dolio: how are they shared here?
12:08:14<smtms>I thought nobody prevented any Haskell implementation from memoizing
12:09:02<quicksilver>nobody prevents it, but they don't need to prevent it
12:09:10<quicksilver>no implementation does anyway because it would be stupid.
12:09:22<quicksilver>however, all implementations share explicitly named values.
12:09:29<quicksilver>let x = f y in x + x
12:09:35<quicksilver>^^ x only calculated once, of course.
12:11:20<trofi>@src group
12:11:21<lambdabot>group = groupBy (==)
12:11:24<trofi>@src groupBy
12:11:24<lambdabot>groupBy _ [] = []
12:11:24<lambdabot>groupBy eq (x:xs) = (x:ys) : groupBy eq zs
12:11:24<lambdabot> where (ys,zs) = span (eq x) xs
12:11:35<trofi>> group [1,2,1,2]
12:11:37<lambdabot> [[1],[2],[1],[2]]
12:11:47<dolio>Well, there's an easy way to settle it...
12:12:11<trofi>> group $ sort [1,2,1,2]
12:12:12<lambdabot> [[1,1],[2,2]]
12:14:19<trofi>@hoogle ':: [(a,b)] -> [(a,[b])]'
12:14:20<lambdabot>Parse error:
12:14:20<lambdabot> --count=20 "':: [(a,b)] -> [(a,[b])]'"
12:14:20<lambdabot> ^
12:15:25<dolio>ivanm: Okay, so, it does have the same f-calling behavior as the library definition.
12:15:33<QtPlaty[HireMe]>@dijin [(a,b)] -> [(a,[b])]
12:15:34<lambdabot>Error: Undefined type []
12:15:55<QtPlaty[HireMe]>ACTION wonders why dijin doesn't know about lists.
12:16:09<dolio>ivanm: The reason is that each element of ys only has to be computed once.
12:16:53<kpreid>QtPlaty[HireMe]: recursion is hairy
12:17:01<ivanm>oh, duh...
12:17:33<dolio>ivanm: So when the outermost map f looks at the second element of ys (to generate the third element), it's already been computed, and so on.
12:17:56<dolio>It looks bad when you inline definitions, because that doesn't show sharing.
12:18:10<ivanm>*nod*
12:18:56<LeCamarade>Is that function called intersperse? The one that puts x between all members of l?
12:19:05<dolio>I was thinking that it did more cons construction/destruction, but I don't think it's O(n^2) there, either.
12:19:37<LeCamarade>Yes. Data.List.intersperse.
12:19:44<dolio>Probably only O(n) more work total, if that.
12:20:40<ivanm>dolio: eh, the actual definition looks cleaner to me anyway
12:22:04<eden>Ah well. I'll have to do a bit of harder thinking and some experimentation.
12:23:04<dolio>ivanm: Well, certainly, I don't have to think about it to verify that it shares things right. :)
12:23:57<dolio>And didn't have to use unsafePerformIO to convince myself. :)
12:24:37<wli>check using vacuum?
12:24:39<LeCamarade>What name is given to this kind of data type where this is the definition: data Void
12:24:57<LeCamarade>That is, with no constructors?
12:24:58<ivanm>LeCamarade: () ?
12:25:08<ivanm>or Not ?
12:25:14<ivanm>LeCamarade: oh, wait, no =...
12:25:19<ivanm>that requires an extension IIRC
12:25:27<LeCamarade>Yes, but I forget the name.
12:25:34<LeCamarade>"Existential"?
12:25:40<dolio>I haven't used vacuum. Will it tell me how many times a function is called to produce the same output list?
12:25:51<idnar>LeCamarade: phantom?
12:25:55<EvilTerran>LeCamarade, phantom type
12:25:56<doserj>-XEmptaDataDecls
12:26:20<dolio>I thought it just showed sharing, and the sharing in the output of both will be the same: none.
12:26:22<LeCamarade>Phantom, yes.
12:26:23<C-Keen>
12:26:42<ivanm>I thought phantom type was something like "newtype FooInt a = Foo Int" :s
12:26:51<doserj>so did I
12:27:02<wli>What do the two different iterate functions look like in vacuum?
12:27:02<ivanm>dolio: I think it shows so graphically
12:27:05<ivanm>have to ask mmorrow though
12:27:11<ivanm>wli: have a look! :p
12:27:24<dolio>That is, unless you do 'iterate id x' and the compiler optimizes map id to id, in which case the 'ys = x : map f ys' version will be better.
12:27:38<ivanm>dolio: oh? why?
12:28:04<dolio>Because then you get 'ys = x : map id ys = x : id ys = x : ys' which is a circular representation.
12:28:13<dolio>But that's a pretty special case.
12:28:14<ivanm>iterate id == repeat, right?
12:28:16<EvilTerran>, let iter f x = x : iter f x in vacuum . take 4 $ iter (():) []
12:28:18<lunabot> [(0,[1,2]),(1,[]),(2,[1,3]),(3,[1,4]),(4,[1,1])]
12:28:20<ivanm>dolio: oh, can ghc pick that up?
12:28:25<EvilTerran>, let iter f x = xs where xs = x : map f xs in vacuum . take 4 $ iter (():) []
12:28:28<lunabot> [(0,[1,2]),(1,[]),(2,[3,4]),(3,[5,1]),(4,[6,7]),(5,[]),(6,[5,3]),(7,[8,1]...
12:28:40<dolio>It might have a RULE for map id = id.
12:28:42<ivanm>oh, lunabot has a cut-down vacuum, does it?
12:28:46<ivanm>dolio: *nod*
12:28:57<EvilTerran>^ for ghc, then, it seems the first one wins
12:29:00<ivanm>so it'll become let ys = x : ys ?
12:29:12<ivanm>EvilTerran: \o/
12:30:23<EvilTerran>er, wait, my first one was wrong. hang on.
12:30:33<EvilTerran>, let iter f x = x : iter f (f x) in vacuum . take 4 $ iter (():) []
12:30:35<lunabot> [(0,[1,2]),(1,[]),(2,[3,4]),(3,[5,1]),(4,[6,7]),(5,[]),(6,[5,3]),(7,[8,1]...
12:30:42<EvilTerran>... they're the same! :D
12:31:02<ivanm>EvilTerran: :/
12:32:44<dolio>iter f x = x : iter f x is definitely bad. That gets O(n^2) behavior.
12:32:58<dolio>Er, x : map f (iter f x)
12:33:10<opqdonut>err, not?
12:33:10<ivanm>no sharing?
12:33:15<EvilTerran>dolio, vacuum disagrees there
12:33:54<mmorrow>, vacuum (fix (\x -> 0 : x))
12:33:56<lunabot> [(0,[1,0]),(1,[])]
12:34:13<mmorrow>, vacuum (cycle [0])
12:34:16<lunabot> [(0,[1,0]),(1,[])]
12:34:18<mmorrow>, vacuum (repeat 0)
12:34:20<lunabot> [(0,[1,0]),(1,[])]
12:34:29<mmorrow>i thought that one was gonna get killed
12:34:40<ygui>hi there :) I have a question about "import Control.Parallel" in "Haskell in 5 Steps", I got an error message saying it does not exist. Do I need to install this package separately? I'm using GHC 6.8.2.
12:34:46<dolio>, vacuum (iterate id 0)
12:34:52<lunabot> Killed.
12:34:57<EvilTerran>, vacuum [(),()..]
12:34:59<lunabot> [(0,[1,0]),(1,[])]
12:34:59<mmorrow>infinite list
12:35:08<ivanm>ygui: probably
12:35:09<opqdonut>, vacuum (iterate (const 0) 0)
12:35:15<lunabot> Killed.
12:35:16<EvilTerran>, vacuum [0 :: Int,0..]
12:35:19<opqdonut>hmm
12:35:23<lunabot> Killed.
12:35:30<ygui>oh, ivanm, let me see...
12:36:05<ivanm>ygui: yeah, you need the parallel library
12:36:16<mmorrow>, let ntimes n = foldr (.) id . replicate n in fmap (vacuum . ($ 0) . flip ntimes id) [0..]
12:36:18<lunabot> [[(0,[])],[(0,[])],[(0,[])],[(0,[])],[(0,[])],[(0,[])],[(0,[])],[(0,[])],...
12:36:26<dolio>Where does vacuum disagree with me? Because I already verified that 'iterate f x = x : map f (iterate f x)' calls f O(n^2) times.
12:36:55<ygui>ivanm: then, where do I find this library? on haskell.org?
12:37:01<ivanm>@hackage parallel
12:37:01<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parallel
12:37:03<EvilTerran>dolio, well, vacuum indicates that the sharing is identical to "iterate f x = x : iterate f (f x)"
12:37:07<ivanm>ygui: which OS/distribution are you using?
12:37:20<wli>iterate f x = let ys = x : map f ys in ys is another story OTOH
12:37:33<dolio>Right. That one's fine.
12:37:39<EvilTerran>ah, i see the difference
12:37:45<EvilTerran>yeah. i think we're in agreement, then :P
12:37:47<mmorrow>, let iter f x = fix (\xs -> x : map f xs) in vacuum (iter id 0)
12:37:53<lunabot> Killed.
12:37:59<ygui>I'm using DreamLinux 3.5, based on Debian Linux
12:38:07<mmorrow>, let iter f x = fix (\xs -> x : map f xs) in vacuumTo (iter id 0)
12:38:08<lunabot> luna: Not in scope: `vacuumTo'
12:38:09<mmorrow>, let iter f x = fix (\xs -> x : map f xs) in vacuumTo 4 (iter id 0)
12:38:10<lunabot> luna: Not in scope: `vacuumTo'
12:38:21<vixey>ooh vacuum was in my dream I think
12:38:25<dolio>Yeah, it's the same situation as "fix f = x where x = f x" versus "fix f = f (fix f)".
12:38:31<mmorrow>vixey: ooh, yay!
12:38:53<vixey>I think I was profiling something very meticulously and using vacuum a lot
12:39:08<mmorrow>vixey: :)!
12:39:12<ygui>ivanm, I'm using DreamLinux 3.5, a debian-based distribution.
12:39:17<ivanm>ygui: no idea about that one
12:39:17<vixey>(other people dream about flying and so on..)
12:39:28<ivanm>you might be able to use debian packages, but I don't know what stage they're at either
12:39:39<ivanm>ygui: your best bet is probably to get cabal-install and use that
12:39:43<ivanm>@where cabal-install
12:39:43<lambdabot>http://hackage.haskell.org/trac/hackage/wiki/CabalInstall
12:39:44<mmorrow>vixey: i updated vacuum-gl, it no longer segfaults when used with -threaded, since i realized that OpenGL uses thread-local state, so i have to forkOS
12:39:48<ivanm>ygui: ^^ have a look there
12:40:16<ygui>ok, ivanm, lambdabot, thanks!
12:40:20<ygui>let me try.
12:40:33<ivanm>good work, lambdabot :p
12:40:34<ivanm>@bot
12:40:35<lunabot> :)
12:40:36<lambdabot>:)
12:40:40<mmorrow>it's pretty stable too, -/+ zoom, arrows move, and it can handle, e.g., forkIO'ing 40 threads all inserting random values into an IntMap in an MVar, and 'view'ing every insert, so you can watch the tree grow in realtime
12:40:41<ivanm>no, not you lunabot
12:41:03<mmorrow>ACTION makes a screenvideo
12:41:14<ivanm>mmorrow: control your bot, it keeps stealing all of lambdabot's snacks! :p
12:41:27<mmorrow>ivanm: :)
12:43:32<quicksilver>mmorrow: ooh, that sounds nice.
12:44:17<dolio>Did you add some bloom?
12:44:35<dolio>You last screenshot was severely lacking it.
12:44:59<ivanm>dolio: you mean "boom"?
12:45:08<ivanm>ACTION wants to know where the earth-shattering kaboom was...
12:45:09<ivanm>;-)
12:45:15<Berengal>How long until we can blast aliens inbetween fingertrees?
12:45:34<dolio>No, bloom: http://en.wikipedia.org/wiki/Bloom_(shader_effect)
12:47:45<mmorrow>quicksilver: it's neato. i've been looking through your forces too.
12:48:00<mmorrow>ACTION fails first attempt at a screenvideo
12:48:14<mmorrow>http://moonpatio.com/repos/vacuum-gl/
12:48:24<ivanm>mmorrow: how does neato compare to dot for the graphs?
12:48:38<ivanm>or do you mean "neat-o", as in "cool", "rad", etc.? ;-)
12:48:42<mmorrow>ivanm: oooh, it's pretty cool in some cases. one sec for a screenshot
12:48:57<ivanm>that's more than one sec! :@
12:48:57<ivanm>;-)
12:49:02<fasta>I would like to add another test executable to the cabal file, but I read somewhere that it's not intended to be used like that. I also don't want to copy all the information manually from the one cabal file to the other. I could write a program which does this, but that seems a bad idea also. Is there a sane solution for this?
12:49:13<quicksilver>mmorrow: I'm sure yours is much cleverer than mine. Mine was merely an agreement with peter V's assertion that it "ought to be easy" ;)
12:49:17<ivanm>ACTION thinks mmorrow is lying about this vacuum app, and is doing everything by hand... using trained monkeys! :p
12:49:32<ivanm>fasta: not sure what you're wanting here...
12:50:06<dcoutts>fasta: the sane solution is to extend cabal, but perhaps you're looking for a quick hack?
12:50:09<ivanm>and I always find it really annoying when devs include their QC, etc. tests in their packaged tarballs... surely they should either require an optional flag or be only found in the development repo?
12:50:18<vixey>"you can watch the tree grow in realtime" -- sounsd cool
12:50:24<mmorrow>ivanm: http://moonpatio.com/vacuum/gallery/neato_vac.png
12:50:53<fasta>ivanm: I want to basically have cabal generate two executables. One is the real program, the other is a program which runs the test suite. I could also write shell scripts to do this, but then it won't work on Windows, without work.
12:51:03<mmorrow>quicksilver: i've been using your code as examples for HsOpenGL stuff
12:51:22<ivanm>mmorrow: my mum says it's "perty", but should be symmetrical... :p
12:51:45<mmorrow>quicksilver: and i don't do any 3D, just 2D textures of image data slurped from graphviz
12:52:01<fasta>mmorrow: dot can do symmetrical graphs too.
12:52:13<mmorrow>ivanm: iirc neato uses a randomized algo, so no two neato renderings are ever the same
12:52:18<mmorrow>fasta: oh nice
12:52:24<ivanm>fasta: can it? dot is for hierarchical graphs, isn't it?
12:52:36<ivanm>mmorrow: I'm pretty sure that it's pretty much the same all the time
12:52:41<ivanm>at least by default
12:53:03<ivanm>I recall playing around with random stuff in dot at least to see what changes it made to some of my graphs, and the answer was "not much" :s
12:53:40<ivanm>mmorrow: but really... a haskell user like yourself, and you don't use xmonad? for shame!
12:53:42<ivanm>:p
12:53:57<ivanm>mmorrow: I like the message your script produces though :p
12:54:23<Berengal>It's the new hello world
12:54:47<Berengal>Didn't you get the memo?
12:54:56<fasta>mmorrow: it appears neato does so, according to https://mailman.research.att.com/pipermail/graphviz-interest/2006q1/003336.html
12:54:59<ivanm>Berengal: so you're saying we need to do a global "s/Hello World/O HAI/g" ?
12:55:14<Berengal>ivanm: No that would be silly...
12:55:24<Berengal>"s/foo/bar/g" is already global ;)
12:55:31<ivanm>Berengal: global for that _file_
12:55:31<xrfang>@src True
12:55:32<lambdabot>Source not found. Maybe you made a typo?
12:55:37<ivanm>I'm saying to do it over the entire _globe_
12:55:41<xrfang>> let a = true
12:55:42<lambdabot> <no location info>: parse error on input `;'
12:55:49<xrfang>> let a = True
12:55:50<lambdabot> <no location info>: parse error on input `;'
12:56:02<xrfang>> let a = True in print a
12:56:03<lambdabot> * Exception: "<IO ()>"
12:56:21<Berengal>ivanm: Which is everything with the right block device... stop correcting my mistakes :P
12:56:30<beelsebob>gah
12:56:31<xrfang>@list
12:56:31<lambdabot>http://code.haskell.org/lambdabot/COMMANDS
12:56:34<beelsebob>why doesn't ftgl work :(
12:56:36<ivanm>Berengal: heh
12:56:42<ivanm>beelsebob: you mean fgl?
12:56:48<beelsebob>no, I mean ftgl
12:56:59<beelsebob>freetype gl
12:57:02<xrfang>> 1 == 1
12:57:03<lambdabot> True
12:57:06<ivanm>ahhhhh
12:57:08<Berengal>faster than greased lightning?
12:57:34<Berengal>?src Bool
12:57:34<lambdabot>data Bool = False | True deriving (Eq, Ord)
12:59:03<ivanm>ACTION thinks someone needs to run sort on lambdabot's channel list shown by "@seen lambdabot"
12:59:07<beelsebob>I managed to fix this before... http://hpaste.org/fastcgi/hpaste.fcgi/view?id=1766
12:59:11<beelsebob>but I can't figure out how the hell I did it
13:00:14<mmorrow>anyways, i fail at screen-capture. here's the code to grow an IntMap with a bunch of threads inserting randomly http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2251#a2251
13:00:32<xrfang>can I define a infix function without ` ?
13:00:45<beelsebob>xrfang: yes, using symbols
13:00:55<mmorrow>ivanm: heh, i use xmonad on-and-off... i like to switch it up
13:00:59<quicksilver>mmorrow: Ah, ok. Cute.
13:01:03<mmorrow>fasta: interesting
13:01:09<beelsebob>> let x <^^^/+\^^^> y = x + y in 5 <^^^/
13:01:10<lambdabot> <no location info>: parse error on input `;'
13:01:11<beelsebob>gah
13:01:16<beelsebob>> let x <^^^/+\^^^> y = x + y in 5 <^^^/+\^^^> 6
13:01:18<lambdabot> 11
13:01:19<xrfang>beelsebob: you mean the function name contains only symbol, no letters?
13:01:23<beelsebob>indeed
13:01:36<beelsebob>there you go – 5 flying saucer 6 is 11
13:01:37<mmorrow>quicksilver: yeah, i wish there was some sort of way to "instrument" the heap so, say, evaluating a node would cause it to be drawn or something
13:01:38<fasta>mmorrow: graphviz is sort of amazing in that it has advanced algorithms, which are actually implemented.
13:01:55<mmorrow>quicksilver: but i think you'd need to be in C-land to do that (or do it during compilation)
13:02:09<mmorrow>fasta: yeah, graphviz is great
13:02:26<fasta>mmorrow: most algorithms of that level are either only have proprietary implementations or only exist in some buggy version in a book (aka, does not exist).
13:02:43<wli>I wish I were capable of implementing advanced algorithms.
13:02:49<wli>fasta: Surely you mean a paper.
13:02:57<Berengal>let 2 + 2 = 5; a + b = a - (-b) in (5 + 2, (3-1) + (1+1))
13:02:59<xrfang>If I want to define a function %, I will need to write (%) right?
13:03:02<fasta>wli: eh, yes.
13:03:05<Berengal>> let 2 + 2 = 5; a + b = a - (-b) in (5 + 2, (3-1) + (1+1))
13:03:07<lambdabot> (7,5)
13:03:33<fasta>wli: implementing advanced algorithms is not difficult, it's figuring out what the paper tries to communicate incompletely and incorrectly.
13:04:18<EvilTerran>xrfang, you can write "x % y = ..."
13:04:29<wli>fasta: That's already beyond me in all known instances.
13:04:42<xrfang>EvilTerran: I am writing a subString function as an exercise
13:04:50<xrfang>I choose to use % to name the function
13:05:02<xrfang>I have to write (%) :: [a] -> [a] -> Bool
13:05:10<xrfang>if I write % :: ... it does not compile
13:05:14<EvilTerran>yeah, *there* you have to write it in ()s
13:05:22<xrfang>tks
13:05:32<EvilTerran>but not in the actual definition, just in the type signatures
13:05:44<ivanm>fasta: heh, I was interested in implementing the VFLib isomorphism algorithm... it's very vague/general (note that they do have a C++ implementation though)
13:05:49<Berengal>?src (%)
13:05:49<lambdabot>x % y = reduce (x * signum y) (abs y)
13:05:54<Berengal>@type (%)
13:05:55<lambdabot>forall a. (Integral a) => a -> a -> Ratio a
13:06:05<ivanm>whilst it's bad and unreadable, at least the nauty paper's algorithm can be slogged out because it's all there
13:06:18<ivanm>not just "hey, look, here's a high-level overview... isn't it cool?" :s
13:06:27<wli>ivanm: What sort of isomorphism? Graph isomorphism?
13:06:33<ivanm>yup
13:06:38<ivanm>I know about hgal
13:06:51<ivanm>it just seems to be very inefficient here :s
13:07:01<ivanm>especially since nauty is often touted as being really fast :s
13:07:15<ivanm>ACTION is trying to re-implement it from scratch atm
13:07:33<wli>I'm struggling hard enough with ways to factor polynomials over algebraic number fields or otherwise find roots in algebraic number fields.
13:08:12<quicksilver>mmorrow: sounds like an RTS hook, yes, although not a stupid one to ask for.
13:08:13<fasta>ivanm: is this going to be on Hackage or not? Either way, it will probably be hard to beat graphviz.
13:08:23<quicksilver>mmorrow: currently vacuum forces as it goes, doesn't it?
13:08:28<ivanm>fasta: graph isomorphism, not graph drawing ;-)
13:08:39<ivanm>though matthew-_ is dumping his graphviz bindings onto me :s
13:09:38<wli>I'm trying to do things like simplify (35*2^(4/5)+35*2^(3/5)+23*2^(2/5)+21*2^(1/5)+43)^(1/7) to 2^(1/5)+1
13:09:46<fasta>ivanm: right
13:10:05<xrfang>the notion @ can be used in lambda only or anywhere? e.g. l@(x:xs) etc.
13:10:16<fasta>ivanm: I thought someone had written a P algorithm for graph isomorphism recently.
13:10:24<EvilTerran>xrfang, anywhere in patterns
13:10:29<xrfang>I try to define a function e.g. test x y, while x and y is list
13:10:32<xrfang>tks
13:10:45<ivanm>fasta: oh? AFAIK, the graph isomorphism problem is not know to be either P or NP :s
13:10:56<fasta>ivanm: http://pierre-menard.blogspot.com/2007/12/graph-isomorphism-is-in-p.html
13:11:01<ivanm>ACTION really should stop responding to people talking to him here and get some shut-eye...
13:11:31<fasta>ivanm: yes, it was unknown for a long time, and arguably still is, until the "community" claims this result is correct.
13:11:33<ivanm>fasta: a lot of these are proven to be wrong...
13:11:46<fasta>ivanm: yes, that's what I said :)
13:12:07<ivanm>heh
13:12:39<vixey>fasta, *wonders if that blog is a hoax or not*
13:12:45<ivanm>fasta: I find it interesting that the blog post is from 2007, but the paper is dated in feb last year...
13:12:53<fasta>vixey: the paper isn't a hoax.
13:12:56<vixey>fasta: I was reason proofs of P = NP on that webiste the other day
13:13:09<vixey>arxiv
13:13:13<fasta>vixey: yes, but that website is not a joke.
13:13:31<ivanm>ACTION really goes to bed this time
13:13:33<ivanm>g'night
13:13:46<vixey>ACTION tries to decode "In China today, Bill Gates is Britney Spears. In America today, Britney Spears is Britney Spears - and that is our problem."
13:14:29<nanothief>With template haskell, is there a way to get the type of an Exp?
13:14:56<QtPlaty[HireMe]>vixey: Bill Gates is a celbrity in china, Britney Spears is a celbrity in the US. This is problem.
13:15:09<wli>vixey: Apparently the Chinese reputedly find captains of industry to be worthwhile people, while usanians find drug-addled "recording artists" to be worthwhile people.
13:15:28<Frontier>http://froni.mybrute.com come kill me
13:15:29<vixey>oh cool I see
13:16:07<Frontier>http://froni.mybrute.com come kill me
13:17:05<wli>Apparently neither place value on science, engineering, or other such concerns.
13:17:10<mmorrow>quicksilver: yeah, it's currently forcing as it goes... there's some weird segfault occurring if it doesn't force everything, but i think it must be something stupid i'm doing and not an inherent limitation..
13:17:29<mmorrow>quicksilver: that would definitely be a nice hook to have
13:17:39<juhp_>ACTION wonders why runghc is not working
13:18:24<wli>ACTION probably falls into some limbo since he regards drug-addled recording artists as degenerates of one stripe and captains of industry as degenerates of another.
13:21:34<quicksilver>mmorrow: *nod*
13:21:45<quicksilver>mmorrow: although, quite often, forcing as you go is definitely waht you want.
13:21:52<quicksilver>I meant, that's a useful tool - observing sharing.
13:22:01<quicksilver>observing incomplete evaluation is another useful tool, though.
13:29:27<xrfang>I know the meaning of $ but I am still a little bit confused. e.g. take (length [1,2,3]) [1,2,3,4]
13:29:41<vixey>well I don't see any $ in that xrfang
13:29:41<xrfang>can I use either "." or "$" to rewrite this function to get rid of ()?
13:29:58<xrfang>in another word, I am a bit confused by the precedence of functions in haskell
13:30:25<xrfang>there are MANY error I made due to lack of () in function definition!
13:30:28<jlaire>no, you can't
13:30:29<mmorrow>quicksilver: yeah, true
13:30:41<mmorrow>err, to both
13:30:44<vixey>xrfang: it works like this f x y z = ((f x) y) z
13:31:00<xrfang>here we have 2 functions, take and length...
13:31:16<vixey>xrfang: if you put any operator in e.g. *, then f x * y z = (f x) * (y z)
13:31:46<xrfang>* itself is a function...
13:31:54<vixey>xrfang: don't bother with ($) it is silly
13:32:18<xrfang>e.g. func x:xs... I must write func (x:xs), otherwise it becomes (func x):xs, right?
13:32:21<jlaire>prefix functions (words) always come before infix functions (symbols) in precedence
13:32:26<jlaire>right
13:32:37<vixey>xrfang, yes
13:33:46<xrfang>if I write: take length [1,2,3] [1,2,3,4], can haskell infer that the function length only take one parameter, so we can omit (), or it will think the function as (take length) [1,2,3] [1,2,3,4]?
13:34:09<vixey>xrfang, not how it works...
13:34:13<vixey>xrfang: it works like this: f x y z = ((f x) y) z
13:34:16<xrfang>it should know how many (maximum) parameters a function can take?
13:34:19<QtPlaty[HireMe]>xrfang: What do you wish to do with the other one?
13:34:20<xrfang>ok
13:34:26<vixey>take length [1,2,3] [1,2,3,4] = ((take length) [1,2,3]) [1,2,3,4]
13:34:41<xrfang>I am not "wish" I just try to fully understand the syntax of haskell :)
13:34:57<QtPlaty[HireMe]>:t take
13:34:59<lambdabot>forall a. Int -> [a] -> [a]
13:35:05<vixey>types aren't even relevant to this
13:35:23<QtPlaty[HireMe]>vixey: I was just working out the paramitors for take.
13:35:26<xrfang>ok, then (take length) is not valid ....
13:35:44<QtPlaty[HireMe]>Thats right though take . length is valid.
13:35:56<xrfang>then, just *suppose* it is valid to write ((take length) [1,2,3]) [1,2,3,4], is that same as: ((take.length) [1,2,3]) [1,2,3,4]
13:36:00<xrfang>note the "." in it
13:36:01<vixey>:t take . length
13:36:02<lambdabot>forall a a1. [a1] -> [a] -> [a]
13:36:25<QtPlaty[HireMe]>xrfang: Not quite
13:36:28<jberryman>xrfang: also, you should realize that ($) and (.) are just regular, higher-order functions
13:36:37<vixey>xrfang: ((take length) [1,2,3]) [1,2,3,4] is ___NOT___ valid
13:36:42<jberryman>@type: (.)
13:36:44<lambdabot>forall b c a. (b -> c) -> (a -> b) -> a -> c
13:36:44<xrfang>a bit confused.
13:36:45<vixey>xrfang: so it isn't the same as something valid
13:36:53<QtPlaty[HireMe]>take (length [1,2,3]) [1,2,3,4]
13:36:57<xrfang>I mean I try to understand the "."
13:37:09<xrfang>func1 func2 func3 123
13:37:11<xrfang>vs.
13:37:11<QtPlaty[HireMe]>@src (.)
13:37:12<lambdabot>(f . g) x = f (g x)
13:37:14<Zao>xrfang: Glue the output of the latter function to the input of the former.
13:37:17<xrfang>func1.func2.func3 123
13:37:23<xrfang>oh
13:37:34<xrfang>that . is right associative...
13:37:35<xrfang>right?
13:38:10<jlaire>right
13:38:10<xrfang>> negate max 3 4
13:38:11<jberryman>xrfang: take a look at the types an source for (.) and ($), and it will sink in
13:38:11<QtPlaty[HireMe]>How do you mean?
13:38:12<lambdabot> No instance for (Num (a -> a -> a))
13:38:12<lambdabot> arising from a use of `negat...
13:38:23<xrfang>> negate ( max 3 4)
13:38:25<lambdabot> -4
13:38:32<xrfang>> negate.max 3 4
13:38:33<lambdabot> No instance for (Ord (a -> b))
13:38:34<lambdabot> arising from a use of `max' at <i...
13:38:51<jlaire>> (negate . max 3) 4
13:38:53<lambdabot> -4
13:39:36<xrfang>what is the diff: negate.max 3 4 vs. (negate . max 3) 4
13:39:51<jlaire>negate . max 3 4 = negate . (max 3 4)
13:40:17<xrfang>thanks jlaire
13:40:25<xrfang>> (negate.max) 3 4
13:40:26<lambdabot> No instance for (Num (a -> a))
13:40:27<lambdabot> arising from a use of `negate' at...
13:40:41<QtPlaty[HireMe]>xrfang: (max 3) is a function.
13:40:44<nlogax>> (negate . max 3) 4
13:40:47<lambdabot> -4
13:40:48<jlaire>> ((negate .) . max) 3 4
13:40:48<xrfang>ok
13:40:50<lambdabot> -4
13:41:20<Berengal>> fmap (fmap negate) max 3 4
13:41:21<lambdabot> -4
13:41:23<QtPlaty[HireMe]>:t (megate . max 3)
13:41:25<lambdabot>Not in scope: `megate'
13:41:38<QtPlaty[HireMe]>:t (negate . max 3)
13:41:40<lambdabot>forall b. (Ord b, Num b) => b -> b
13:41:45<jlaire>:t fmap
13:41:46<Saizan>negate . max 3 4 == \x -> negate (max 3 4 x); (negate . max) 3 4 == negate (max 3) 4; (negate . max 3) 4 == negate (max 3 4)
13:41:47<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
13:41:52<wli>http://wli.pastebin.com/m11009a94 <-- still stumped wrt. modules
13:42:42<wli>Where do signatures and sharing constraints go?
13:42:45<phoebe1860>hi there
13:42:59<phoebe1860>any body here?
13:43:17<Berengal>Yes, hello :)
13:43:42<QtPlaty[HireMe]>module Modules(TypeYouWishToExport(..),functions,to,export) where
13:43:59<QtPlaty[HireMe]>ACTION is disembodied.
13:45:40<phoebe1860>dadada
13:45:41<wli>Well, I've got export lists in the module bit of the AST.
13:49:03<jberryman>is there a way to get GHC to derive Ord when my type contains a type that's not an instance of Ord?
13:49:49<jberryman>seems like it should just ignore that part of the data type, if it can
13:49:55<xrfang>> (negate.max 3) 4
13:49:56<lambdabot> -4
13:50:15<xrfang>> (.) negate (max 3) 4
13:50:17<lambdabot> -4
13:50:36<QtPlaty[HireMe]>jberryman: You wish force a type constraint?
13:50:36<xrfang>> (.) negate max 3 4
13:50:37<lambdabot> No instance for (Num (a -> a))
13:50:37<lambdabot> arising from a use of `negate' at...
13:52:18<kadaver>> (.) (+) 3 4
13:52:19<lambdabot> Overlapping instances for Show (b -> b)
13:52:19<lambdabot> arising from a use of `s...
13:52:32<kadaver>> (.) (+ . *) 3 4
13:52:33<lambdabot> <no location info>: parse error on input `.'
13:52:34<Berengal>jberryman: You mean like "data Foo = A Int | B Char | C foo" ?
13:52:37<kadaver>> (+ . *) 3 4
13:52:38<lambdabot> <no location info>: parse error on input `.'
13:52:47<kadaver>> ((.) + *) 3 4
13:52:48<lambdabot> <no location info>: parse error on input `*'
13:52:55<kadaver>> ((.) + (4*)) 3 4
13:52:56<lambdabot> Occurs check: cannot construct the infinite type: b = a -> b
13:52:56<lambdabot> Proba...
13:53:02<kadaver>> ((.) (+6) (4*)) 3 4
13:53:03<lambdabot> No instance for (Num (t -> a))
13:53:03<lambdabot> arising from the literal `6' at <...
13:53:08<plash>> ((+) . (*)) 3 4
13:53:09<lambdabot> No instance for (Num (a -> a))
13:53:09<lambdabot> arising from a use of `+' at <int...
13:53:19<kadaver>> (.) (+6) (4*) 3 4
13:53:20<lambdabot> No instance for (Num (t -> a))
13:53:20<lambdabot> arising from the literal `6' at <...
13:53:24<jlaire>:t ((+) . (*))
13:53:25<lambdabot>forall a. (Num a, Num (a -> a)) => a -> (a -> a) -> a -> a
13:53:27<QtPlaty[HireMe]>ACTION asks "Is there any projects in haskell that while not trival would be benifical to the Haskell community and I could work at.
13:53:30<poucet>Please cut the spam
13:53:32<kadaver>> (.) (+6) (min 2) 3 4
13:53:33<lambdabot> No instance for (Num (t -> a))
13:53:33<lambdabot> arising from the literal `6' at <...
13:53:46<poucet>You can privmsg lambdabot
13:54:08<QtPlaty[HireMe]>ACTION is looking for something of 'Goldylocks' skill leval.
13:54:31<Saizan>QtPlaty[HireMe]: the cabal's trac is full of them :)
13:54:46<QtPlaty[HireMe]>Saizan: URL?
13:55:12<dcoutts>QtPlaty[HireMe]: "easy" cabal tickets: http://hackage.haskell.org/trac/hackage/report/13
13:55:17<kadaver>is darcs dying(because of git)?
13:55:31<jberryman>kadaver: no
13:56:57<ehird>kadaver: yes
13:57:03<dcoutts>kadaver: afaict, development is quite active and the size of the user base is relatively stable
14:02:04<ryanakca>How would I join two lists together? I've tried myFunct xs = xs:xs ... but that doesn't seem to work...
14:02:17<QtPlaty[HireMe]>ryanakca: ++
14:02:21<xrfang>I wrote a function to check if a list is a sub-list of another: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2252
14:02:30<ryanakca>QtPlaty[HireMe]: Ah, thanks
14:02:33<xrfang>however, it does not compile: Could not deduce (Eq a) from the context ()
14:03:15<xrfang>on line 16...
14:03:29<Saizan>xrfang: the correct signature is "(%) :: Eq a => [a] -> [a] -> Bool"
14:03:41<xrfang>ok, thanks, modifying
14:03:50<Saizan>xrfang: because of your use of the (==) operator
14:03:55<Saizan>?type (==)
14:03:56<lambdabot>forall a. (Eq a) => a -> a -> Bool
14:04:08<QtPlaty[HireMe]>zrfang: You used == without constraning it to things that can be equal. Add Eq a => to your signature.
14:04:14<Axman6>xrfang: if you're unsure about a type signature, you should leave it out, and then get ghci to tell what it is
14:04:38<DrSyzygyFR>Is there a good way to limit execution time for a haskell program without using ulimit?
14:04:58<xrfang>so if I do NOT write it actually haskell CAN infer the correct signature? :)
14:05:02<DrSyzygyFR>I wanna profile a program not likely to finish; but ulimit kills it before the profiler writes out.
14:05:04<koeien_>xrfang: most of the time
14:05:04<Axman6>xrfang: also, just a style thing, instead of xh:xt, x:xs is usually used, as it says this is the first x in a list of xes
14:05:19<wli>There's not even that good of a way to limit execution time with ulimit.
14:05:25<quicksilver>DrSyzygyFR: have a thread run a long threadDelay and then kill the worker thread?
14:05:26<Axman6>xrfang: one of the best things about haskell is the type inference :)
14:05:34<xrfang>Axman6: yes, but x is used to represent the entire list :p
14:05:38<QtPlaty[HireMe]>xrfang: Most of the time yes.
14:05:49<xrfang>I will modify it to make clearer
14:05:52<Axman6>xrfang: well, xss is the usual name for that :)
14:05:53<xrfang>thanks,
14:06:04<Axman6>so you'd have xss@(x:xs)
14:06:13<Berengal>I use any of (h:t) (x:xs) xx@(x:xs)
14:06:23<DrSyzygyFR>quicksilver: Whu?
14:06:24<Saizan>quicksilver: that doesn't guarantee much about termination
14:06:26<xrfang>an "offtopic" question: ghci compiling is "real" or not? i.e. I make a hello world, the executable size is several hundred kb
14:06:35<xrfang>is it a real compiled executable
14:06:37<wjt>yes
14:06:46<xrfang>or an intepreter with some script binded in?
14:07:02<Berengal>It's real, it just includes lots of runtype info such as the garbage collector
14:07:06<xrfang>a "hello world" worth xxx KB... hm...
14:07:08<xrfang>ok
14:07:09<Axman6>i thought it was bytecode
14:07:11<xrfang>thanks
14:07:13<Berengal>"info" being the wrong word...
14:07:20<xrfang>... :|
14:07:29<Berengal>"code" being more corre... >_<
14:07:29<Saizan>ghci interprets to bytecode
14:07:31<Axman6>which is between native compilation and interpretation (like java)
14:07:31<wjt>stripping the binaries makes a *big* difference
14:07:33<Berengal>correct*
14:07:39<Axman6>hoorah, i was right
14:07:43<xrfang>I will try strip
14:07:49<xrfang>just curious
14:07:54<Saizan>what you get from ghc --make is a compiled binary
14:08:13<quicksilver>DrSyzygyFR: what was unclear? Create a new thread. Run long running cmoputation you don't expect to terminate. Kill it after n seconds.
14:08:28<quicksilver>Saizan: it guarantees clean termination which means you get a useful profile.
14:08:31<Saizan>which has the runtime system linked in, the runtime system does things like scheduling threads and running the garbage collector
14:09:29<xrfang>strip: 400430 -> 264084 (hello world)
14:09:31<xrfang>quite good
14:10:16<xrfang>Saizan: yes, I used exerb to generate ruby executable on windows, but that is actually ruby.exe binded with a "bytecode" version of the script ;)
14:11:24<bastl>where can i find some condensed information on the history of haskell: why/how was it invented, what languages did precede it, what languages were displaced?
14:11:44<Axman6>bastl: wikipedia says a bit
14:11:59<DrSyzygyFR>quicksilver: I got it now.
14:12:05<DrSyzygyFR>I never touched the threading interface.
14:12:09<DrSyzygyFR>before.
14:12:11<quicksilver>ACTION nods
14:12:20<quicksilver>well it's something of a hacky way to do what you asked
14:12:23<quicksilver>but I don't know of a clean way :)
14:12:25<Berengal>bastl: http://haskell.org/haskellwiki/History_of_Haskell
14:12:27<DrSyzygyFR>What you were suggesting was clear. How to do it wasn't until I googled a bit.
14:12:31<xrfang>on line 9 of http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2252
14:12:35<Axman6>DrSyzygyFR: threading may seem a little scary, but trust me, in haskell, it's _really_ nice to work with :)
14:12:41<xrfang>it says*** Exception: t.hs:18:18-29: Irrefutable pattern failed for pattern (_ : yt')
14:12:44<cothoughtpolice>bastl: http://research.microsoft.com/en-us/um/people/simonpj/papers/haskell-retrospective/
14:12:47<xrfang>run time error :S
14:13:01<xrfang>what is "Irrefutable pattern failed"?
14:13:18<Berengal>xrfang: It means the pattern match failed. It expected to see a : but didn't, because the list was empty
14:13:49<xrfang>ok, thanks, I will modify
14:13:55<Saizan>xrfang: so in your case, at some point y' was an empty list
14:14:23<xrfang>understandable, but I feel my program is being stupid
14:14:25<xrfang>one moment
14:14:34<BONUS>xrfang: what is your function supposed to do
14:14:41<Berengal>Is this the sublist function?
14:14:56<xrfang>it takes 2 lists
14:15:07<xrfang>if [a] is a sublist of [b] return true, else false
14:15:21<xrfang>an exercise while reading LYAH :)
14:15:31<BONUS>ah :)
14:15:53<Axman6>heh
14:16:03<trofi>@pl \n -> (n,1)
14:16:04<lambdabot>flip (,) 1
14:16:49<Axman6>:t uncurry id
14:16:50<lambdabot>forall b c. (b -> c, b) -> c
14:16:56<Axman6>:t curry id
14:16:57<lambdabot>forall a b. a -> b -> (a, b)
14:17:24<QtPlaty[HireMe]>expn LYAH?
14:17:44<wli>Learn You A Haskell, an extended Haskell tutorial
14:17:45<xrfang>hi expn?
14:18:02<QtPlaty[HireMe]>xrfang: Expand
14:18:10<quicksilver>@where lyah
14:18:10<lambdabot>www.learnyouahaskell.com
14:18:12<quicksilver>^^
14:18:28<xrfang>the (_:yt')... match takes place in the let part, I don't know if I can use if... then in that part or not?
14:18:29<xrfang>e.g
14:18:37<Axman6>Learn you a haskell for great good QtPlaty[HireMe]
14:18:50<xrfang>if y' == [] then ... else (_:yt') = y'...
14:18:51<Saizan>xrfang: it seems you're doing too many things at once in your function, btw, the logic can be much simpler
14:18:56<xrfang>but I think it does not make sence
14:19:04<Axman6>> null []
14:19:06<lambdabot> True
14:19:07<Axman6>> null [1]
14:19:09<lambdabot> False
14:19:19<quicksilver>xrfang: case y' of [] -> .... ; (_:yt') -> ....
14:19:23<xrfang>Saizan: I sure think so, that's why I think it is stupid, but I try not to use built-in functions or as little as...
14:19:25<quicksilver>xrfang: this is what case is for.
14:19:40<xrfang>I will try thanks
14:20:48<bastl>would it be ok to say that haskell is the standardized successor of languages like ML, Scheme, Lisp and Miranda !?
14:21:38<Axman6>it's a standardised successor to gopher at least
14:21:46<Saizan>Miranda surely
14:22:04<Axman6>ML, Scheme and Lips are all still used widely
14:22:12<Axman6>Lisp*
14:22:23<Axman6>"widely"
14:22:25<Saizan>and you can say that it's in the ML family, for scheme and Lisp i'd not be very convinced
14:22:48<dolio>Gofer didn't predate Haskell.
14:22:57<Axman6>didn't it?
14:23:06<Berengal>let rle l = map (head &&& length) . group $ l; let isSublist a b = let (a',b') = (rle.sort *** rle.sort) (a,b) in all (\(e,l) -> e `elem` (map fst a') && ((>=l).fromJust $ lookup e a')) b' in isSublist [1..10] [1,2,3]
14:23:06<Axman6>i was mistaken then
14:23:09<wli>I usually treat it like a "better ML," except I miss modules.
14:23:16<Berengal>> let rle l = map (head &&& length) . group $ l; let isSublist a b = let (a',b') = (rle.sort *** rle.sort) (a,b) in all (\(e,l) -> e `elem` (map fst a') && ((>=l).fromJust $ lookup e a')) b' in isSublist [1..10] [1,2,3]
14:23:16<dolio>It was based on 1.2, apparently.
14:23:17<lambdabot> <no location info>: parse error (possibly incorrect indentation)
14:23:21<Berengal>:/
14:23:23<Berengal>Works on my machine
14:23:54<doserj>> let (%) = (or .) . (. tails) . map . isPrefixOf in [3..11] % [1..12]
14:23:56<lambdabot> True
14:24:09<Saizan>gofer was more like an experimental spinoff to try some new features
14:24:31<Axman6>ah ok
14:24:40<Axman6>like monad comprehensions? or was that in haskell?
14:24:44<jlaire>let (%) = isInfixOf in [3..11] % [1..12]
14:24:46<jlaire>> let (%) = isInfixOf in [3..11] % [1..12]
14:24:48<lambdabot> True
14:25:09<Saizan>i think it was constructor classes, but i'm not that good at history
14:25:14<dolio>Monads appeared in 1.3, so Gofer may have been the first to have them.
14:25:34<DrSyzygyFR>ACTION has a Gröbner basis system for operads. Wooooters!
14:25:39<Axman6>dolio: you've been going on haskell for a while i take it?
14:26:10<dolio>No, but I've looked up this stuff at various times.
14:26:22<Axman6>fair enough
14:26:30<bastl>I want to say how Haskell developed to the state it is in now: started as a standardized successor to XYZ, was quickly/widely adopted by language researchers, nowadays has a kind of open-source-flavour, rich infrastructure, general purpose language.
14:27:08<poucet>bastl: http://en.wikipedia.org/wiki/Haskell_(programming_language)
14:28:23<xrfang>how to view modified version of code I pasted at moonpatio.com? it seems I cannot modify the code there, (after modify I still see the old version)
14:29:03<Saizan>xrfang: refresh and/or scroll down the page
14:29:03<dolio>The motivation was that lots of people were experimenting with lazy languages at the time, apparently, and they decided they'd be better off if there was some common language for that, rather than a bunch of custom ones.
14:29:22<bastl>poucet: thanks but the history section is to coarse, while being lazy whith class is too fine :-/
14:29:52<dolio>And as I recall they wanted to use Miranda, but the author didn't want to just open source it. So Haskell was made instead (and it looks a lot like Miranda).
14:30:18<QtPlaty[HireMe]>ACTION preffs Haskell to miranda so much.
14:30:23<bastl>dolio: really? is that citable?
14:30:33<bastl>ACTION never heard that.
14:30:42<xrfang>thanks Saizan
14:31:06<dolio>Which part? It's probably in the retrospective someone posted a link to a few minutes back.
14:31:16<bastl>ok
14:31:23<bastl>the open-source thing i mean
14:32:11<dolio>That may be in there, too. I'm pretty sure that was the reason. Its author didn't want to just give up control of it to a committee.
14:32:16<jlaire>the author also asked that Haskell has a sufficiently different syntax so people won't confuse it with Miranda
14:32:39<QtPlaty[HireMe]>jlaire: How strong is the miranda community now?
14:33:15<dolio>I don't think it's still being developed, is it?
14:33:26<jlaire>I don't think so, either
14:33:37<fasta>TFP is the last thing Turner did that I know of.
14:33:54<ryanakca>Could I have some feedback on http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4247#a4247 please (RWH p.69, #5, question and code included)... How is it style wise, etc.?
14:33:57<centrinia>What is Turner doing right now?
14:34:52<Axman6>ryanakca: might want to use tail btw
14:34:55<centrinia>ryanakca, I'm pretty sure that myCheck runs in O(n^2) time.
14:35:06<Saizan>ryanakca: take (length xs - 1) xs == init xs
14:35:08<Axman6>instead of take (length xs - 1)
14:35:15<Axman6>uh, or init even
14:36:06<Axman6>how efficient is the isPalin xs = xs == reverse xs version anyway?
14:36:22<Saizan>Axman6: O(n)
14:36:26<BONUS>yeah use init. although take (length xs - 1) xs does not equal init xs for infinite lists :)
14:36:35<ryanakca>What's init?
14:36:40<BONUS>> init [1,2,3,4]
14:36:42<lambdabot> [1,2,3]
14:36:43<centrinia>> let myCheck x = x == reverse x in myCheck $ filter (/= ' ') "madam im adam"
14:36:44<lambdabot> True
14:36:45<Axman6>Saizan: which is about as good as it can get right?
14:36:45<BONUS>first elements without the last
14:37:00<BONUS>Axman6: yeah, although it has O(n) space complexity imo
14:37:25<Axman6>> let myCheck x = x == reverse x in myCheck $ filter (/= ' ') "able was i ere i saw elba"
14:37:26<lambdabot> True
14:38:06<ryanakca>Ah. That makes infinitely more sense.
14:38:07<wli>isPalin "Sarah"
14:38:24<QtPlaty[HireMe]>isPalin "Michal"
14:38:58<johh>finding palindromes in linear time: http://johanjeuring.blogspot.com/2007/08/finding-palindromes.html
14:40:17<ryanakca>Also, is there such a thing as vi keybindings for the ghci prompt?
14:40:51<wli>ryanakca: I use the libreadline -based vi keybindings for ghci.
14:43:18<ryanakca>wli: ... and how would I go by enabling that. While compiling libreadline? ghci?
14:44:01<centrinia>> snd . (\z -> foldr (\y (x:xs,s) -> (xs,(y == x) && s)) (z,True) z) $ filter (/= ' ') "never odd or even"
14:44:03<lambdabot> True
14:44:10<centrinia>> snd . (\z -> foldr (\y (x:xs,s) -> (xs,(y == x) && s)) (z,True) z) $ filter (/= ' ') "sarah palin"
14:44:11<lambdabot> False
14:44:48<centrinia>Does that have sublinear space complexity?
14:47:11<Saizan>centrinia: that uses linear stack, afaict
14:47:35<centrinia>foldr uses a linear stack?
14:48:19<Saizan>it does if the combining function is strict on its second argument
14:48:35<dons>?users
14:48:35<lambdabot>Maximum users seen in #haskell: 658, currently: 613 (93.2%), active: 22 (3.6%)
14:49:26<centrinia>Okay, how does one test if a string is a palindrome with sublinear complexity? :(
14:49:44<centrinia>Uh, sublinear space complexity.
14:50:27<Saizan>with an array?:)
14:51:33<cjay>centrinia: normally you don't count the input as long as it doesn't get written to
14:51:35<quicksilver>well you certainly need it in a structure which has fast access to both ends.
14:51:37<cjay>at least with turing machines
14:51:48<quicksilver>so a Seq or an Array or something special purpose
14:52:02<quicksilver>and then just iterate in a way which doesn't build up thunks or stack.
14:52:27<Berengal>If the input is a linked list, I don't think it's possible
14:52:29<trofi>ACTION seeks updateOrInsertIfNothing in Data.Map
14:52:47<centrinia>So it is not possible to test if a linked list contains a palindrome in linear time complexity and sublinear space complexity? :(
14:53:09<Berengal>You want to get a hold of both ends of the string at the same time, and that requires either looking for the end repeatedly, or pushing it into another structure
14:54:06<quicksilver>trofi: "alter"
14:54:06<EvilTerran>you might be able to do something cunning with some kind of O(log n)-sized str ucture
14:54:20<trofi>:t alter
14:54:21<lambdabot>Not in scope: `alter'
14:54:25<trofi>:t M.alter
14:54:26<centrinia>> let myCheck x = x == reverse x in myCheck $ filter isAlpha "dammit, i'm mad!"
14:54:26<lambdabot>forall a k. (Ord k) => (Maybe a -> Maybe a) -> k -> M.Map k a -> M.Map k a
14:54:28<lambdabot> True
14:54:38<quicksilver>trofi: or insertWith
14:54:40<trofi>quicksilver: thanks a lot!
14:54:40<Berengal>@insertWith
14:54:40<lambdabot>Unknown command, try @list
14:54:45<Berengal>@hoogle insertWith
14:54:45<lambdabot>Data.IntMap insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
14:54:45<lambdabot>Data.Map insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
14:54:45<lambdabot>Data.Map insertWith' :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
14:54:53<quicksilver>Berengal: please don't do that.
14:55:10<quicksilver>it adds no value to the help I just gave, and caused 6 lines of output including your failed attempt.
14:55:20<quicksilver>I'm sure peopple can find the docs for Data.Map if they want them.
14:56:00<wli>You should be able to remember where the halfway point is and so only check ceiling (genericLength xs / 2)
14:57:00<centrinia>That's still linear with respect to genericLength xs :(
14:57:20<wli>You can't do better than linear.
14:58:43<byorgey>centrinia: I'm confused on what you mean by "sublinear space complexity". You have to at least store the string being tested somewhere in memory.
14:59:04<byorgey>you can never use sublinear space by definition.
14:59:19<cjay>byorgey: you can, if you don't count the input
14:59:30<centrinia>What if you write off the space requirements of the inputs?
14:59:33<DrSyzygyFR>So sublinear _additional_ space.
15:01:21<EvilTerran>i think "space complexity disregarding input space requirements" is one of those things where functional data structures will inevitably lose out
15:01:24<beelsebob>DrSyzygyFR: I don't get the distinction
15:01:39<byorgey>I guess my point is, if you're already using linear space to store the input, who cares about using additional linear space?
15:02:19<centrinia>byorgey, maybe the input doesn't explicitly require linear space.
15:02:44<centrinia>You might be able to compute the input on the fly.
15:03:21<poucet>byorgey: oy
15:04:23<byorgey>centrinia: well, I guess you can get into an interesting discussion of what "input" means. But generally if you're computing something on the fly, then it isn't the input. the input was whatever data you needed to construct this on-the-fly computation.
15:04:33<byorgey>hey poucet
15:04:54<poucet>byorgey: Hey :)
15:04:55<EvilTerran>centrinia, if you're computing the input on the fly, it's not really a linked list
15:05:08<poucet>byorgey: Life is limited, factors matter, O-notation is overrated :)
15:05:17<dolio>What if it's lazy?
15:06:28<EvilTerran>dolio, well, you'll still need to either force the entire thing in memory (in which case the "on-the-fly" aspect is irrelevant) or generate it repeatedly (in which case the data structure it happens to be passing through is a bit moot)
15:06:44<wli>What are the inputs to fibs = let fs = 0 : 1 : zipWith (+) fs (tail fs) in fs?
15:07:31<dolio>length [1..1000000] runs in O(1) space.
15:08:00<dolio>(Hopefully.)
15:08:16<poucet>> length [1..1000000]
15:08:18<lambdabot> 1000000
15:10:02<lpsmith>wli: what do you mean?
15:10:23<wli>It's a list generated on the fly so to speak.
15:10:46<lpsmith>correct, but what do you mean by "inputs"?
15:11:00<wli>omfg someone else handle this
15:12:12<poucet>wli: fibs is a nullary 'function', it has no inputs
15:12:17<byorgey>poucet: maybe constant factors matter to you, but here in academia I am mercifully shielded ;)
15:12:26<poucet>byorgey: until you try to run it on your machine?
15:12:59<byorgey>what is this "running" you speak of? all I ever do is write code and then typecheck it.
15:13:48<poucet>And the typechecking occurs in the typechecker of the compiler?
15:13:49<poucet>Smart
15:13:50<poucet>Very clever
15:14:10<poucet>so you don't evne have to run the compiler, you just typecheck it :)
15:18:35<DrSyzygyFR>Btw, how do I make Cabal play nice with umlauts?
15:18:40<DrSyzygyFR>Or Haddock for that matter?
15:18:54<dcoutts>DrSyzygyFR: .cabal files are UTF-8
15:19:07<dcoutts>DrSyzygyFR: as are .hs files
15:19:48<DrSyzygyFR>dcoutts: Ah.
15:20:01<DrSyzygyFR>Yeah, I seem to have saved everything in latin1 so far. *fixes*
15:21:07<DrSyzygyFR>Another random Q. How do I make the haddock generated from the cabal description field not come out as a solid chunk of text?
15:22:03<dcoutts>DrSyzygyFR: strangely, to get blank lines in fields in .cabal files you need the line to begin with a . and otherwise be blank.
15:22:14<DrSyzygyFR>dcoutts: Aight!!
15:22:21<dcoutts>crazy I know, I'll lift that restriction next time I rewrite the parser
15:22:40<dcoutts>it used to be the case that blank lines separated sections
15:23:34<DrSyzygyFR>I get Setup: operads.cabal:16: unrecognised field or section: "."
15:24:08<dcoutts>DrSyzygyFR: I think it's got to be at the same indentation level
15:24:33<DrSyzygyFR>Ah, ok!
15:25:47<cinema>kosmikus: ping
15:25:47<lambdabot>cinema: You have 2 new messages. '/msg lambdabot @messages' to read them.
15:40:48<Axman6>the google logo today is awesome
15:41:24<quicksilver>ACTION thinks Axman6 is too easily awed.
15:42:18<Axman6>you juat wait ultil there's a quicksilver logo when you die and i think it's awesome ;)
15:42:30<Axman6>just even
15:43:16<gwern>ACTION looks
15:43:32<gwern>OH MY GOD. MY LIFE IS CHANGED FOREVER
15:43:41<gwern>THIS CHANGES EVERYTHING
15:44:42<Axman6>ACTION replaces awesome with pretty cool to cease the snide remarks
15:45:14<gwern>ACTION is always snide until smithers gives me my sponge-bath
15:45:17<gwern>and caffeine
15:47:09<ali_clark>hi, hope you don't mind if i ask a question to help me clear something up...
15:47:16<mreh>i need a solution for testing for character presses, all the IO actions that I have wait for key presses
15:47:20<mreh>ask away
15:47:47<ali_clark>thanks, heres a function: foo x = case x of { 0 -> 0; y -> 1 / y }
15:47:56<mreh>yup
15:47:56<ali_clark>is foo 0 compiled straight to 0?
15:48:06<mreh>nope
15:48:13<ali_clark>okay, thanks!
15:48:25<ali_clark>but if i wrote foo 0 = 0 that would be, right?
15:48:44<gwern>mreh: you can't know that. that seems like a perfectly possible optimization to me
15:48:46<mreh>well, i dont know about the compiled C code
15:49:02<gwern>ali_clark: to know for sure you need to look at the code, and obviously use -O2
15:49:19<mreh>when I hear compiled in my head I think of something else
15:49:24<MyCatVerbs>ali_clark: the optimizer is both smarter and dumber than you might expect.
15:49:48<mreh>can you help meeee now?!?!
15:49:52<ali_clark>hmmms i thought it was merely a case that pattern matching a fn definition is strict but not otherwise
15:50:11<ali_clark>ach nvm
15:50:16<MyCatVerbs>ali_clark: it will easily compile { foo x = case x of { 0 -> 0; y -> 1 / y; } } and { foo 0 = 0; foo y = 1 / y; } to the same code.
15:50:41<ali_clark>oh right thats what i was asking, thanks!
15:50:42<quicksilver>ali_clark: for the specific case of numbers, I think not.
15:50:42<mreh>use pattern matching
15:50:49<mreh>your job isnt to optimize code
15:50:52<quicksilver>hmm.
15:50:56<quicksilver>actually, yes it will.
15:51:02<quicksilver>it will inline and reduce that.
15:51:16<MyCatVerbs>If you get paranoid, grab ghc-core off hackage ("cabal install ghc-core" should hopefully just work) and check the core output.
15:51:32<MyCatVerbs>Otherwise, profile first, *then* worry.
15:51:59<mreh>how can i check for a keypress if all my IO actions *wait* for a keypress?
15:52:00<gwern>ACTION looks at the core output. man i dunno
15:52:17<MyCatVerbs>gwern: painful, isn't it? =)
15:52:22<gwern>mreh: then by definition can't the io action assume a keypress?
15:52:32<gwern>MyCatVerbs: yeah. it doesn't seem to even keep the identifiers
15:52:32<mreh>no
15:52:53<mreh>gwern: it's a reactive animation
15:53:11<mreh>when users press keys, stuff moves
15:54:03<mreh>so if the window tick is up, then it needs to refresh the animation
15:54:18<lpsmith>gwern: that case should get optimized if "foo" is inlined, otherwise not.
15:54:39<quicksilver>even without inlining that kind of thing can be optimised by SpecConstr
15:54:48<quicksilver>(although probably not on numbers, which aren't normal constructors)
15:54:51<mreh>i dont know what you mean by assume, gwern
15:54:56<quicksilver>but with inlining it will collups completely.
15:55:01<quicksilver>collapse.
15:55:04<quicksilver>what a weird typo.
15:55:05<mreh>hehe
15:55:14<mreh>subconcious lolspeak
15:55:24<DrSyzygyFR>Ooookay.
15:55:32<quicksilver>mreh: as for your question the details depend on your reactive framework I'm sure.
15:55:41<DrSyzygyFR>So now it starts closing in on being time to think about a good distribution point for this package.
15:55:42<quicksilver>but you should have a way to refresh every tick
15:55:46<quicksilver>irrespective of input
15:55:48<gwern>mreh: if all the functions block until a keypress, then keypress implies running and vice versa; so we can infer a keypress from running
15:56:01<DrSyzygyFR>My own academic webpage? Google code? Hackage? Somewhere else?
15:56:06<DrSyzygyFR>Thoughts?
15:56:17<gwern>mreh: this is like the cogito or anthropic arguments; if something must be true for us to consider the proposition at all, then it is true
15:56:27<DrSyzygyFR>One thing that speaks against hackage might be the extreme domain specificity of this... (at least currently)
15:57:10<mreh>gwern, i understand
15:57:23<EvilTerran>DrSyzygyFR, what does it do?
15:57:29<mreh>so is there a serparate IO framework, like an IO stream
15:57:30<mreh>one I can read
15:58:12<quicksilver>you don't want to mess with IO directly if you're using a reactive thing.
15:58:16<quicksilver>you want ot use the facilities it gives you
15:58:23<quicksilver>otherwise you'll just break everything.
15:58:24<mreh>ill show you my code so far
15:58:28<mreh>ill paste it
15:58:44<MyCatVerbs>@where hpaste
15:58:45<lambdabot>http://hpaste.org/
15:58:59<mreh>yo
16:00:05<pejo>DrSyzygyFR, distribute it through hackage, have your own homepage for it somewhere and just point to hackage.
16:00:15<mreh>this should be enough for you to understand
16:00:16<mreh>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4248#a4248
16:01:04<quicksilver>mreh: oh, when you said reactive I thouhgt you meant 'Reactive'
16:01:12<quicksilver>it's an API for FRP written by conal.
16:01:22<mreh>:)
16:01:42<quicksilver>the answer to your question lies in how SOE works, I guess.
16:01:46<mreh>you assumed too much
16:01:47<quicksilver>I've never used the SOE event stuff.
16:02:02<DrSyzygyFR>EvilTerran: It computes gröbner bases for operads.
16:02:14<EvilTerran>DrSyzygyFR, ok, i have no idea what that means. ;)
16:02:17<DrSyzygyFR>Right now, I expect the audience to be no bigger than some 30-60 algebra and topology researchers.
16:02:20<mreh>i think i have a solution somewhere, ill peek in that
16:02:28<EvilTerran>DrSyzygyFR, there's already some pretty specialised stuff on hackage
16:02:51<ErhardtMundt>bye
16:04:12<pejo>DrSyzygyFR, even if it's a small audience it's really nice to be able to cabal install it.
16:05:41<dcoutts>DrSyzygyFR: 30-60 is a big audience :-)
16:09:31<dons>well done to eaton and tom hawkins for releasing Atom, http://www.reddit.com/r/programming/comments/8fukm/atom_is_a_dsl_in_haskell_for_designing_hard/
16:10:38<roconnor>oh
16:10:47<roconnor>so it has nothing to do with syndication
16:10:55<dons>that's right.
16:11:10<gwern>atom is a bad name
16:11:12<roconnor>damn
16:11:14<roconnor>:)
16:11:15<gwern>that was my first thought too
16:11:22<roconnor>I need a atom parser
16:11:29<gwern>roconnor: don't worry, we already have an atom lib
16:11:31<gwern>in that sense
16:11:33<roconnor>and I have no hydraulic trucks
16:11:39<roconnor>oh good
16:11:42<gwern>rss, iirc, handles both rss and atom
16:11:47<DrSyzygyFR>dcoutts: Point.
16:11:49<gwern>or was it feed that handled both?
16:12:02<dons>does take much for gwern to go off into the brambles :)
16:12:02<DrSyzygyFR>dcoutts: Especially given that I'll probably need to hand-hold almost everyone. :-P
16:12:09<dcoutts>:-)
16:12:18<roconnor>I need to rewrite Akregator in Haskell
16:12:23<gwern>ACTION is a Bear of Little Brain, and Long Words confuse me
16:12:34<roconnor>I should call it Krocodile
16:12:53<MyCatVerbs>ACTION pours hunny over gwern's head.
16:13:12<gwern>ACTION feebly reaches up, but drat these stubby arms
16:13:30<MyCatVerbs>I'm surprised that you don't just tilt yourself.
16:13:41<gwern>but then I should fall over
16:13:56<MyCatVerbs>We could get you a stool.
16:14:06<MyCatVerbs>Alternately, we could point at you and laugh. That's good too.
16:20:15<ksf>almost every kde program needs a rewrite.
16:21:14<roconnor>ksf: really?
16:21:24<roconnor>I find Akregator really really bad
16:21:24<gwern>ACTION amends that statement to make it even truer: almost every program needs a rewrite.
16:21:32<ksf>like konsole, which crashes on me every time i close it.
16:21:36<roconnor>The number of articles in a feed is often negative
16:21:53<gwern>roconnor: wow. so... it's sucking information out of you?
16:21:57<roconnor>ya
16:22:12<roconnor>ksf: crashing on close doesn't sound so bad from a user's stand point
16:22:27<roconnor>it is probably faster than traditional closing
16:22:50<ksf>works here... but i suspect it to lag badly behind the actual rss feeds, and khtml suckage is a whole story on its own.
16:23:29<ksf>somehow, khtml manages to be slower than firefox, and that isn't easy to do.
16:23:39<Berengal>KDE does have overall buggier programs than the gnome defaults I've found. However, they're also better, despite the bugs...
16:23:47<roconnor>we need an Hhtml
16:23:58<ksf>don't get me started on ktype's keyboard layout and lesson editors.
16:24:02<Berengal>Hmm... Haskell DE...
16:24:14<roconnor>HDE
16:24:24<Berengal>I'd join that project
16:24:33<ksf>that'd be the desktop monad.
16:24:45<roconnor>that is a lot of software ...
16:25:22<ksf>html engine and toolkit are important things to have, though.
16:25:44<Berengal>Speaking of monads, I find it awesome that a haskell program is nothing more than a value of IO a. You could import a bunch of them and sequence them if you wanted
16:26:02<roconnor>import?
16:26:10<Berengal>as in "import Foo"
16:26:15<roconnor>yep
16:26:30<gwern>Berengal: yeah but how often does anyone export their main for you to use?
16:26:31<roconnor>import Random
16:26:48<gnuvince>@index (=?_
16:26:48<lambdabot>bzzt
16:26:50<gnuvince>@index (=?)
16:26:50<lambdabot>bzzt
16:26:58<Berengal>gwern: True
16:28:30<Berengal>I still like the idea though...
16:29:22<quicksilver>I'm with berengal. The idea is nice.
16:29:37<quicksilver>You can even use 'withArgs' to change the command line args for them.
16:29:58<gwern>stdin/stdout might be tricky
16:30:53<Berengal>Might have to write a shell monad to handle all the handles and pipes...
16:30:59<ksf>hmmm... you can close both, I never tried that, but I think you could reopen them to different handles.
16:31:19<Berengal>I get getContents opens them to a new handle
16:31:20<ksf>don't listen to me.
16:31:49<ksf>you still have to have different processes for them to point to different places.
16:31:52<Berengal>Or at least, getContents >>= (\s -> getLine >>= (\s' -> putStrLn (s' ++ s))) throws an exception on getLine
16:31:54<Ferdirand>sequencing independant programs in a single process sure would be funny
16:32:07<Berengal>(But getContents continues to read afterwards if you catch it)
16:32:09<ksf>so forkOS'ing the mains would'nt be a bad idea.
16:37:39<DrSyzygyFR>Where can I find the recommended top level structure to put my package into?
16:38:23<dons>http://haskell.org/haskellwiki/Hierarchical_module_names
16:38:33<dons>out of date though. the current namespace of hackage is much much bigger
16:38:37<dons>there's about 50 categories now
16:38:59<DrSyzygyFR>dons: I think Algebra is suitable for this one though. :-P
16:39:03<DrSyzygyFR>How do I set it?
16:39:04<roconnor>I'm thinking I am never going to put anything in Data or Control ever again.
16:39:08<dons>Math.*
16:39:17<DrSyzygyFR>I need to make my source files and my Cabal file agree, right?
16:39:22<EvilTerran>Control.Data
16:39:24<DrSyzygyFR>module Math.Operad where (?)
16:39:25<EvilTerran>Data.Control? :P
16:39:29<roconnor>ahhhhhhh
16:40:23<ksf>Data.Maybe is such a misnomer, you import it for the monad... and monads usually are Control.*
16:40:50<copumpkin>what if you import it for maybe or fromMaybe
16:41:01<copumpkin>or even fromJust
16:41:14<uccus>hi guys! I want to put this somewhere on the wiki... which page would be most appropriate?
16:41:15<uccus>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4249
16:41:21<DrSyzygyFR>copumpkin: Such as I've done all over the place lately. :-P
16:42:23<cnwdup>@pl liftM3 (.)
16:42:23<lambdabot>liftM3 (.)
16:42:25<EvilTerran>uccus, that last comment confounds "error" and "fail"
16:42:35<cnwdup>Was there a special operator for that?
16:42:44<EvilTerran>?type liftM3 (.)
16:42:46<lambdabot>forall b c a (m :: * -> *). (Monad m) => m (b -> c) -> m (a -> b) -> m a -> m c
16:42:58<EvilTerran>?type (<=<)
16:43:00<lambdabot>forall b (m :: * -> *) c a. (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c
16:43:11<EvilTerran>derp
16:43:36<uccus>EvilTerran: well a pattern match failure is an error, right? shouldn't it? am I missing something? I thought it's a cool demonstration that errors are... erm... nevermind
16:44:08<EvilTerran>uccus, a pattern-match failure on the left of a <- results in an invocation of "fail" as defined by the monad, not "error"
16:44:29<EvilTerran>?undo do Just x <- foo; return x
16:44:30<lambdabot>foo >>= \ a -> case a of { Just x -> return x; _ -> fail ""}
16:44:55<monochrom>ACTION parodes Marx. "The history of programming language is defined by a struggle between two classes: control and data. Every development re-draws the boundary between them."
16:44:57<uccus>EvilTerran: :( got you
16:45:08<Berengal>Would it be possible to restrict do-notation that could fail to instances of MonadZero?
16:45:19<EvilTerran>Berengal, with -XNoImplicitPrelude, yes
16:45:20<DrSyzygyFR>ehhhhhh
16:45:30<DrSyzygyFR>How do I name my source files for this to work? *confused*
16:45:39<EvilTerran>Berengal, and you can even have do-notation with no <- be in Applicative instead of Monad
16:45:46<quicksilver>Math/Operad/Coolness.hs
16:45:49<EvilTerran>(with (>>) = (*>))
16:45:50<DrSyzygyFR>Ahhhh
16:45:57<quicksilver>contains module Math.Operad.Coolness
16:46:00<Berengal>EvilTerran: Hmm... awesome, maybe?
16:46:02<DrSyzygyFR>And the module Math.Operad?
16:46:11<EvilTerran>DrSyzygyFR, Math/Operad.(l)hs
16:46:11<DrSyzygyFR>Math/Operad.hs so no collission. fine
16:46:17<mmorrow>DrSyzygyFR: one naming scheme i like (for libraries that are logically a single unit, but have general applicability) is <Main-Category>.<Application/Library-Name>.<SubCategory>
16:46:26<EvilTerran>Berengal, indeed, there is potential for awesome there.
16:46:30<mmorrow>e.g. Language.Haskell.Exts.Syntax
16:46:41<uccus>so outside a monad if some value matches no equations what happens?
16:46:51<EvilTerran>uccus, then "error" is invoked
16:46:56<mmorrow>Math.LeetCalculator.Algebra.Ring
16:47:07<uccus>so is there any way to "catch" that error?
16:47:11<EvilTerran>(or equivalent; you end up with bottoms floating around, anyway)
16:47:14<EvilTerran>not in pure haskell
16:47:15<Berengal>EvilTerran: I'm assuming -XNoImplicitPrelude means you'll have to define your own Monad and MonadZero class though, and put fail in MonadZero instead?
16:47:22<EvilTerran>Berengal, yeah
16:47:36<EvilTerran>and import Prelude hiding (lots of things)
16:47:38<Berengal>The rest is done by the desuggaring?
16:47:45<uccus>or does it just mean that my program will collapse?
16:47:47<cnwdup>EvilTerran, thank you.
16:48:19<ksf>fail belongs into its own monad.
16:48:22<uccus>Berengal: the GHC spec says it will use whatever (>>=), (>>), fail are in scope no matter watch they are
16:48:28<EvilTerran>Berengal, as long as you give the right types to all the names the desugaring uses, it should work
16:48:43<EvilTerran>(and, of course, follow the semantics :P)
16:48:46<ksf>and monadic pattern failures can just call error directly if the monad does'nt implement fail.
16:49:04<uccus>same for fromIntegral but I don't think it's that easy to mess with Num
16:49:31<Berengal>ksf: The point is that fail is an ugly hack that shouldn't be in the Monad class. Anything that could potentially fail would therefore have to be a MonadZero, or you'd get a type error
16:50:01<uccus>so? should I put it on the wiki? I mean I am quite sure a lot of people would want to look under to 'do' notation hood
16:50:05<uccus>time and again
16:50:40<ksf>Berengal, that, or have a compile switch that inserts calls to errors in the right places.
16:50:59<ksf>it's an issue more or less orthogonal to top-level pattern match failures.
16:51:19<ksf>*calls to "error"
16:51:25<Berengal>ksf: Why would we want to throw in undefined values when we could have compile time checking?
16:52:03<ksf>because i might not want to have it.
16:52:23<ksf>...i'm not compiling with pattern match warnings and -werror all the time, either.
16:52:29<monochrom>static-checking-phobia
16:53:16<ksf>that is, I don't want to have any different outside behaviour, just fail out of the Monad class.
16:53:43<Berengal>well, error drops you all the way out to the outer IO monad...
16:54:02<DrSyzygyFR>dons: HackageDB still tells me that my top-level path name is unallocated: Math.
16:54:03<ksf>...so does Monad IO's fail.
16:54:08<ksf>...as it calls error.
16:54:11<ksf>most fail's do.
16:54:21<quicksilver>in my version of truth, you can't catch error even in the IO monad.
16:54:28<quicksilver>so it crashes the program
16:54:35<quicksilver>it doesn't go to the outer IO monad.
16:54:50<Berengal>The Maybe monad has a meaningful failure, so does the list monad. The IO monad, Reader, State... not so
16:55:05<uccus>I wonder what should we call that class with just fail... Fallible? Gullible? Refutable?
16:55:12<Berengal>MonadFail?
16:55:21<uccus>that's ... mundane
16:55:22<ksf>yeah. that's why the former can implement fail, and the rest can just crash and forget about fail.
16:55:40<quicksilver>Berengal: actually the IO monad does have a meaningful fail.
16:55:51<quicksilver>The IO monad officially and importantly has catchable exceptions.
16:55:54<ksf>"Enterprise"
16:55:56<quicksilver>that's a perfectly fine file.
16:55:56<monochrom>Human <-- name for the class with just fail.
16:56:10<quicksilver>it's the pure 'error' which shouldn't be catchable.
16:56:33<Berengal>Yeah, okay, IO has a meaningful fail
16:56:40<Berengal>Which is in fact an exception, I just checked...
16:56:43<mopped>Is there an 'infinity' in haskell? like an identity element for minimum?
16:56:54<monochrom>No.
16:57:08<Berengal>mopped: There is for bounded types
16:57:25<dons>DrSyzygyFR: that's ok.
16:57:29<vixey>mopped: you can define it
16:57:32<uccus>well.. this conversation would be over if meaningful fails where abandant
16:57:34<vixey>data N = Z | S N
16:57:35<Berengal>> let minimum' = foldl' min maxBound in minimum' []
16:57:36<lambdabot> ()
16:57:39<vixey>infinity = S infinity
16:58:21<wjt>I wish there were a Natural type
16:58:31<vixey>wjt: data N = Z | S N
16:58:35<vixey>I give you it
16:58:40<uccus>what about the package nat?
16:58:44<wjt>a newtype Natural = MkNatural Integer i mean
16:59:13<Berengal>How would the Num instance for Natural look?
16:59:16<wjt>it makes me sad that I wind up using signed Integers when I don't really mean to, but I don't think depending on an extra library is sensible
16:59:20<wjt>Berengal: truncated
16:59:22<Berengal>How would you implement negate?
16:59:34<wjt>but it's a fair argument.
17:00:35<monochrom>We widely agree that Num is unsatisfactory. We just disagree on what is satisfactory.
17:00:37<Berengal>Natural just isn't a number the way Haskell defines it
17:01:03<uccus>what about the package on hackage called nat?
17:01:06<uccus>?
17:01:10<dons>slides on galois' experience using Haskell over the past decade, http://www.galois.com/blog/2009/04/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galois/ enjoy!
17:01:18<bogner>anyone around who makes debian packages from cabal packages? the instructions on the wiki seem slightly broken
17:01:32<dons>bogner: ask on the debian-haskell list
17:02:03<bogner>thanks dons
17:02:28<mmorrow>data N a where Z :: N (N ()); S :: N (N n) -> N (N (N n)); Inf :: N ()
17:03:24<copumpkin>zomg a mmorrow
17:03:56<mmorrow>omzg
17:08:40<BONUS>dons: was the talk taped?
17:08:41<DrSyzygyFR>Woot! I'm on hackage!
17:08:57<dons>BONUS: nope.
17:10:06<copumpkin>DrSyzygyFR: nice!
17:10:16<gwern>mm. it's too bad you can't profile a binary and have multiple threads
17:10:49<gwern>that'd make showing memory leaks easier, because gitit forkIOs requests; so I could do -N4 and get 4x request thoroughput, presumably
17:11:53<dons>gwern: i heard a rumour that works in ghc 6.10.x
17:12:19<gwern>dons: no, I just tried
17:12:51<gwern>6.10.2, that is
17:13:24<dons>$ ghc -O2 -threaded -prof A.hs --make
17:13:24<dons>Linking A ...
17:13:24<dons>$ time ./A +RTS -p
17:13:24<dons>"hello"
17:13:25<dons>./A +RTS -p 0.00s user 0.00s system 47% cpu 0.007 total
17:13:31<BONUS>cool slides. it's just awesome how the combination of the type system, purity, and higher-order functions works so well to achieve robust applications and such a high-level of thinking
17:13:39<dons>gwern: 6.102.
17:13:54<dons>BONUS: :) excellent. that's what I hoped to convey.
17:15:02<gwern>6.102? man where am I gonna get that
17:15:13<gwern>dons: ./A +RTS -p -N4 -RTS works for you?
17:15:46<dons>ah no. that does not work. using the threaded runtime + prof only works with -N1
17:15:54<goalieca2>> 5!
17:15:55<gwern>yes, that's what I'm complaining about
17:15:55<lambdabot> <no location info>: parse error on input `;'
17:16:09<dons>right. but you can use the threaded rts
17:16:16<dons>so that's better than in 6.8.x
17:16:34<goalieca2>> multiply [1..5]
17:16:35<lambdabot> Not in scope: `multiply'
17:16:37<gwern>yeah, but what good is that? about all that does is avoid having to recompile
17:16:49<goalieca2>> foldl (*) [1..5]
17:16:50<dons>hmm?
17:16:51<lambdabot> Overlapping instances for Show ([[t]] -> [t])
17:16:51<lambdabot> arising from a use...
17:16:55<goalieca2>> foldl (*) [1..5] 1
17:16:57<lambdabot> No instance for (Num [t])
17:16:57<lambdabot> arising from a use of `*' at <interact...
17:17:29<dons>gwern: i think the burden is on you explaining why that isn't useful?
17:17:59<BONUS>haha cool picture at the end. use haskell, finish soon, take left over time for vacation
17:18:06<dons>:)
17:18:19<dons>well, it was more that galois was some kind of oasis in the vast ocean :)
17:18:28<dons>but vacation is also good
17:19:06<Berengal>ACTION wishes he could use Haskell at work, or even python, but no... Java is the One Language to Rule Them All :(
17:20:31<monochrom>One >>= to bind them all. In the dark lands of Monads.
17:21:27<gwern>@quote land.*of
17:21:27<lambdabot>ghc says: jump island out of range
17:21:31<gwern>@quote land.*of
17:21:31<lambdabot>ghc says: jump island out of range
17:21:40<gwern>bah. I was sure we had a mordor quote in there
17:21:52<gwern>@quote bind.*them.*all
17:21:52<lambdabot>No quotes match. Maybe you made a typo?
17:21:56<gwern>:(
17:22:12<gwern>monochrom: come up with a better full version and @remember it stat!
17:23:00<vixey>@quote bind
17:23:01<lambdabot>ghc says: Implicit parameters escape from the monomorphic top-level binding(s)
17:23:02<vixey>@quote bind
17:23:02<lambdabot>ghc says: bindings for unlifted types aren't allowed
17:23:03<monochrom>The broken one is @quote actually. It's dumb.
17:23:03<vixey>@quote bind
17:23:03<lambdabot>ghc says: Implicit-parameter bindings illegal in a parallel list comprehension
17:23:04<vixey>@quote bind
17:23:05<lambdabot>ghc says: bindings for unlifted types aren't allowed
17:23:05<vixey>@quote bind
17:23:05<lambdabot>ghc says: Implicit parameters escape from the monomorphic top-level binding(s)
17:23:14<vixey>ghc shouldn't be in there...
17:23:43<gwern>dons: does galois just use cabal-install as a in-house dev's tool, or are actual customers using it?
17:24:36<gwern>dons: also, how does the 'line/column for errors' thing work? is that just a convention, devs manually counting them and inserting them into error's string arg?
17:24:59<BONUS>hmm what if you
17:25:12<BONUS>yeah, what if some lines upward push some lines with error downwards
17:25:39<gwern>BONUS: there are tricks to avoid manual things. like I uploaded a prelude replacement package which abused CPP to determine line numbers for non-total functions like head
17:25:56<BONUS>ah co0l
17:26:31<gwern>(interesting code. fortunately I rarely run into exceptions from prelude functions, or I know where they are)
17:27:31<BONUS>i only sometimes get tripped up by div, but i've gotten used to checking for 0 now
17:28:44<dons>gwern: hah, no. we use tools :)
17:29:05<dons>"manually counting line/columns" is a bit ridiculous, don't you think? :)
17:29:07<gwern>well, I sort of assumed. haskell-src-exts based parsing perhaps?
17:29:24<dons>we've a few preprocessors lying around. i think they're cpp-based
17:29:44<gwern>(I guess it could be a parser, which gets called as a preprocessors via the ghc -Fgmc trick)
17:37:01<Berengal>I've got the feeling most Haskell code is BSD, am I right?
17:37:23<Saizan>it seems like that
17:37:41<Berengal>Are there any major GPLed Haskell projects at all?
17:37:47<bremner>except that using n+k patterns
17:37:55<McManiaC>is there a way to use the return of a io function like "a -> IO b" in a function that takes one arguemnt of type b without having to write an extra line like "f a >>= \b -> g b" ?
17:38:02<gwern>Berengal: what, like darcs or yi?
17:38:05<Saizan>anyone used the libsvm bindings?
17:38:06<dons>Berengal: ~77% on hackage
17:38:12<dons>darcs is GPLd
17:38:15<Cale>McManiaC: You can just write f a >>= g
17:38:16<McManiaC>or do { b <- f a; return g b }
17:38:25<Berengal>Interesting...
17:38:36<Berengal>dons: You got stats for GPL as well?
17:38:36<dons>apps are more likely to be GPLd than libraries
17:38:36<gwern>not really. small languages want to be bsd-biased
17:38:38<Cale>McManiaC: but you must use either do-notation, bind, or one of the other combinators to run the IO action
17:38:48<gwern>it's the big languages that need gpl protection
17:38:54<dons>16% GPL
17:39:02<McManiaC>Cale: bind?
17:39:05<Cale>>>=
17:39:08<McManiaC>ok
17:39:11<McManiaC>pity
17:39:13<McManiaC>:)
17:39:14<Cale>g =<< f a might be a nice way
17:39:24<Cale>McManiaC: If you just pass the IO action as a parameter, it will mean that the *action* is passed as a parameter, not its result
17:39:26<gwern>dons: that's a good point too. executables aren't linked into stuff in the same way libraries are, so people don't care nearly so much whether darcs is gpl or bsd
17:39:41<Cale>McManiaC: This seems like it might be an inconvenience, but it has its advantages as well.
17:39:42<dons>right
17:39:54<dons>though cabal makes it more likely to use apps as libraries
17:40:12<gwern>you mean the library/executable style is encouraged more?
17:40:16<dons>yep
17:40:31<dcoutts>aye, it's common to take an app, expose all the modules as a lib and make the exe dep on the lib
17:40:33<dons>its trivial to turn a cabalised app into a library
17:40:38<dons>unlike in almost every other build system
17:40:38<Cale>McManiaC: In particular, you can write functions which take IO actions as parameters, and make use of them when and how they need to, like custom control structures.
17:40:45<dcoutts>then refactor 'til the internal modules export a nicer API
17:40:47<gwern>true. how would you even turn a autotools executable into a library?
17:41:10<McManiaC>Cale: but if you want to use "if" with the result of "a -> IO Bool" for example you have to add another "myTest <- runTest foobar" line before the if block in a do-notation?
17:41:13<dcoutts>dons, gwern: needs support for that cabal feature to let an exe dep on the lib in the same package
17:41:18<Cale>McManiaC: Yeah.
17:41:20<bremner>heh, don't get too proud until you can make shared libs :-)
17:41:30<Cale>McManiaC: Or of course, you can write your own if :)
17:41:34<dcoutts>dons, gwern: for it to be really convenient. otherwise it builds everything twice
17:41:37<dons>IHG task, iirc
17:41:42<Cale>McManiaC: There are 'when' and 'unless' in the Control.Monad library
17:41:46<Cale>:t when
17:41:47<dcoutts>bremner: we're working on it
17:41:48<gwern>bremner: the power of shared libs is as nothing compared to the power of the force!
17:41:48<lambdabot>forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
17:41:57<Cale>er, well, that's a little different
17:42:00<McManiaC>yup i already used them
17:42:13<McManiaC>but u still have to write that line
17:42:17<Cale>But it wouldn't be hard to write something of that sort which took an m Bool
17:42:25<dcoutts>bremner: I'm currently updating the new ghc build system to handle shared libs (which had partial support in the old build system)
17:42:25<Cale>If you have to do it a lot.
17:42:31<McManiaC>ok
17:42:49<grapey>Mollie_C_xo@live.co.uk
17:43:06<grapey>smellie-x@hotmail.com
17:43:12<Cale>grapey: ?
17:43:23<Cale>what?
17:43:25<gwern>spam
17:43:29<bremner>spam?
17:43:35<ali_clark>who benefits from that?
17:43:43<mauke>spammers
17:43:49<Raevel>girls? though maybe i'll pass on chatting with smellie-x
17:43:50<McManiaC>whenM test run = do { t <- test ; when t run }
17:43:53<Cale>Is he baiting spammers into taking those email addresses?
17:43:55<bremner>dcoutts: cool.
17:44:07<McManiaC>or just liftM when?
17:44:07<McManiaC>^^
17:44:19<Cale>McManiaC: yeah, that works there.
17:45:01<McManiaC>@type liftM2 when
17:45:02<lambdabot>forall (m :: * -> *) (m1 :: * -> *). (Monad m1, Monad m) => m1 Bool -> m1 (m ()) -> m1 (m ())
17:45:21<McManiaC>@type (join.liftM2) when
17:45:22<lambdabot> Couldn't match expected type `Bool' against inferred type `m ()'
17:45:22<lambdabot> Expected type: Bool -> Bool -> r
17:45:22<lambdabot> Inferred type: Bool -> m () -> m ()
17:45:26<McManiaC>:o
17:47:23<ali_clark>I got another fun beginner question for you guys...
17:47:31<ali_clark>fun1 :: (Num a) => a -> a; fun1 = (+ 1)
17:47:37<ali_clark>fun2 = ((+ 1) :: (Num a) => a -> a)
17:47:57<McManiaC>@type join $ liftM2 when
17:47:57<ali_clark>the second comes out with Integer -> Integer , is that expected?
17:47:58<lambdabot> Couldn't match expected type `Bool' against inferred type `m ()'
17:47:58<lambdabot> Expected type: m1 Bool -> m1 Bool -> a
17:47:58<lambdabot> Inferred type: m1 Bool -> m1 (m ()) -> m1 (m ())
17:48:14<gwern>ali_clark: sure. 1 defaults to Integer
17:48:23<Berengal>Actually, it's the MR
17:48:30<gwern>hush you
17:48:36<ali_clark>gwern: then how come the first gets away with it?
17:48:51<Berengal>(+1) is polymorphic, but when it gets bound to fun2 the MR defaults it
17:49:09<Berengal>fun1 isn't defaulted because it has a type signature
17:50:15<Cale>ali_clark: The monomorphism restriction means that pattern bindings without explicit type signatures must not be typeclass polymorphic.
17:50:28<Cale>ali_clark: fun1 has an explicit type signature, so the MR doesn't apply
17:50:41<Cale>ali_clark: Normally I just turn the MR off since it's a nuisance.
17:51:17<ali_clark>okay thanks, I guess I can see how they're not really the same now
17:51:28<Cale>(though, having to type {-# LANGUAGE NoMonomorphismRestriction #-} is also a bit of a nuisance)
17:51:37<Berengal>ACTION keeps the MR on unless it's severely hampering his style. Adding type signatures is good practice anyway
17:52:38<ali_clark>but it is a bit weird, even : fun3 = let { f' = (+ 1); f' :: (Num a) => a -> a; } in f' comes out as Integer -> Integer
17:53:06<romildo>Hi.
17:53:36<seliopou>monomorphism restriction?
17:53:36<Berengal>ali_clark: It's all because fun3 is interpreted as a value, and values can't be polymorphic, even when they're functions...
17:54:01<romildo>How do I get an editable CellRendererToggle in a TreeView in gtk2hs?
17:57:11<ali_clark>I guess you guys must have thought this through alot already, I'll go read up on MR :)
17:57:28<vixey>ali_clark: best thing is to just turn off MR
17:57:42<Berengal>Or add type signatures...
17:57:56<vixey>that's not also the best :p
17:58:07<Berengal>It's good enough most of the time
17:58:29<Cale>ali_clark: note that if it has an explicit parameter, it also avoids the MR
17:59:13<skorpan>i've cabal installed parsec on my user account, but how do i make ghc recognize it without writing my own cabal file?
17:59:15<Cale>ali_clark: The MR is both overzealous in what it applies to, and should not have been treated as a compile error (a warning would have done the same job in a less irritating way)
17:59:35<dcoutts>skorpan: it'll be available automatically
17:59:46<Berengal>Hackage needs an Acme hierarchy...
17:59:50<skorpan>dcoutts: ghc --make can't find it though
18:00:01<skorpan>i know it's installed, because cabal tells me so
18:00:03<monochrom>http://www.haskell.org/haskellwiki/Monomorphism_restriction
18:00:07<dcoutts>skorpan: then it's not properly registered
18:00:13<dcoutts>skorpan: ghc-pkg list parsec
18:00:33<skorpan>dcoutts: yep, it's there alright
18:00:35<Cale>ali_clark: Basically, it's there to prevent performance problems when something like myBigNumber = product [1..100000] gets re-evaluated every time it's used because it's polymorphic.
18:00:40<skorpan>both globally and on my user account
18:00:54<dcoutts>skorpan: ok, does ghci -package parsec work?
18:01:10<skorpan>hm... no. :|
18:01:18<skorpan>i get "couldn't find module Parsec"
18:01:19<skorpan>weird
18:01:30<dcoutts>skorpan: there is no module Parsec
18:01:36<monochrom>Heh
18:01:41<skorpan>then this documentation i'm reading is way old i guess
18:01:46<skorpan>2001, wow
18:01:49<monochrom>Yes it is.
18:01:49<uccus>anyone with a bit of time here: I have a really weird question. is ((->) a) an instance of Applicative? is pure = const here?
18:01:51<dcoutts>skorpan: sounds likely
18:02:09<mauke>uccus: yes
18:02:10<Cale>uccus: yes
18:02:16<mauke>uccus: it's not very weird :-)
18:02:20<uccus>hehe thanks guys you are the best
18:02:23<ali_clark>Cale: thanks i'd say that makes sense
18:02:26<dcoutts>skorpan: ghc-pkg field parsec exposed-modules
18:02:30<vixey>> pure () :: ()
18:02:31<lambdabot> Ambiguous occurrence `pure'
18:02:31<lambdabot> It could refer to either `Control.Appl...
18:02:32<Berengal>uccus: ((->) a) is even a monad
18:02:35<vixey>> pure () () :: ()
18:02:36<lambdabot> Ambiguous occurrence `pure'
18:02:36<lambdabot> It could refer to either `Control.Appl...
18:02:36<Cale>If you know the SK calculus, the implementations of pure and <*> should be familiar
18:02:56<monochrom>like, K and S respective? :)
18:03:00<Cale>yes
18:03:17<uccus>yes I have figured out that it is a functor and an applicative so I guess monads are the next natural step. pure is const, <*> is ap. id is id from category
18:03:28<uccus>id is I
18:03:56<Cale>> (do x <- id; y <- reverse; z <- map toUpper) "hello"
18:03:57<lambdabot> <no location info>:
18:03:57<lambdabot> The last statement in a 'do' construct must be an ...
18:04:01<Cale>> (do x <- id; y <- reverse; z <- map toUpper; return (x,y,z)) "hello"
18:04:03<lambdabot> ("hello","olleh","HELLO")
18:04:31<Cale>^^ an example of this monad :)
18:04:47<Cale>> sequence [id, (+2), (*2), (^2), (2^)] 5
18:04:48<lambdabot> [5,7,10,25,32]
18:05:14<Cale>> ap zip tail [1..5]
18:05:15<skorpan>is there any up-to-date tutorial on how parsec works? the old 2001 tutorial seemed so promising...
18:05:15<lambdabot> [(1,2),(2,3),(3,4),(4,5)]
18:05:18<uccus>ok ok guys
18:05:49<Berengal>skorpan: RWH has a chapter on parsec
18:06:08<monochrom>Module names are about the only major difference.
18:06:19<skorpan>thanks
18:06:44<uccus>sheesh
18:06:47<uccus>:D
18:06:58<monochrom>A few of the functions are moved to from the Combinators module the Prim module, but you won't easily notice that.
18:07:29<monochrom>The haddock pages of 3.x.x.x are fairly complete.
18:17:45<Berengal>Acme.CurrentTime: Provides a pure way to get the current day, provided the package is kept up to date
18:18:00<monochrom>ACTION tries Berengal's "fix error" in ghci :)
18:18:20<monochrom>hahahahaha
18:18:24<mauke>@quote hint.*beg
18:18:24<lambdabot>mauke says: a hint to beginners: typing 'fix error' in ghci does not have the intended effect
18:18:45<monochrom>Is that a real module?
18:18:48<Berengal>Hehe. Rather the opposite
18:19:11<Berengal>monochrom: No. I'm just looking through CPAN and wondering if it might be fun to port some to hackage
18:19:19<mauke>http://search.cpan.org/~jesse/Acme-Current-Forever-1.00/lib/Acme/Current.pm
18:19:51<monochrom>haha
18:21:36<dons>Berengal: that's a good idea.
18:22:06<dons>Berengal: also http://www.reddit.com/r/haskell_proposals
18:24:24<gnuvince>dons: are your slides for the London Haskell User Group online yet?
18:24:47<dons>yes.
18:24:58<dons>http://www.galois.com/blog/2009/04/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galois/
18:25:07<gnuvince>Thanks!
18:25:40<Hunner>Ooo, the FP conference is this Thursday
18:26:16<Salve>**Looking for my shotgun**
18:26:30<Salve>I think i've been playing to much left4dead
18:31:24<gnuvince>dons: what does the expression "2 rungs above performance spec" mean?
18:32:01<dons>application-specific requirements. we were two ratings higher than required.
18:32:51<dons>i.e. perf. not an issue.
18:33:53<gnuvince>ok
18:39:22<pumpkin_>that point in your slides about BSD for static linking is interesting
18:41:43<edwardk>dons: awesome talk
18:42:02<pumpkin_>we need videos!
18:42:03<pumpkin_>:)
18:42:10<burp_>ghc for opensolaris, anyone tried it?
18:42:11<pumpkin_>the slides are good
18:42:13<gnuvince>dons: hope you don't mind: http://www.reddit.com/r/programming/comments/8fw51/talk_by_reddits_own_dons_presented_at_%CE%BBondon_hug/
18:42:33<pumpkin_>edwardk: I made the fold into a ContraFunctor just for the fun of it
18:43:02<edwardk>pumpkin_: fold?
18:43:21<edwardk>pumpkin_: i've since lost context ;)
18:43:30<pumpkin_>I've been playing with fold combinators like Taejo described in his blog a while back
18:43:44<edwardk>which one in particular?
18:43:45<pumpkin_>http://github.com/pumpkin/folds/blob/49a8fc30c57567067dce5fcf0c31bc585ef28c29/Fold.hs
18:43:50<Hunner>burp_: I've been having a horrible time trying to get ghc on sol10, but haven't tried opensol yet
18:44:01<pumpkin_>http://squing.blogspot.com/2008/11/beautiful-folding.html is the original post
18:44:18<edwardk>ah an explicitly existential fold
18:44:31<pumpkin_>my code turned ugly because I decided to make a Num instance for it
18:44:41<burp_>Hunner, must be similar there then :(
18:45:07<vixey>> naiveMean xs = sum xs / fromIntegral (length xs)
18:45:08<lambdabot> <no location info>: parse error on input `='
18:45:11<vixey>why don't you call that one uglyMean :p
18:45:18<pumpkin_>lol
18:45:44<pumpkin_>it's not a good mean either, even if you could do it efficiently
18:45:48<pumpkin_>but it's a fun example
18:45:50<edwardk>pumpkinL i have a library i was working on after msfp that includes a generic version of that
18:45:59<edwardk>i don't know that i ever posted it
18:46:07<pumpkin_>ooh
18:46:09<pumpkin_>generic how?
18:46:10<edwardk>(that generalizes to any functor)
18:46:19<Taejo>pumpkin: you could have fromInteger = pure
18:46:25<vixey>ACTION wants to know how to fuse foldr f [] . foldr g [] without build
18:46:30<pumpkin_>Taejo: true, not sure why I didn't put that in
18:46:47<wli>@type uncurry (/) . foldr (\x (n, s) -> (n + 1, s + x)) (0, 0)
18:46:48<lambdabot>forall a. (Fractional a) => [a] -> a
18:47:29<pumpkin_>I did this using a GADT before
18:47:40<pumpkin_>but the GADT-ness of it prevented it from fusing nicely
18:47:53<pumpkin_>so I moved back to the function one
18:47:54<edwardk>vixey: i was going towards implicit cata/build fusion by transforming the functor into build form. i'd had a nice few hour discussion with tarmo uustalu about it and went pretty deep in that space and a few days later wandered off and looked at something else shiny ;)
18:48:14<pumpkin_>edwardk: release it! I'm hungry :D
18:48:38<edwardk>pumpkin_: heh, i'll see if i can dig it up
18:49:12<edwardk>i've been chewing through machines like popcorn over the last 6 months or so, so i'm not quite sure where all my little code odds and ends are at the moment.
18:49:30<pumpkin_>Taejo: my next step is to play with the same idea in TH
18:50:00<skorpan>@src ErrM
18:50:00<lambdabot>Source not found. I feel much better now.
18:50:03<skorpan>@hoogle Errm
18:50:04<lambdabot>No results found
18:50:07<Taejo>pumpkin: I'm not sure how you get there from here
18:50:08<skorpan>what is ErrM? :P
18:50:08<kadaver>what is the name of a good C mp3 lib, i always forget
18:50:25<kadaver>@src flip
18:50:26<lambdabot>flip f x y = f y x
18:50:33<orbitz>kadaver: search freshmeat
18:50:42<kadaver>@src zipWith
18:50:43<lambdabot>zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
18:50:43<lambdabot>zipWith _ _ _ = []
18:50:48<skorpan>hm, nvm
18:51:09<pumpkin_>the ideal would be BSP's ghc plugins
18:51:09<pumpkin_>but it's not ready yet
18:51:09<pumpkin_>Taejo: oh, I wouldn't be able to reuse much code, but the same basic idea, using a list of known folds
18:51:10<edwardk>pumpkin: contrafold is pretty gratuitous, if you're a bifunctor that is contravariant in your first argument and covariant in your second, you're probably a Category, which expresses that much more intuitively.
18:51:36<edwardk>pumpkin: though i didn't look in depth to make sure it would work
18:51:46<pumpkin_>edwardk: oh, it was mostly as a joke :P I just saw that after was a nice fmap
18:51:55<pumpkin_>and asked about a co-fmap :P so people pointed me to ContraFunctor and I used it
18:52:08<ehird>What is the appropriate data structure to use for a very efficient 2D array?
18:52:18<Botje>how spare is it?
18:52:23<pumpkin_>anyway, gotta go :)
18:52:25<pumpkin_>bbl
18:53:12<ehird>Botje: Well, uh, it covers the whole range of signed platform ints, and only a miniscule amount of that, around the center, will generally be used
18:53:15<ehird>So: Very.
18:53:21<ehird>Sparse I assume you mean
18:53:31<Botje>then you probably want a Data.Map or IntMap
18:53:39<ehird>Botje: What's an IntMap?
18:53:46<Botje>Map specialized for ints
18:53:49<ehird>Ah
18:53:55<ehird>Botje: So a nested IntMap or a Map on (Int,Int)
18:54:01<Botje>ehh
18:54:09<ehird>Still, I'm looking for mega speed for lookups here.
18:54:14<ehird>Run in a very tight loop.
18:54:26<Botje>IntMap only assuming you think it's worthwhile stuffing your coordinates in one Int
18:54:29<ehird>A hash table of some sort would probably work best...
18:54:30<Botje>otherwise, go for Map
18:54:36<ehird>Botje: Impossible; it's (Int,Int)
18:54:50<Botje>you can combine two ints into one
18:54:59<Botje>if you're only going to use a miniscule amount
18:55:12<ehird>Botje: In practice.
18:55:16<ehird>Theoretically, any amount can be used.
18:55:18<ehird>It's an interpreter.
18:55:21<Botje>ah.
18:55:25<Botje>then just go for a Map
18:55:28<ehird>Kay. Thanks.
18:55:43<Botje>Hash tables are available too, but if you're going to add to it you're boned
18:56:27<ehird>mm
18:56:41<ehird>Botje: Maybe I should use an unboxed (# Int, Int #) tuple?
18:56:49<Botje>yeah
18:56:56<Botje>I believe there's a strict-pair package on hackage
18:57:02<wli>Well, you're best off rolling a flexible array by hand that avoids using arrays so large that the GC's lack of card marking kills you.
18:57:04<edwardk>Data.HashTable should have some kind of {-# DEPRECATED #-} flag or something to scare people away
18:57:15<Botje>Data.Strict.Tuble
18:57:17<Botje>*Typle, even
18:57:20<Botje>*TUPLE
18:57:24<Botje>ACTION stares at his keyboard
18:57:29<Botje>always trying to sabotage me
18:57:31<edwardk>botje: there are several, depending on how strict you want to me
18:57:44<edwardk>adaptive-containers has one that even unboxes
18:57:52<ehird>Botje: That's not unboxed.
18:58:04<ehird>(# !Int, !Int #) would probably be the most raw thing that fits my purposes.
18:58:11<Botje>oh.
18:58:12<eu-prleu-peupeu>is there any ffi to python ?
18:58:20<Botje>It's strict, not unboxed, yes.
18:58:22<wli>AIUI the library hash table does not avoid taking hte huge hit from the GC on that front.
18:58:23<Botje>sorry :)
18:58:27<ehird>:)
18:58:45<c_wraith>eu-prleu-peupeu: only through C. And that sounds like a real pain.
18:58:58<eu-prleu-peupeu>c_wraith: indeed :/
18:59:14<ehird>Hmm...
18:59:19<eu-prleu-peupeu>i guess ill have to endure it :/
18:59:19<ehird>What is needed for (# !Int, !Int #)?
18:59:24<ehird>MagicHash, BangPatterns doesn't work
18:59:27<ehird>I get a parse error on !
18:59:44<edwardk>ehird: the ! isn't legal there
18:59:45<Saizan>you can't have ! in types like that.
18:59:47<Valodim>aah, that new wiki logo is much better
18:59:57<edwardk>ehird: you can use (# Int#, Int# #)
19:00:08<ehird>edwardk: Ah
19:00:14<ehird>And then make a strict constructor?
19:00:28<edwardk>but you might have a better time just defining, data IntPair = IntPair {-# UNPACK #-} !Int {-# UNPACK #-} !Int
19:00:30<edwardk>and using that
19:00:30<ehird>edwardk: OTOH, that makes doing any maths on the coordinate a real pain.
19:00:32<ehird>ah
19:00:33<Saizan>data IntPair = IntPair {-# UNPACK #-} !Int {-# UNPACK #-} !Iint
19:00:33<ehird>thanks
19:01:23<Saizan>typing {-# on an it keyboard is a PITA
19:01:31<edwardk>you can even omit the {-# UNPACK #-} -- and just rely on -funbox-strict-fields
19:01:38<edwardk>saizan: heh
19:01:38<ehird>edwardk: is that wise, though?
19:01:51<edwardk>ehird: not terribly, i like to keep it in to be precise
19:02:03<ehird>how does that work with record syntax?
19:02:11<ehird>{ {-# UNPACK #-} x :: !Int,
19:02:12<ehird>?
19:02:27<edwardk>ehird: Foo { x :: {-# UNPACK #-} !Int, ...
19:02:34<ehird>thanks
19:06:10<ehird>data Point = Point { x :: {-# UNPACK #-} !Int
19:06:10<ehird> , y :: {-# UNPACK #-} !Int }
19:06:14<ehird>is what I want for
19:06:16<ehird>with point !(!x,!y) = Point { x = x, y = y }
19:06:21<ehird>*went
19:07:16<edwardk>have any more !'s you want to throw in there? =)
19:07:27<ehird>edwardk: Yes!!!!!!!!!!!!!
19:07:36<edwardk>i the (x,y) is strict you don't need one around it
19:07:56<ehird>I don't need any, the fields are strict :-)
19:08:06<edwardk>thats where i was going next =)
19:10:35<ehird>point (x,y) *will* always be inlined... right?
19:10:47<ehird>w/ -O2
19:10:53<edwardk>paranoid much? =)
19:11:19<ehird>edwardk: My performance competitors include a guy whose code is C littered with branch prediction stuff and _posix_fadvise.
19:11:26<edwardk>hahahaha
19:11:30<edwardk>what are you doing?
19:11:58<ehird>Writing a http://esolangs.org/wiki/Befunge -98 interpreter: http://cpansearch.perl.org/src/JQUELIN/Language-Befunge-4.10/lib/Language/Befunge/doc/bf98-specs.html
19:12:08<p_l>ehird: is he also manually mainpulating cache? :D
19:12:13<kadaver>what does unpack do?
19:12:17<edwardk>the competition is so fierce, because the stakes are so small
19:12:20<ehird>Possibly the most bloated, extensible (it has modules...) esoteric language on the planet
19:12:41<ehird>kadaver: puts the ints directly in, instead of via a pointer, I think
19:12:43<Berengal>ehird: There's Java...
19:12:50<edwardk>kadaver: normally an Int is represented by a thunk in memory that can be forced to obtain the value. unpacking it forces it when you go to stick it in the field and then stuffs a real machine integer into the thunk directly
19:12:58<ehird>Berengal: *groan*
19:13:10<Berengal>I know, it was low...
19:14:04<wli>Am I the only one who finds th "esoteric languages" unworthy of any attention/notice/etc. whatsoever?
19:14:16<edwardk>kadaver: data Foo = Foo {-# UNPACK #-} !Int {-# UNPACK #-} !Double -- is a single constructor wrapped around an integer and double directly. while data Foo = Foo Int Double -- is a Foo tag wrapped around a pair of pointers, one to a thunk that evaluates to an Int and one that evaluates to a Double
19:14:22<edwardk>wli: no
19:14:34<Botje>some of them are worth thinking about/over
19:14:39<ehird>wli: PROGRAMMING IS SERIOUS BUSINESS
19:14:50<ehird>Fun is strictly forbidden, lest we write unmaintainable code!
19:14:54<lament>the stuff edwardk does certainly seems esoteric to me
19:14:54<dschoepe>wli: I think they are useful as exercises for compiler/interpreter writing
19:15:03<ehird>Most of all, theoretical models are NEVER helpful to discover new concepts.
19:15:04<dschoepe>Or simply entertainment
19:16:40<edwardk>wli: i liked jot as a Goedel numbering, but I find most esolangs tedious
19:17:18<vixey>seen one seen 99% of them
19:17:19<wli>ACTION suggests that there are better languages for exercises in compiler/interpreter writing.
19:17:31<lament>the one where you can assign numbers to different numbers and control flow is done by line numbering is pretty clever
19:17:38<ehird>wli: have you considered it's a fun timekiller?
19:17:54<edwardk>wli: sure, any language with a sufficiently complicated module system, for instance ;)
19:18:03<lament>ehird: do you remember the name of the one i'm talking about?
19:18:11<edwardk>ehird: yes i've killed many a fun time doing that
19:18:12<kadaver>can haskell call dll?
19:18:12<ehird>lament: Forte.
19:18:21<ehird>lament: http://esolangs.org/wiki/Forte
19:18:30<edwardk>@faq can haskell call dll?
19:18:30<lambdabot>The answer is: Yes! Haskell can do that.
19:18:33<monochrom>wli: You are not the only one to pay no attention. You are just the only one who say you pay no attention. Me, for example, I pay so no attention that I don't even bother bringing it up. :)
19:18:42<lament>ehird: thanks
19:18:52<ehird>@faq can haskell be an esolang?
19:18:53<lambdabot>The answer is: Yes! Haskell can do that.
19:19:10<PeakerWork>the main Israeli bus company logo: http://egged.co.il/images/logo.jpg
19:19:25<PeakerWork>my friend saw the Haskell logo and thought it was Egged :)
19:20:05<Botje>"egged"
19:20:06<monochrom>Yeah, everyone is finding the logo too similar to most railway logos etc. :)
19:20:15<Botje>that's a fun company name :)
19:21:26<wli>monochrom: In non-esolang-related affairs, slapping a higher-order module system atop basic FP lang constructs is proving difficult for me.
19:22:18<wli>monochrom: http://wli.pastebin.com/m11009a94 is about as far as I've gotten wrt. cooking up AST ADT's for it.
19:22:29<ehird>20:21 wli: monochrom: In non-esolang-related affairs, slapping a higher-order module system atop basic FP lang constructs is proving difficult for me. ← that's not esoteric‽
19:22:48<monochrom>No, SML does that and not eso
19:23:06<wli>Yes, that's why it's non-esolang-related.
19:23:07<kadaver>is haskell defined in BNF?
19:23:07<kadaver>how do you use dlls?
19:23:17<monochrom>Hell, modula-3 does that and can even be imperative, not just functional.
19:23:20<vixey>no about BNF
19:23:37<edwardk>kadaver: can't be, layout doesn't fit BNF style
19:23:58<ehird>ML is esoteric.
19:24:15<Berengal>Define esoteric...
19:24:32<vixey>no don't
19:24:40<monochrom>I guess I have to look up "esoteric" for real. The word is so... esoteric... that I haven't bothered to. :)
19:24:42<vixey>this is #haskell
19:24:44<Berengal>Some research languages certainly border on esoteric
19:25:09<edwardk>esoteric is any language stranger than what I could ever foresee myself getting paid to use some day. ;)
19:26:05<Berengal>That's certainly a pragmatic view
19:26:31<monochrom>I guess "esoteric" is defined by community size.
19:26:44<edwardk>berengal: i'm sure there is a diagonalization argument available where someone hands me a $20 bill to slap together some malbolge some day, but, meh ;)
19:27:29<monochrom>diagonalization is not supposed to be used like that! :)
19:27:51<Berengal>edwardk: I once ran a contest where I offered to buy SM equipment for anyone who provided a malbolge entry
19:27:54<edwardk>monochrom: there is a certain modicum of 'deliberately obtuse' that comes with the esoteric moniker
19:27:55<ehird>ACTION tries to come up with a nice binary operator for Point-construction
19:28:13<kosmikus>cinema: pong
19:28:16<edwardk>ehird: :*: is whats used in uvector for its strict pairs
19:28:28<ehird>I tried .:. but it looks awkward
19:28:32<ehird>Maybe ::
19:28:33<edwardk>then its not just for construction, its the type operator
19:28:43<ehird>O hwait
19:28:45<ehird>that's taken, duhh
19:28:46<ehird>*duh
19:28:49<edwardk>hah
19:29:07<edwardk>:*: has the benefit of indicating its a 'product'
19:29:30<edwardk>:* is about as short as you could get and be a type operator, but its asymmetric
19:29:41<edwardk>er 'is as short as you could get'
19:29:44<ehird>Type operator isn't important, just operator :P
19:29:57<edwardk>ehird: bah, support first class pattern matching ;)
19:30:25<edwardk>otherwise you're stuck with contorting your code to work around this not being a pair
19:31:32<ehird>how about .*.
19:31:59<edwardk>ehird: at that point in time you might as well make them colons and get pattern matching syntax for free ;)
19:32:00<ehird>aw that's not a type operator
19:33:32<wli>Well, the point of what I'm on about is to interpret statically-checked FP crap that has modules in it.
19:35:40<edwardk>data Point = (:*:) { x :: {-# UNPACK #-} !Int, y :: {-# UNPACK #-} !Int } deriving (Eq,Ord,Show,Read,KitchenSink) -- taxicab (a :*: b) = abs a + abs b
19:36:14<edwardk>or taxicab p = abs (x p) (y p) -- god naming the fields x and y is horrific ;)
19:36:25<vixey>why don't you use (,)?
19:36:44<edwardk>vixey: he wants ridonculous speed or something
19:37:27<ehird>yar
19:37:29<ehird>unboxed strictity
19:37:46<ehird>:*: is hard to type, I think I'll just have (Point x y) :-P
19:38:04<edwardk>meh
19:38:47<monochrom>windows (x p) :)
19:39:07<edwardk>better than windows (m e)
19:39:35<PeakerWork>I dislike record fields being getters by default. I think they should be lens/accessors by default
19:39:45<p_l>ACTION is instantly reminded of the "Troubled Windows" Opening...
19:40:01<edwardk>peaker: not a bad idea, had the idiom been established back when they added records to the language
19:40:14<monochrom>Yeah, I think there is no good name for the two coordinates (either too common like "x" or too long like "x_coord"). Since there are only two fields, you don't need names that much. Perhaps call them "get_x" "get_y".
19:40:49<edwardk>monochrom: except _'s aren't haskelly, so you get the ugly getX and getY
19:41:03<monochrom>get'x get'y
19:41:06<monochrom>Oleggy
19:41:11<edwardk>*shudder*
19:41:17<PeakerWork>edwardk: I hope it goes into Haskell'
19:41:32<edwardk>peaker: doubtful, that would break a ton of code
19:41:40<PeakerWork>I thought Haskell' was all about breaking code :-)
19:41:50<monochrom>Not verily.
19:42:04<edwardk>Peaker: nah, haskell' is about noting the fac tthat there has been a decade of progress since haskell 98, so lets pin some of it down and support it
19:42:29<wjt>PeakerWork: "lens"?
19:42:47<monochrom>My understanding is Haskell' is allowed to break some code but should not be too much.
19:43:13<edwardk>the only thing being really broken in haskell 98 is n + k patterns, which were only supported in 98 for legacy reasons already! and if you listen to Richard O'Keefe the sky is falling and it will cause him years of rewrites.
19:43:17<PeakerWork>wjt: "functional references", Data.Accessor, and various other isomorphic structures/aliases
19:43:23<monochrom>It's more important mission is to legalize a lot of extensions since 98.
19:43:49<PeakerWork>edwardk: surely an automated tool can fix n + k patterns automatically in code?
19:44:02<edwardk>Peaker: thats the camp that i'm in
19:44:08<vixey>what does fix n + k mean?
19:44:14<PeakerWork>Python 3k have the python2to3 script
19:44:18<edwardk>vixey: machine translate, etc.
19:44:22<vixey>?
19:44:26<monochrom>"Haskell' : legalize cocaine and comonads now!"
19:44:28<Saizan>i don't think (n+k) patterns are that evil either
19:44:48<PeakerWork>vixey: translate n+k matches to subtractions/guards (I don't know the exact semantics of these patterns)
19:44:48<Gracenotes>> let f 0 = []; f s@(n+1) = s:f n in f 10
19:44:50<lambdabot> [10,9,8,7,6,5,4,3,2,1]
19:44:51<pumpkin_>they're not evil, but they're silly I think
19:44:58<edwardk>monochrom: i don't know that the world is ready for comonads. lets take this slowly
19:45:13<monochrom>Heh
19:45:31<edwardk>introduce them for medical purposes on a State monad by State monad basis.
19:45:36<vixey>what's the point it turning n+k into something equivalent
19:45:54<Saizan>vixey: removing them from the language
19:45:56<edwardk>vixey: to get them out of the language and to give the whiners a graceful exit path
19:46:17<Gracenotes>come now, didn't you all want to pattern-match on addition since childhood?
19:46:25<Gracenotes>are you taking this dream away from people too???
19:46:41<uccus>what's (const id) . fa <*> fb?
19:46:46<monochrom>Take the childhood away from the people.
19:46:50<vixey>if you are removing n+k then I'm removing Prelude
19:46:56<vixey>I hate Prelude it is a nuisance
19:46:58<uccus>I'm removing Prelude
19:47:00<monochrom>hehe
19:47:04<Gracenotes>:o you wouldn't
19:47:09<vixey>I'll do it
19:47:13<uccus>yes I would
19:47:18<neoswish>can anyone explain me, why its impossible to write type signatures in the same line with definition? =)
19:47:19<edwardk>its funny at icfp06 during the haskell' get together there was a Credit Suisse guy panicking about how Haskell' would change his world, and at the time I stood up and joked that the only language feature anyone was even considering pulling was n + k, and at the time the entire room
19:47:31<idnar>edwardk: why are n + k patterns broken?
19:47:31<monochrom>See, this is why Haskell' will never finish.
19:47:37<uccus>but what's (const id) . fa <*> fb
19:47:48<edwardk>demurred that it was entirely a joke... now here we are 2-3 years later and folks are finally considering it in earnest
19:47:52<vixey>uccus that's what it is you wrote it
19:47:56<Gracenotes>@type (const id) . ?fa <*> ?fb
19:47:57<lambdabot>forall a b a1. (?fb::a1 -> a, ?fa::a1 -> b) => a1 -> a
19:48:37<ivan-kanis>can i tell at runtime if ghc is on Windows or Unix?
19:48:43<edwardk>idnar: they can't rebind if you have a different '+' in scope and they rely on unverifiable semantics of Num's - and + method, and they mislead you into thinking that Haskell can do this magic for any method
19:48:43<Saizan>it's fa, apparently?
19:48:48<Saizan>ah, no, fb
19:49:07<Saizan>ivan-kanis: System.Info should have that
19:49:09<DrSyzygyFR>ivan-kanis: I saw something recently about macros being defined by the compiler.
19:49:11<uccus>Saizan... please please guide me through your reasoning...
19:49:14<idnar>edwardk: I don't think "broken" is an appropriate word, in that case
19:49:18<DrSyzygyFR>Or listen to Saizan who as always makes more sense
19:49:18<vixey>edwardk they never mislead me
19:49:22<edwardk>idnar: if i have n + k patterns, why can't i write foo (as ++ bs) = ...
19:49:22<idnar>edwardk: the feature works exactly as intended
19:49:22<Gracenotes>neoswish: it's the way Haskell does it syntactically. If you mean in ghci, then you can do something like...
19:49:25<Gracenotes>> let a :: Int; a = 4 in a
19:49:26<ivan-kanis>Saizan: thanks i'll look
19:49:27<lambdabot> 4
19:49:46<Saizan>uccus: i was just judging by the type
19:49:47<DrSyzygyFR>Prelude> System.Info.os
19:49:47<DrSyzygyFR>"darwin"
19:49:52<DrSyzygyFR>ivan-kanis: Like that.
19:49:53<Gracenotes>neoswish: or just > let a = (4 :: Int)
19:50:13<ali_clark>isn't it broken simply because + is not a data constructor and it is just a special case?
19:50:14<ivan-kanis>DrSyzygyFR: thank you
19:50:15<edwardk>idnar: i understand the pedagogical reason for its initial inclusion, but its a wart. like unary minus not forming a section.
19:50:24<PeakerWork>I thought there was a simple rule: You get to pattern match on data constructors. Except n+k -- does anything else violate this rule?
19:50:34<vixey>unary minus!! yes
19:50:38<idnar>edwardk: warts are generally best fixed by a new language
19:50:38<vixey>Get rid of that
19:50:39<DrSyzygyFR>ivan-kanis: Thank Saizan - he's the one who pointed it out.
19:50:40<ivan-kanis>can I do conditional import ?
19:50:44<vixey>unary minus is worse than n+k
19:50:51<Gracenotes>Peaker well, if you think in terms of Succ and Zero...
19:50:52<DrSyzygyFR>ivan-kanis: Use the CPP extension.
19:50:53<PeakerWork>vixey: I agree -- its also an easily automatable fix
19:50:59<idnar>edwardk: Haskell' claims to not be a new language, so dropping n + k in Haskell' seems out of place
19:50:59<wli>Heck, I don't see why not allow m*n+k patterns like fib (2*n+1) = (fib n)^2 + (fib (n+1))^2 ; fib (2*n) = (fib n)*(fib n + 2*fib (n-1))
19:51:00<ivan-kanis>DrSyzygyFR: ok
19:51:02<PeakerWork>Gracenotes: No, I mean *literally* data-constructors
19:51:03<DrSyzygyFR>And THEN you'll want that there are platform macros around.
19:51:05<vixey>Hey we shhould design a new Haskell
19:51:11<edwardk>wli: thats the slippery slope =)
19:51:13<monochrom>Yes, n+k is the only non-constructor-based pattern.
19:51:28<PeakerWork>there's a good reason to get rid of n+k -- complicating the language for no good reason
19:51:29<idnar>call it Haskell 3000, or something :P
19:51:30<monochrom>Succ and Zero are constructors too.
19:51:35<Gracenotes>PeakerWork: but it's *like* a data constructor. To mesh with the Succ/Zero definition of numbers
19:51:45<PeakerWork>idnar: Python 3000 is just the project name, its really just called Python 3
19:51:51<idnar>PeakerWork: yes, I know
19:51:54<PeakerWork>it can be called Haskell 2
19:51:54<Gracenotes>that's the motivation behind n+k. Perhaps silly, but at least that's where it comes from afaia
19:51:58<ali_clark>it might be cool to have some kind of logic or inverse-of system to allow it though?
19:52:01<idnar>PeakerWork: but if I said Haskell 3, the joke would be rather obscure
19:52:06<monochrom>And Succ is more like plain "n+1" than general "n+54958".
19:52:14<vixey>ali_clark: that's what Curry does
19:52:15<PeakerWork>Gracenotes: as far as you...?
19:52:30<Gracenotes>am aware
19:52:39<edwardk>Gracenotes: if you want n + k, provide a framework for generalized views that gives you that functionality on the left side of the =. i'm not against the idea, but it is an unnecessary wrinkle
19:52:42<idnar>PeakerWork: it was already as obscure as it is; my point was that Python 3000 was always supposed to be a joke, and the fact that the Python developers have forgotten why it was a joke is rather disturbing
19:53:07<edwardk>the major tie breaker for it back in 98 was that there were published books that taught using it, i'd say that 11 years is enough to let that card play out.
19:53:10<Gracenotes>monochrom: well. (Succ (Succ (Succ (Succ ... (Succ x) ... ))))
19:53:28<monochrom>Yuck, but OK I see now.
19:53:32<vixey>this is why S is better than Succ, it's so much shorter
19:53:41<ehird>configure: error: readline not found, so this package cannot be built
19:53:44<ehird>But I have readline!
19:53:46<PeakerWork>idnar: why was it a joke? :)
19:53:47<ehird>(cabal package readline)
19:54:12<monochrom>Someone once asked "why does Num require Eq" and the answer is n+k pattern.
19:54:13<idnar>PeakerWork: because breaking backwards compatibility like that is suicide for a "production" language
19:54:17<dcoutts>ehird: it'll be looking for the C lib and headers
19:54:23<PeakerWork>monochrom: Num is a horrible class, IMO
19:54:26<ehird>dcoutts: yes - and they are there.
19:54:37<idnar>PeakerWork: for Haskell, you can always claim that it's part of "avoid success at all costs", and Haskell certainly isn't trying to be Python or Java
19:54:44<edwardk>vixey: bah, you should use a pair of base cases, T and F, and then ave O and I for the individual bits that prefix the infinite tail, that way you can reason about it in 2s complement constructors.
19:54:49<PeakerWork>idnar: you know the "slow death vs. quick death" thing?
19:54:50<monochrom>See, n+k makes Num horrible.
19:54:56<dcoutts>ehird: check the detailed output from configure, see what goes wrong when it tries to find them
19:54:59<Gracenotes>you're a mean one, Mr. Num. You really are a heel
19:55:06<PeakerWork>monochrom: Num is horrible with or without n+k :)
19:55:08<ehird>dcoutts: how can I do that with cabal-install?
19:55:11<monochrom>Heh
19:55:13<idnar>PeakerWork: none of the warts that are "fixed" in Python 3000 are fatal, either individually or collectively
19:55:14<Gracenotes>you're as cuddly as a cactus, you're as charming as an eel
19:55:14<edwardk>monochrom: bah, Num makes Num horrible
19:55:15<PeakerWork>@type abs
19:55:16<Gracenotes>Mr. Num
19:55:17<lambdabot>forall a. (Num a) => a -> a
19:55:19<PeakerWork>^^ Just plain wrong, IMO
19:55:21<wli>The solution is simple. Haskell' is to standardize extensions. Haskell 2 is to break backward compatible.
19:55:26<dcoutts>ehird: run the ./configure script manually and look at the config.log that it generates
19:55:28<idnar>PeakerWork: they're all irrelevant superficial blemishes
19:55:35<wli>s/compatible/compatibility/
19:55:36<ehird>dcoutts: I'm doing "cabal install readline".
19:55:44<PeakerWork>idnar: well, backwards compatibility with non-fatal things is a slow death..
19:55:48<edwardk>wli: that was the initial thought, but now it looks like Haskell' is a rolling wave, not a single event
19:55:51<Gracenotes>PeakerWork: it makes sense for some non-real Nums, not so much others
19:55:52<dcoutts>ehird: then cabal unpack readline first and cd into it
19:55:53<idnar>PeakerWork: it's like buying a new car without an engine, because your current car has some scratches on the paintwork
19:56:02<PeakerWork>idnar: also, you now have Python2 and Python3 as two separate languages, that's an ok situation, imo
19:56:05<idnar>PeakerWork: sure, the new one looks better, but you can't drive it anywhere
19:56:10<ehird>ah I think it wants a newer version
19:56:26<uccus>let { view 0 = Zero; view n = Succ (n - 1); fac (view -> Zero) = 1; fac (view -> Succ n) = (n + 1) * fac n } in fac 5
19:56:27<idnar>PeakerWork: separate languages is okay, the problem is that Python 3 has very little going for it
19:56:31<monochrom>The number hierachy is hard.
19:56:36<skorpan>> "sup dawg " ++ (fix "we heard you like recursion so " ++)
19:56:37<lambdabot> Couldn't match expected type `a -> a'
19:56:44<idnar>PeakerWork: although people trying to pretend that they're the same language are muddying the issue
19:56:45<ehird>> "sup dawg " ++ (fix $ "we heard you like recursion so " ++)
19:56:46<lambdabot> The operator `++' [infixr 5] of a section
19:56:46<lambdabot> must have lower prec...
19:56:48<skorpan>> "sup dawg " ++ (fix ("we heard you like recursion so " ++))
19:56:49<lambdabot> "sup dawg we heard you like recursion so we heard you like recursion so we ...
19:56:50<pumpkin_>aw
19:56:50<vixey>yeah
19:56:58<PeakerWork>Gracenotes: It makes sense for reals and subgroups of reals, but it should be a->some kind of Real for other types
19:57:19<idnar>PeakerWork: anyhow, I'm ranting out of control here now; but coming back to my original point, Haskell' wasn't supposed to be a new language
19:57:21<PeakerWork>idnar: it has a lot of support going for it -- everyone is trying to be Python3 compatible
19:57:23<Gracenotes>-> Num, probably :\
19:57:43<PeakerWork>Gracenotes: abs :: (Num a, Num b) => a -> b ?
19:57:45<Gracenotes>of course, that's a general num, you'd have to construct it from +, -, /, etc.
19:57:49<pumpkin_>we should start a new haskell standard with fixed numerical hierarchy :P
19:57:58<pumpkin_>Haskell''
19:58:00<PeakerWork>Gracenotes: you need b to a specific type depending on a
19:58:05<monochrom>One may argue that "sup dawg " ++ (fix ("we heard you like recursion so " ++)) is really corecursion.
19:58:06<edwardk>idnar: if you only add and never remove, you wind up with c++.
19:58:06<wli>Haskell 2
19:58:12<Gracenotes>PeakerWork: yes.
19:58:12<PeakerWork>Yeah, I agree: Haskel 2
19:58:20<Gracenotes>so now Num is a multiparam typeclass :)
19:58:24<vixey>Haskell 1.618
19:58:26<idnar>edwardk: well, Python isn't playing in the "research language" space
19:58:27<PeakerWork>Gracenotes: I'm fine with Num a => a -> Double
19:58:28<Gracenotes>all of a single method
19:58:31<Gracenotes>the solution indeed
19:58:43<pumpkin_>Gracenotes: just make it match standard algebraic structures a bit more
19:58:53<vixey>idnar: type systems research with python
19:58:55<edwardk>idnar: sure, i was talking about n+k in haskell. i think the restraint of the haskell' folks is remarkable
19:58:56<monochrom>Haskell ME, Haskell Vista
19:58:57<Gracenotes>PeakerWork: and for Int instance? hm...
19:59:01<PeakerWork>Yeah, "abs" can be a member of a multi-param type-class
19:59:05<Gracenotes>pumpkin_: it's easy to go overboard though
19:59:06<Valodim>Haskell 2 = Brooks
19:59:09<maltem>On what structures is abs defined, mathematically, besides Complex numbers and subsets thereof?
19:59:13<PeakerWork>without making (+) a member of a multi-param type-class
19:59:14<siki>How can I provide or override a default implementation of a function in a class that is a sub-class of another type class?
19:59:18<idnar>edwardk: in the Haskell space, I think a Haskell 2 (or whatever) could work out just fine, but I didn't think that's what Haskell' was supposed to be
19:59:27<vixey>maltem: I supposed normed vector spaces
19:59:28<Gracenotes>maltem: arguably, matrices, if you take abs = determinant
19:59:33<PeakerWork>maltem: vectors in vector spaces
19:59:37<Valodim>ie, Haskell Brooks Curry :)
19:59:39<pumpkin_>Gracenotes: the current one is woefully inadequate though
19:59:39<idnar>edwardk: Java would probably be a better-executed example than C++, though
19:59:41<vixey>not every vector spac
19:59:42<vixey>not every vector space
19:59:42<edwardk>personally most of the monomorphisation of haskell 98 appalls me, there is a lot more i'd like to see reverted
19:59:42<fynn>"Haskell 2"? what are you guys talking about?
19:59:50<monochrom>Haha Valodim
19:59:52<DrSyzygyFR>What kind of equations do people expect abs to fulfill?
19:59:53<pumpkin_>edwardk: same here
19:59:53<vixey>fynn just making things up as we go
19:59:54<Taejo>Gracenotes: urgh... the determinant isn't a norm
19:59:59<PeakerWork>siki: why is it being a sub-class relevant?
20:00:00<DrSyzygyFR>It seems like it should be good for any norms.
20:00:02<vixey>triangle inequality
20:00:05<edwardk>idnar: nah, the c core is a pretty good analogy to haskell 98 in the modern context ;)
20:00:06<idnar>edwardk: C++'s evolution has been... dismal and underwhelming
20:00:07<Gracenotes>Taejo: well, it does yield a real value
20:00:08<kadaver>isnt esoteric: created to be weird
20:00:09<DrSyzygyFR>Which makes the determinant kinda ucky.
20:00:13<pumpkin_>@users
20:00:14<lambdabot>Maximum users seen in #haskell: 658, currently: 633 (96.2%), active: 34 (5.4%)
20:00:14<maltem>vixey, heh, I was going to add "and not counting arbitrary vector space norms"... I'm used to write those as ||·|| instead of |·|
20:00:19<DrSyzygyFR>Wait ...
20:00:21<DrSyzygyFR>:t abs
20:00:23<lambdabot>forall a. (Num a) => a -> a
20:00:25<DrSyzygyFR>Yup.
20:00:30<DrSyzygyFR>That's a tricky bit.
20:00:31<bremner>Gracenotes: err, non-negativity?
20:00:31<idnar>edwardk: Java's evolution has impressed me a lot, despite the fact that I still don't want to write Java code if I can possibly help it
20:00:36<siki>PeakerWork: I can't seem to be able to do it. Let me give an example
20:00:36<edwardk>abs should be from a module on a ring to a ring ;)
20:00:45<DrSyzygyFR>Very seldom is a norm really a map from something to itself.
20:00:45<Gracenotes>edwardk: hush! before it spreads!
20:01:04<maltem>The absolute value really is a special kind of norm, not vice versa
20:01:05<DrSyzygyFR>edwardk: The joys of the horribly designed numerical typeclasses!
20:01:11<Gracenotes>this conversation is lolz incidentally
20:01:24<Gracenotes>-.-
20:01:32<DrSyzygyFR>Gracenotes: SRSLY. They way Num is designed makes doing real mathematics in Haskell REALLY difficult and obnoxious.
20:01:37<siki>Let's say I have: class A a where \ foo:: Double -> Double \ foo x = 1
20:01:50<DrSyzygyFR>ACTION defined some Num instances recently that were mainly undefined....
20:02:00<PeakerWork>siki: you're not using the "a" type variable there
20:02:04<bremner>DrSyzygyFR: try FORTRAN
20:02:15<DrSyzygyFR>bremner: Yeah, because THAT's what I need.
20:02:15<siki>and then class (A a) => B a where \ foo x = 2
20:02:16<bos>@seen dons
20:02:16<lambdabot>dons is in #haskell-in-depth, #haskell-soc, #gentoo-haskell, #concatenative, #arch-haskell, #darcs, #yi, #xmonad, #ghc and #haskell. I last heard dons speak 1h 29m 24s ago.
20:02:18<PeakerWork>siki: you mean: class A a where foo :: a -> a \ foo x = x ?
20:02:29<bos>Where can I find a PDF or similar copy of the current Haskell logo?
20:02:29<siki>yes
20:02:31<siki>sorry
20:02:36<PeakerWork>siki: ah, override super-class default implementations.. I am not sure if that's possible
20:02:37<bremner>DrSyzygyFR: well, you might hate Haskell less
20:02:38<monochrom>FORTRAN is real unless declared integer.
20:02:42<Gracenotes>not to mention, the Num typeclasses don't have too many useful auxiliary methods. Generally when you write a Num-polymorphic method you have a specific type in mind
20:02:44<bos>A Google search just gives me the contest page, with its million entries.
20:02:47<dons>bos: yo
20:02:56<dons>oh the svg?
20:02:57<DrSyzygyFR>bremner: You seem to assume I hate haskell, instead of being a fierce advocate slightly annoyed with some quirks.
20:02:59<siki>PeakerWork: yes that's what I want
20:03:01<dons>i've got one you can use.
20:03:04<bos>dons: SVG, PDF, anything at all :-)
20:03:24<bremner>DrSyzygyFR: nah, just adding white noise to the channel
20:03:33<bos>dons: it would be nice to have a canonical page on the wiki with pointers to various version
20:03:36<dons>yes.
20:03:42<dons>there is one
20:03:46<dons>but doesn't have the final .svg yet
20:03:47<PeakerWork>siki: maybe you really want function records instead of classes?
20:03:49<bos>hmm, google reveals it not
20:03:51<dons>i've a version though. gimme a sec
20:04:06<Valodim>huh? it's on the contest page isn't it?
20:04:09<eu-prleu-peupeu>hey dons, its been a long time :)
20:04:11<Valodim>http://haskell.org/haskellwiki/ThompsonWheelerLogo <- that one?
20:04:35<PeakerWork>siki: data A a = A { f :: a -> a } ; b :: A a ; b = A {f = id}
20:04:56<bos>dons: ta much
20:05:49<dons>http://www.galois.com/~dons/images/haskell-logo.svg
20:06:08<PeakerWork>http://egged.co.il/images/logo.jpg
20:06:28<kadaver_>is it complicated to use DLLs?
20:07:02<siki>PeakerWork: well I have a bunch of instances of "class A" that I want to behave a certain way and then some more that I want behaving in some other way but all instances should have the same function so from the outside the look the same.
20:07:08<siki>I'm not sure if that made sense
20:07:25<kadaver_>to use a C Dll ? do I use the FFI as normal?
20:07:25<kadaver_>http://www.haskell.org/ghc/docs/6.4/html/users_guide/win32-dlls.html
20:07:25<kadaver_>isnt very clear
20:07:33<dons>to use a C DLL is easy
20:07:36<PeakerWork>siki: the question is whether it really has to be a type-class? Why not a record of functions?
20:07:53<dons>where's haskell.org gone ?
20:08:24<siki>I'm not sure what record functions are....let me look them up. I'm quite new to Haskell.
20:08:55<PeakerWork>siki: a record is basically like a tuple except the stuff in it have not only positions but also names
20:09:06<PeakerWork>siki: a record of functions is like a tuple that contains functions
20:09:15<PeakerWork>siki: except the functions inside have names
20:09:20<PeakerWork>siki: so its somewhat similar to a type-class
20:10:26<PeakerWork>siki: with records of functions you get more control about the exact behavior -- and it doesn't have to be determined by the type - you can choose whatever "instance"/implementation you want - and you can do stuff like combining existing records of functions in various ways
20:10:41<maltem>Why does the logo on haskell.org have a slimmer and colder look than what people voted for?
20:10:43<kadaver_>dons ok but where does it say how to?
20:11:16<PeakerWork>maltem: as Stalin said -- the voters don't have the power, those that count the votes do :)
20:11:41<skorpan>how do i make an EOF in ghci? e.g. when reading from stdin
20:11:50<maltem>PeakerWork, so much for the power. What about the motivation?
20:12:30<monochrom>Don't "make" an EOF. Detect it. You get an exception when you read with getLine or getChar.
20:13:08<siki>PeakerWork: I'm trying to digest what you wrote. Basically, I want all instances to have a certain common behavior (function) but I want to be able to group them and give different default implementations of that function to each group.
20:13:20<c_wraith>skorpan: do you mean to quit ghci? ctrl-d on unix, ctrl-z on windows
20:13:24<wli>PeakerWork: It was intended as a critique of e.g. the US. But all the more reason to grind out a CPO-STV module.
20:13:32<skorpan>i don't want to quit ghci, i have a program which reads from stdin
20:13:44<kadaver_>I want to use mpg123's dll to play mp3s but I can't find info on how to use DLL's
20:14:03<seliopou>skorpan, you can't ctrl+c
20:14:05<c_wraith>skorpan: once you close stdin, it stays closed... Meaning ghci isn't going to do much, either.
20:14:09<Zao>kadaver_: Grab a suitable header, foreign import, link against its import lib?
20:14:09<seliopou>can, rather
20:14:26<skorpan>seliopou: then it segfaults :|
20:14:38<seliopou>o_O
20:14:43<seliopou>that's 100% intense
20:14:50<c_wraith>skorpan: You're using 6.10.2?
20:14:58<skorpan>yes c_wraith
20:15:03<c_wraith>Use 6.10.1
20:15:06<c_wraith>It's less broken
20:15:06<seliopou>You don't get "Interrupted."?
20:15:09<seliopou>and then a prompt?
20:15:12<skorpan>seliopou: no, it segfaults
20:15:20<c_wraith>seliopou: 6.10.2 dies on ctrl-c
20:15:25<skorpan>so you're telling me to use 6.10.1? i thought 6.10.2 *fixed* bugs?
20:15:28<monochrom>main = do { main' `catch (\ _ -> return ()) ; putStrLn "The End" }; main' = do { getLine >>= putStrLn; main' }
20:15:48<c_wraith>From what I've seen, 6.10.2 only added bugs
20:15:59<seliopou>ACTION pets ghc 6.8.2
20:16:09<ehird>Is there a way to make cabal use the git revision number as a version?
20:16:16<skorpan>seliopou: let x = x in x ;P
20:16:23<BONUS>6.8.2 has a nasty scoping bug
20:16:43<dcoutts>ehird: you'd need a bit of scripting
20:16:56<ehird>dcoutts: how much? :-)
20:17:10<dcoutts>ehird: sorry, not sure. I've not done it.
20:17:32<hgolden>Hi. I tried to compile buddha-1.2.1 under ghc-6.10.2. It failed due to old references (lang package). Has anyone patched it? Does anyone use it? Thanks.
20:17:39<ehird>If I only have one description should it be description or synopsis in .cabal?
20:17:56<dcoutts>ehird: ideally you should use both. hackage displays both.
20:18:23<ehird>dcoutts: So have them identical?
20:18:25<dcoutts>ehird: a one line summary for the synopsis and a bit more (not repeating) for the description
20:18:35<ehird>But I only have one thing to say :-)
20:18:36<dcoutts>ehird: no, the description is in addition
20:18:50<ehird>Right... but I have nothing to say.
20:18:54<ehird>More than the synopsis.
20:19:02<Saizan>"Duh"
20:19:09<ehird>:-)
20:19:28<dcoutts>ehird: then leave the description blank
20:19:44<kadaver_>Zao: how do I link? and with lib you meant he dll?
20:21:46<Zao>kadaver_: On windows, you don't link against DLLs directly.
20:22:03<siki>Anyone else has any recomendation in how a sub-class can override its super-class' default implementation of a function?
20:22:12<Zao>kadaver_: You link against an import library which which has stubs that call into the DLL.
20:22:20<siki>if it can be done at all....
20:22:30<Zao>You should have a header with the function signatures, an import library to link to and a DLL to run with.
20:22:56<Zao>Some toolchains (probably mingw) can synthesise a decent import library from a DLL, provided you only want exported functions.
20:23:24<ehird>Warning: 'license: MIT' is not a recognised license. # :\
20:25:57<kadaver_>exe's are never for linking?
20:26:43<kadaver_>i have some dlls, a .h but not .lib
20:26:55<p_l>kadaver_: You can open a dll manually
20:27:51<p_l>link libraries are there to ease that part of the process (I guess it might have something to do with windows not using position-independent binaries except for some stuff on 6.1)
20:31:04<Zao>You have LoadLibrary + GetProcAddress much like you have dlopen + dlsym on posixy boxen.
20:31:37<Zao>ehird: That annoys me to no end.
20:32:49<edwardk>ehird: there is a bsd-like entry you can use iirc
20:36:00<kadaver>is the .def file the import lib?
20:38:48<dons>it is kind of "industrial haskell" sort of day. 3 nice articles on commercial users
20:39:23<kadaver>im to sexy for my body
20:39:30<kadaver>where?
20:39:55<p_l>kadaver: .def is used as input for import lib gen.
20:40:17<p_l>kadaver: import libs usually end up as *.lib just like static ones
20:47:22<dons>wow hackathon video: http://tom.lokhorst.eu/hac5/
20:47:40<dons>with a soundtrack. fun fun
20:49:12<kadaver>well there is no .lib
20:50:32<p_l>heh, everyone with laptops. Where are the times you had to lug a desktop computer to a con? ^^;
20:50:39<edwardk>ACTION returns to bashing esolangs, not that oklopok is here ;)
20:50:43<edwardk>er now that
20:51:23<oklopok>i was here the whole time!
20:51:26<kadaver>dons:did you use mpg123?
20:51:40<edwardk>oklopok: yes, just in a form i didn't recognize ;)
20:51:41<dons>in the past, yes.
20:52:09<oklopok>i've done little work on esolangs recently, due to university bus..iness, so i'm fine with that.
20:52:15<p_l>um, one of the guys looked familiar... except as far as I know I'm the only one in abdn-compsci society that used haskell...
20:52:30<edwardk>ah, here i was eagerly awaiting some form of okloskell ;)
20:52:47<oklopok>i don't mind things i don't waste my time on being stupid
20:52:53<oklopok>what's okloskell?
20:53:00<kadaver>brainskell
20:53:02<oklopok>oh this is #haskell
20:53:05<oklopok>right!
20:53:08<edwardk>=)
20:53:24<oklopok>well i was just looking at my old esolangs and thinking god i used to be smart
20:53:59<Cale>which ones?
20:54:08<oklopok>ef and graphica.
20:54:15<oklopok>i'm sure you know them.
20:56:12<Cale>Somehow the names seem familiar, but I can't find them :)
20:56:45<oklopok>all that's online is a few examples
20:56:55<oklopok>and ef doesn't have anything else in existance.
20:57:16<Cale>Maybe you wrote some blog posts about them?
20:57:17<oklopok>i mostly do vaporware, since i don't have the patience for programming or making specs.
20:57:29<oklopok>Cale: well i don't have a blog per se.
20:57:57<Cale>I just vaguely recall something linked from the programming reddit at some point
20:58:14<oklopok>8|
20:58:15<vixey>http://www.esolangs.org/wiki/Ef
20:58:16<oklopok>well that wasn't me :P
20:58:22<vixey>http://www.esolangs.org/wiki/Graphica
20:58:26<vixey>this is not working
20:58:30<oklopok>hmm
20:58:45<oklopok>well i don't exactly use wikis
20:58:48<pumpkin_>hmm, Pointed is something you can stick something into?
20:58:50<oklopok>scary.
20:59:12<Cale>pumpkin_: something with an equivalent of 'return'
20:59:17<pumpkin_>I see
20:59:31<oklopok>but i wonder why the pages exist
20:59:36<vixey>they don't
20:59:40<pumpkin_>so every Pointed is a functor, but not vice versa?
20:59:40<oklopok>oh, right
20:59:46<Cale>right
21:00:20<oklopok>didn't know that's the way to say page not exists.
21:00:36<Cale>pumpkin_: The term comes by way of analogy with Set, where a function 1 -> A can stand in as a version of A with a special point identified
21:00:37<pumpkin_>the latest email on -cafe seems to say that backwards though
21:00:45<pumpkin_>"They are in order of power: every monad is an applicative; every applicative is a functor; every functor is pointed."
21:01:03<pumpkin_>from the "Converting IO [XmlTree] to [XmlTree]" thread
21:01:11<Cale>pumpkin_: So if you consider a natural transformation 1 -> T where T is some functor, that's rendered in Haskell as a polymorphic function: a -> T a
21:01:27<pumpkin_>but ((->) a) is a functor and not pointed
21:01:31<pumpkin_>ok
21:01:35<Cale>Not every functor is pointed
21:01:40<pumpkin_>ok :)
21:01:45<pumpkin_>just making sure
21:02:41<pumpkin_>outside of category-extras
21:02:50<pumpkin_>what is this called? a Pointed functor?
21:03:00<Saizan>((->) a) is pointed.. unless you mean (Flip (->) a)
21:03:38<Cale>Yeah, a pointed functor.
21:03:41<edwardk>pumkin: ((->)a) is pointed, its a monad =)
21:03:52<pumpkin_>oh, true, hmm
21:03:58<Cale>Most functors have more than one way of being pointed though.
21:04:03<edwardk>but you are right that not every functor is pointed
21:04:09<Cale>So it's not appropriate to call a functor pointed without picking one.
21:04:21<Cale>and yeah, there are of course some which are not
21:06:14<edwardk>pointed is just a way of saying there is a family of coalgebras that has a member for every object in the source category of the functor that you want to somehow point out as somehow canonical
21:06:36<Deewiant>Yes, just that
21:06:46<pumpkin_>edwardk: duh ;)
21:06:55<pumpkin_>but yeah, I mostly understood that, which is encouraging
21:07:11<edwardk>Deewiant: i should have capstoned that with the standard mathematician way of avoiding responses: "obviously" ;)
21:07:23<Deewiant>:-)
21:07:54<pumpkin_>edwardk: you gonna write a knol on dogamorphisms too?
21:08:21<edwardk>pumpkin: i went home to do so, but my dogamorphism ate my homework.
21:08:33<pumpkin_>onoes
21:08:48<edwardk>catamorphic failure
21:09:03<pumpkin_>epimorphic failure?
21:09:28<pumpkin_>I guess I should drop the -ure
21:09:30<edwardk>clearly there are several kinds of failure involved, so polymorphic failure.
21:14:15<a_guest>I have a question regarding left and right folds. When folding over infinite lists, should my choice be left fold? Since a right fold needs to go infinite deep to reach [] which it starts from?
21:14:32<Deewiant>> foldr f z [1..]
21:14:38<lambdabot> f 1 (f 2 (f 3 (f 4 (f 5 (f 6 (f 7 (f 8 (f 9 (f 10 (f 11 (f 12 (f 13 (f 14 (...
21:14:42<Deewiant>> foldl f z [1..]
21:14:43<edwardk>a_guest: in a strict language, yes, in a lazy language with a non-strict function you probably want foldr
21:14:48<glguy>a_guest, only right folds make sense on an infinite list
21:15:03<glguy>as they can produce a value before seeing the end of the list
21:16:30<glguy>a_guest, the right fold doesn't actually start at the right end of the list
21:16:59<skorpan>:t fmap
21:17:01<idnar>@ping
21:17:01<lambdabot>pong
21:17:02<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
21:17:07<glguy>foldr f z (a:b) -> f a (foldr f z b)
21:17:13<ski>> foldr (const ()) undefined [0..]
21:17:15<glguy>if f a _ can produce a value without inspecting the _
21:17:16<lambdabot> Couldn't match expected type `b -> b' against inferred type `()'
21:17:34<kadaver>ACTION commits hatakari
21:17:37<glguy>then you'll see a value before you hit the end
21:17:59<ski>> foldr (\_ _ -> ()) undefined [0..]
21:18:01<lambdabot> ()
21:18:16<ski>> foldr (\x _ -> x) undefined [0..]
21:18:17<lambdabot> 0
21:18:21<c_wraith>I just *finally* managed to wrap my head around fix. I'm not used to thinking like this.
21:18:28<ski>> foldr (\x xs -> x:xs) undefined [0..]
21:18:29<lambdabot> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,...
21:18:49<skorpan>:t sequence_
21:18:50<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m ()
21:22:41<ryanakca>Could someone help me with se noai
21:22:41<ryanakca>ahttp://hpaste.org/fastcgi/hpaste.fcgi/view?id=4264#a4264:se ai
21:23:10<a_guest>So the prime building case of lists ([]) are not required for infinite lists?
21:23:48<oklopok>> foldr (\x xs -> x:xs) 0 [0..]
21:23:49<lambdabot> No instance for (Num [a])
21:23:49<lambdabot> arising from the literal `0' at <inter...
21:23:51<ryanakca>Ooops, *kicks screen*, could someone help me with ^^ please, question and code included, from RWH. I'm not sure what I'm doing wrong... it works in my head, just not in code :/
21:24:00<oklopok>isn't it because undefined can be of type list too
21:24:35<glguy>ryanakca, you can't ++ the head of a list into its tail
21:24:36<a_guest>((a : b) : c) : ... legal, but (a : b) : c not legal?
21:25:25<oklopok>a_guest a:b is a list, and : takes a "value" as its left argument
21:25:26<kadaver>> fix f (-1) in f
21:25:28<lambdabot> <no location info>: parse error on input `in'
21:26:28<kadaver>@src fix
21:26:29<lambdabot>fix f = let x = f x in x
21:26:36<ryanakca>glguy: Ah, thanks, figured it out
21:26:47<Gracenotes>:t fix ?f (-1) -- :<
21:26:48<lambdabot>forall a t. (Num a, ?f::(a -> t) -> a -> t) => t
21:27:29<kadaver>@type fix
21:27:30<lambdabot>forall a. (a -> a) -> a
21:27:38<a_guest>oklopok: if a, b are elements: the finite expression a : b is not valid.
21:27:53<ErhardtMundt>hello
21:28:30<oklopok>a_guest: that too
21:29:16<a_guest>oklopok: but a infinite construction definition is legal?
21:30:32<oklopok>a_guest: a finite one would be too, as long as the undefined isn't actually evaluated
21:30:50<oklopok>> head (1 : 2 : 3 : undefined)
21:30:51<lambdabot> 1
21:30:54<oklopok>wow
21:30:55<oklopok>that worked.
21:31:21<a_guest>My first thought was that infinite lists should be defined from left, since a right definition would go infinite deep to reach the []
21:32:17<oklopok>a_guest: basically the thing that creates the list is just an unevaluated trunk, when you need its head, you just evaluate it a bit until you get it, and the definition gives you the head after one step into the recursion
21:32:24<oklopok>i'm not good at explaining.
21:32:26<a_guest>...Hence construct infinite lists with (++).
21:32:49<oklopok>ah
21:32:55<oklopok>i actually missed some context
21:34:24<oklopok>and now i'm not sure what you're asking, but you've been given lots of answers, and i don't actually know all that much
21:34:28<a_guest>oklopok: I thought that a list nescesscarly needed to be buildt from the prime case [].
21:34:34<oklopok>a_guest: it is.
21:34:59<oklopok>thing is you don't need to have the end of the list evaluated before you start using it
21:35:30<oklopok>kinda like you can do (head [1..]) even though [] hasn't been reached yet
21:35:30<koninkje>a_guest: lists only need to be build from [] if the (:) constructor is strict in its recursion, which is not the case in Haskell
21:36:45<oklopok>> take 10 ((flip (:)) [1..])
21:36:47<lambdabot> Couldn't match expected type `[a]'
21:36:48<oklopok>err
21:36:58<oklopok>> take 10 (folrl (flip (:)) 0 [1..])
21:36:58<lambdabot> Not in scope: `folrl'
21:37:00<oklopok>...
21:37:06<oklopok>> take 10 (foldl (flip (:)) 0 [1..])
21:37:06<lambdabot> No instance for (Num [b])
21:37:07<lambdabot> arising from the literal `0' at <inter...
21:37:12<oklopok>i really should try this stuff in priv :P
21:37:21<oklopok>> take 10 (foldl (flip (:)) [] [1..])
21:37:33<koninkje>> take 10 . foldl (flip(:)) 0 $ [1..]
21:37:40<lambdabot> mueval: Prelude.read: no parse
21:37:43<lambdabot> No instance for (Num [b])
21:37:43<lambdabot> arising from the literal `0' at <inter...
21:37:54<oklopok>koninkje: i'm trying to get foldl to make sense, probably doesn't make much sense
21:38:18<koninkje>foldl is just like foldr except the arguments to the first function are swapped
21:38:33<koninkje>(strictness and implementation details aside)
21:38:52<Saizan>> foldl f z [1..3]
21:38:55<lambdabot> f (f (f z 1) 2) 3
21:38:58<Saizan>> foldr f z [1..3]
21:38:59<lambdabot> f 1 (f 2 (f 3 z))
21:39:38<a_guest>www.foldr.com
21:41:18<mikm>I laughed, a_guest
21:41:43<Saizan>www.foldl.com
21:41:55<koninkje>http://en.wikipedia.org/wiki/File:Fold-diagrams.svg
21:43:05<koninkje>if only http://cale.yi.org/index.php/Fold_Diagrams weren't down
21:43:14<Cale>koninkje: oh...
21:43:16<Cale>it's down?
21:43:26<mikm>It's up for me
21:43:32<koninkje>"can't find server" I'm told...
21:43:43<Cale>koninkje: Maybe a bad dns cache
21:43:56<koninkje>http://downforeveryoneorjustme.com tells me it's just me :(
21:44:20<oklopok>it always does
21:44:20<Cale>99.247.248.73
21:44:28<koninkje>working now
21:48:18<a_guest>thank you for answers.
21:51:38<equaeghe>how do I uninstall packages installed using cabal?
21:52:07<dcoutts>equaeghe: you can unregister them with ghc-pkg, if you need the disk space you can remove the files with rm
22:01:57<Cale>It would be nice if at some point cabal got an uninstall feature :]
22:02:07<dcoutts>wouldn't it
22:02:19<dcoutts>ACTION invites volunteers
22:02:42<dcoutts>the approach is just to install into a temp dir, record the list of files and stash it somewhere
22:02:53<dcoutts>can all be done in cabal-install without any changes to the Cabal lib
22:06:14<dons>quite easy, really
22:06:20<dons>its a bit like fake install support, though
22:07:01<kadaver>dman engineering is friggin easy after doing software
22:07:23<Philippa_>engineers have better libraries ;-)
22:09:42<lament>bigger, certainly
22:11:46<Botje>.oO(checkinstall runhaskell Setup.lhs install)
22:19:33<zoheb>Is anyone using ghci as a command shell?
22:19:57<zoheb>I looked up Haskell Shell on google but saw nothing exciting
22:21:45<Gracenotes>hshell? :)
22:22:03<Gracenotes>hsh. gsh.
22:22:14<bremner>s/hs//
22:22:30<zoheb>I saw a Jun 2006 blog entry for it
22:23:14<Gracenotes>Haskell would make a nice shell. monad/pipe analogies and the like
22:23:31<zoheb>I did rather roll my own shell
22:23:36<kadaver>i use ghci as a calculator, faster to fire up than windows calc or python
22:23:57<zoheb>there doesn't seem to be much that the shells seem to do
22:24:20<zoheb>It would be great if any of the shells had readline support
22:24:35<zoheb>hshell doesn't seem to have it
22:24:38<Gracenotes>argh. time to pkill firefox again >:[
22:25:05<zoheb>also, has anyone tried installing the haskell readline library on windows?
22:25:18<zoheb>It isn't in the default install?
22:25:36<zoheb>some of the instructions are back from 2004
22:27:47<zoheb>yet another question, Is there anyway to read a an arbitrary string and "compile" it into an arbitrary expression
22:27:59<zoheb>arbit haskell expr
22:28:03<zoheb>the way ghci works
22:28:06<kadaver>firefox is really friggin memoryheavy
22:28:11<kadaver>and crashes often lately
22:28:16<kadaver>time for aa rewrite
22:28:18<Axman6>yup
22:28:19<kadaver>in haskell!
22:28:26<zoheb>To put it another way, how would I write my own ghci
22:28:30<Gracenotes>my firefox doesn't usually have the courtesy to crash, it just freezes
22:28:47<Axman6>zoheb: interact
22:28:47<Gracenotes>and then the pkilling begins! *eyes gleam*
22:28:55<Axman6>:t interact
22:28:56<lambdabot>(String -> String) -> IO ()
22:29:42<zoheb>what I want to know is the eqvt of readS
22:30:01<zoheb>for an arbitrary haskell expression
22:30:03<mauke>zoheb: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mueval
22:30:37<zoheb>that looks right
22:30:49<zoheb>interact isn't good enogh
22:31:08<Axman6>it's a start
22:31:23<Axman6>but yes, mueval is what you want
22:31:26<zoheb>does ghci use mueval
22:31:29<Gracenotes>mauke: hm, using process? *eyes suspiciously*
22:31:45<Gracenotes>ghci uses an evaluator with GHC primitives
22:32:44<zoheb>Gracenotes, Is it part of a library somewhere?
22:32:57<Gracenotes>the GHC source, in the compiler directory
22:33:06<zoheb>ouch
22:33:24<Lemmih>zoheb: There's a 'ghc' library but it isn't that easy to use.
22:33:33<Gracenotes>http://darcs.haskell.org/ghc/compiler/ghci/
22:33:38<zoheb>I guessed as much :-|
22:33:39<Gracenotes>ghci itself
22:34:03<zoheb>But the ghci prompt does not have readline like fnctionality
22:34:10<Gracenotes>particularly see GhciMonad, InteractiveUI and GhciTags
22:34:17<zoheb>like Ctrl-R to reverse look up command history
22:34:23<Axman6>zoheb: it doesn't? o.O
22:34:49<jeffwheeler>Is there a way to include a package when using runhaskell or similar? It seems like it should be -p name, or similar, but this doesn't seem to do anything.
22:34:52<kadaver>getInfoOnMp3PlayingInHaskell >>= passInfoToKadaver
22:34:57<mauke>zoheb: it does here
22:35:07<zoheb>I am on windows
22:35:16<zoheb>ctrl-r doesnt seem to work
22:35:51<jeffwheeler>Oh, -package seems to work. How silly of me.
22:35:57<zoheb>does it work on Unix?
22:36:44<Saizan>zoheb: are you on 6.10?
22:36:49<zoheb>yes
22:37:01<Saizan>zoheb: try installing ghci-haskeline from hackage then
22:37:20<Saizan>and using that
22:37:20<zoheb>ok
22:39:39<Baughn>kadaver: checkHackageForPackages >>= return
22:50:55<kadaver>let onReturn (Person k) = "help" ++ "kadaver" in onReturn (Person "kadaver")
22:51:14<kadaver>> let onReturn (Person k) = "help" ++ k in onReturn (Person "kadaver")
22:51:15<lambdabot> Not in scope: data constructor `Person'Not in scope: data constructor `Pers...
22:51:28<kadaver>> let onReturn k = "help" ++ k in onReturn "kadaver"
22:51:30<lambdabot> "helpkadaver"
22:51:39<zoheb>has anyone use cabal on windows? I think I am running into some firewall shit
22:52:14<zoheb>C:\Windows\system32>cabal update Downloading the latest package list from hackage.haskell.org cabal: getHostByName: does not exist (no such host entry)
22:54:45<ehird>Why do Map functions take the map last? It's quite irritating
22:55:24<Axman6>thing `f` map?
22:55:28<kadaver>hmm dont know sorry, mine just works
22:55:45<glguy>ehird, usually what you want in the end is a function Map _ _ -> Map _ _
22:55:53<glguy>so it is helpful to have the map parameter last
22:56:00<ehird>I suppose.
22:56:06<glguy>then you can write things like: modify (Map.insert a b)
22:59:39<adamvo>@type flip -- this isn't too irritating, ehird, is it?
22:59:41<lambdabot>forall a b c. (a -> b -> c) -> b -> a -> c
22:59:48<ehird>adamvo: insert :: Ord k => k -> a -> Map k a -> Map k a
22:59:56<ehird>it's not as simple as just a single flip
23:00:07<Axman6>ACTION dislikes haveing to use flip
23:00:17<ehird>Axman6: yeah, it's like using stack shuffling words
23:00:22<ehird>in concatenative langs
23:00:53<Axman6>i'm not really a big fan of pointfree style anyway
23:00:58<adamvo>@type flip $ uncurry Data.Map.insert
23:00:59<lambdabot>forall a b. (Ord a) => M.Map a b -> (a, b) -> M.Map a b
23:01:09<ehird>curry . flip . uncurry?
23:01:10<ehird>SRS?
23:02:24<ehird>also, are nested "where"s bad style? ;)
23:02:35<ski>no
23:05:43<Cale>Well, they *might* be suboptimal, but sometimes they're totally appropriate.
23:06:12<zoheb>Can someone do me a favor and try this ----------> ping hackage.haskell.org
23:06:30<zoheb>I cant ping this from my place
23:06:34<mauke>2 packets transmitted, 0 received, 100% packet loss, time 999ms
23:06:47<ehird>ditto
23:06:51<Cale>I can't ping, but I can get to the website.
23:06:51<ehird>looks like monk is down
23:06:55<jeffwheeler>Yep
23:06:59<ehird>ah
23:07:00<ehird>ditto
23:07:04<ehird>monk's blocking pings, rather.
23:07:08<zoheb>no wonder my cabal isn't updating
23:07:19<ehird>i don't see why not
23:07:31<Cale>ACTION tries a cabal update
23:07:39<jeffwheeler>Works for me.
23:07:42<Cale>Seems to work, yeah
23:07:44<zoheb>actually even my host name isn't getting resolved
23:08:04<Cale>69.30.63.197
23:08:06<zoheb>I think its the firewall at my place
23:11:31<zoheb>f this - this is some kind of workplace firewall
23:11:56<zoheb>Is cabal useful without an internet connection?
23:12:03<Cale>zoheb: somewhat
23:12:10<Zao>You can always use it to build packages you already have source for.
23:12:12<Cale>zoheb: You can use it to build packages easily
23:12:19<Zao>It can probably unpack cached packages too.
23:12:33<coolsner>cabal is not only a package manager, it's a build system too
23:12:34<zoheb>download the package and cabal install from there?
23:12:40<Cale>Issuing cabal <command> without a package name from inside the top-level source directory of a package will work.
23:12:47<Cale>yeah
23:13:00<zoheb>what about updates?
23:13:12<Cale>Well, you'd have to download them and install them by hand like that
23:13:37<zoheb>ok
23:13:58<Cale>Oh, updating the hackage database is unnecessary
23:14:10<Cale>Since you'll only be installing the packages manually anyway
23:14:21<zoheb>hmm
23:14:26<Cale>And I don't usually recommend cabal upgrade anyway
23:15:22<Cale>(it can inadvertently install versions of things where the version that comes with your copy of ghc would usually be better)
23:15:39<Cale>(and then you end up with dependency hell)
23:18:24<glguy>Didn't GHC get a new foreignptr in 6.10.2 or so?
23:18:29<glguy>one that runs its finalizers
23:18:52<pumpkin_>yeah
23:19:00<glguy>what module was that added to?
23:19:01<pumpkin_>well, the behavior definitely changed, I can't remember the specifics
23:19:08<pumpkin_>they changed the existing one
23:19:18<dons>there's a discussion about it on the list at the moment
23:19:35<glguy>which list
23:20:02<dons>glasgow-haskell-users@ i think
23:21:45<glguy>a search on nabble shows no posts about foreignptr in the last month
23:21:47<glguy>do you know the title?
23:21:49<Saizan>re cabal with no connection: you can run cabal fetch foo when you're connected, and then cabal install foo later
23:21:59<zoheb>Noob question - I am looking at cabal docs, it seems you just cd into the dir and run setup.hs, so I dont really need cabal to perform a cabal install?
23:26:45<Saizan>zoheb: you can runghc Setup configure; runghc Setup build; runghc Setup install instead of "cabal install"
23:26:51<adamvo>is anybody here who can help me with my code.haskell.org / community.haskell.org account? It is supposed to be enabled today, but when I try to ssh in, I am asked for a password (and not my RSA private key)
23:27:10<Saizan>zoheb: but that's becoming more and more an UI for scripts rather than for humans
23:27:11<zoheb>yes, thats what the documentation said
23:28:22<yav>kkjjkkj
23:28:31<yav>(sorry, this was for vim)
23:31:10<Igloo>adamvo: What username?
23:31:24<adamvo>Igloo: aavogt
23:32:31<zoheb>http://mibbit.com/pb/8A2Rh3
23:32:48<zoheb>I suspect this isn't going to go too well
23:33:21<Saizan>zoheb: well, you need to install those packages first
23:33:31<zoheb>Yes
23:33:54<zoheb>does it do automatic recursive updates
23:34:10<Saizan>yes, if you run "cabal update" to download the index first
23:34:53<Igloo>adamvo: Can you paste the end of your SSH public key please?
23:37:21<Igloo>adamvo: Or actually, just send the key to support@community.h.o. The one we have seems to be corrupt
23:38:37<amckinley>hey, newbie parsec/haskell question: im parsing a list with two different types of elements, and i need to invoke a different parser depending on the type of element
23:39:06<adamvo>Igloo: thanks, I'll mail the public key then
23:39:21<amckinley>what do i need to do to group all the elements of one type in one list, and all the elements of the other type in a different list?
23:40:34<ski>@hoogle [Either a b] -> ([a],[b])
23:40:34<lambdabot>No results found
23:40:59<copumpkin>wasn't that partitionEithers ?
23:41:06<copumpkin>or something along those lines
23:41:16<ski>possibly .. istr seeing it on mailing list at some point
23:41:24<copumpkin>http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Either.html#v:partitionEithers
23:41:28<copumpkin>new in 6.10 I guess?
23:41:43<copumpkin>there's also lefts and rights that do what you'd expect
23:42:01<yav>but no mapEither? we should add that
23:42:15<amckinley>ski: i was thinking about using Either, but i thought Either was exclusively for a "good" Right case and a "failure
23:42:17<vixey>what's mapEither??
23:42:20<amckinley>" Left case
23:42:28<copumpkin>amckinley: I hope not
23:42:43<yav>mapEither :: (a -> Either b c) -> [a] -> ([b],[c])
23:42:50<copumpkin>:t map . either
23:42:51<dons>:t partition
23:42:51<lambdabot>forall a c b. (a -> c) -> [b -> c] -> [Either a b -> c]
23:42:52<lambdabot>forall a. (a -> Bool) -> [a] -> ([a], [a])
23:42:54<yav>it is like mapMaybe
23:42:59<vixey>why would you do that
23:43:03<ski> mapEither :: (a0 -> a1) -> (b0 -> b1) -> (Either a0 b0 -> Either a1 b1) -- ?
23:43:04<copumpkin>ah
23:43:05<dons>:t mapMaybe
23:43:06<lambdabot>forall a b. (a -> Maybe b) -> [a] -> [b]
23:43:10<amckinley>copumpkin: good deal :) im going through RWH; thats what it seemed to imply
23:43:13<ski> mapEither :: (b0 -> b1) -> (Either a b0 -> Either a b1) -- ?
23:43:23<copumpkin>mapNeither!
23:43:27<dons>mmm
23:43:28<copumpkin>we need a function called that
23:43:28<yav>:)
23:43:56<yav>mapNeither :: (a -> b) -> [Either x y] -> [Either x y]
23:43:59<dons>?let can't = False
23:44:00<lambdabot> Defined.
23:44:04<ski>amckinley : that's the `Either e' monad, yes
23:44:05<kadaver>who talked about cabal on widnows before?
23:44:10<kadaver>i get the same error now
23:44:20<kadaver>$ cabal update
23:44:20<kadaver>Downloading the latest package list from hackage.haskell.org
23:44:20<kadaver>cabal.exe: getHostByName: does not exist (no such host entry)
23:44:22<ski>one could consider a different `Either e' applicative, though ..
23:44:53<ski>@type mapMaybe
23:44:54<lambdabot>forall a b. (a -> Maybe b) -> [a] -> [b]
23:45:52<ski> instance Monoid e => Applicative (Either e)
23:45:54<ski> where
23:46:05<ski> pure a = Right a
23:46:24<ski> Left e0 <*> Left e = Left (e0 `mappend` e)
23:46:40<ski> Left e0 <*> _ = Left e0
23:46:51<ski> _ <*> Left e = Left e
23:47:05<ski> Right f <*> Right a = Right (f a)
23:47:37<ski>you can use this for accumulating all the "reachable exceptions", e.g.
23:48:54<Igloo>adamvo: Does it work now?
23:49:41<amckinley>and so my type should be something like "statement :: Parser (Either Declaration Parameter)"?
23:49:48<ski>yav : hm .. how would the corresponding map for lists look like ?
23:49:57<amckinley>(where declaration and parameter are the two different types)
23:50:04<ski>amckinley : possibly, yes
23:50:33<yav>ski: which map?
23:50:42<codebliss>isLoved = (<3)
23:50:52<yav>ski: oh i see
23:50:59<amckinley>ski: is there a different way you'd suggest doing it?
23:51:05<yav>haven't thought about it, let me see
23:51:19<ski> mapList :: (a -> [] b) -> ([a] -> [] [a]) -- i suppose
23:51:47<yav>ski: perhaps. it makes more sense for simple "sum" types
23:51:55<copumpkin>type Algebra f a = f a -> a
23:52:07<yav>the idea is that you map, and then group the results according to their tags
23:52:08<ski>(/me wonders whether there should possibly be a `transpose' or `sequence' in there ..)
23:52:10<copumpkin>hmm
23:52:47<ski>amckinley : it depends on what you want, i suppose
23:53:08<ski>i don't really see why a "statement" should be either a "declaration" or a "parameter", myself
23:53:19<adamvo>Igloo: it works, thanks
23:53:37<ski>(erm s/[] [a]/[] [b]/ ..)
23:53:48<amckinley>ski: if you have some time to get into it and help me, i can give you a little more context and you can tell me what other egregious beginner haskell sins im committing :)
23:54:10<ski>(copumpkin : hm ?)
23:54:26<copumpkin>from http://knol.google.com/k/edward-kmett/catamorphisms/3qi7x2qrdushx/2#
23:54:59<ski>(yes)
23:55:30<copumpkin>I don't really have a question, I just thought that was an interesting type
23:55:33<copumpkin>:P
23:55:59<ski>amckinley : i could take a look
23:56:37<ski>(`mapList :: (a -> 1 + b * ..) -> ([a] -> 1 + [b] * ..)' .. hm)
23:56:54<amckinley>ski: http://pastebin.com/me085169
23:56:59<ski>@type mapMaybe id
23:57:00<lambdabot>forall b. [Maybe b] -> [b]
23:57:05<amckinley>im writing a parser for dhcpd config files
23:57:22<ski>@type let mapEither :: (a -> Either b c) -> [a] -> ([b],[c]); mapEither = undefined in mapEither id
23:57:23<lambdabot>forall b c. [Either b c] -> ([b], [c])

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