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