Experimental IRC log haskell-2009-06-10

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

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

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

00:00:31<dumael>SamB: floppy disk emulation is how El Torito works afaik. After you've boot up any OS off a cd, they still need drivers for things like IDE/SATA controllers. Windows and linux get a fair shock when they can't detect the boot cd due to a lack of drivers.
00:00:35<ray>opera software clobbered my hoogle shortcut :(
00:00:48<ray>i had to change it to :h
00:01:01<SamB>dumael: well, you ALSO need to get the BIOS to stop emulating the floppy, don't you?
00:01:13<TheColonial>:k [Int]
00:01:14<lambdabot>*
00:01:39<idnar>SamB: I'm not sure it matters
00:01:41<SamB>and do whatever else is needed to eject the CD?
00:02:02<SamB>or does it load the whole emulated floppy into RAM?
00:02:13<SamB>and just waste that piece of RAM forever?
00:02:13<dumael>er, not wholly certain.
00:03:03<mcnster>hi. what is an elegant way to map/fold a type of [(a,b)] into [(b,[a])]?
00:03:20<idnar>SamB: apparently "no emulation" mode is mostly used these days
00:03:30<Peaker>mcnster: you mean (b,[a]) ?
00:04:20<mcnster>i mean [(b,[a])]
00:04:38<ray>that question requires more detail than just the types
00:04:44<SamB>idnar: ah.
00:05:06<p_l>dumael: that's wrong. There are few modes, with *one* of them being floppy emulation
00:05:12<SamB>even so, it'd take a pretty hefty amount of RAM in my way of thinking to actually unmount your knoppix CD
00:05:31<ray>knoppix is fat
00:05:33<SamB>or a good-sized swap partition, I guess
00:05:38<dumael>p_l: thanks for the correction.
00:05:40<p_l>dumael: Win9x used floppy emulation mode, and that's probably the only OS I know of that used that :)
00:05:43<SamB>ray: no, cloop ext2, I think
00:05:52<idnar>haha
00:05:56<ray>fat as in obese :)
00:06:20<SamB>(wouldn't be much point in it's using ext3, now would there?)
00:08:05<pumpkin>hmm
00:08:12<mcnster>example [('a',1),('b',1),('a',2)] -> [(1,['a','b']),(2,['a'])]
00:08:31<pumpkin>so what's a good strategy for "exploring" a multidimensional input space for benchmarking?
00:09:44<Cale>well...
00:10:01<pumpkin>lol, I guess it's a rather abstract question
00:10:55<Cale>> M.fromListWith (++) . map (\(x,y) -> (y,[x])) $ [('a',1),('b',1),('a',2)]
00:10:57<lambdabot> fromList [(1,"ba"),(2,"a")]
00:11:04<Cale>> M.toList . M.fromListWith (++) . map (\(x,y) -> (y,[x])) $ [('a',1),('b',1),('a',2)]
00:11:06<lambdabot> [(1,"ba"),(2,"a")]
00:11:48<pumpkin>so say I want to benchmark a function with a single-dimensional (numerical) input, I can start with 1, and multiply by 2 until it gets too slow (with a timeout), and then sample the range more or less uniformly
00:11:54<Cale>mcnster: how's that?
00:12:34<mcnster>cale, i'm in my 2nd day of being awake, so you'll excuse me if i take a moment to grok :)
00:12:44<Cale>pumpkin: Wouldn't you want a bunch of inputs of varying complexity?
00:13:12<pumpkin>Cale: yeah, that's what I mean...
00:13:48<Cale>pumpkin: Oh, I suppose you could compare algorithms by the largest input they can handle in a fixed amount of time
00:13:56<Cale>But that seems funny :)
00:14:15<pumpkin>well, the idea was to keep the benchmark to a reasonable time in all cases
00:14:29<pumpkin>because things like factorial 10000 (like what's in the ghc testsuite) aren't always possible
00:14:48<pumpkin>integer-simple would take hours to compute it in the current state
00:15:25<mcnster>@hoogle fromListWith
00:15:26<lambdabot>Data.IntMap fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a
00:15:26<lambdabot>Data.Map fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
00:15:26<lambdabot>Data.IntMap fromListWithKey :: (Key -> a -> a -> a) -> [(Key, a)] -> IntMap a
00:15:39<pumpkin>Cale: still getting a sense of the complexity and coefficients
00:17:09<pumpkin>Cale: does it seem silly?
00:17:22<Cale>pumpkin: I think it's a reasonable thing to try :)
00:17:26<ray>cale's one liner isn't especially fancy this time, he's just exploiting the natural properties of Map
00:17:42<ray>i recognize it because i was exploiting Set earlier
00:18:37<pumpkin>Cale: the idea was to write a "quickbench" that "explored" the input space with typeclasses a bit like quickcheck's Arbitrary, and presented timings from a bunch of samples in a reasonable time window
00:18:58<pumpkin>so far I have a really simple interface to 1-d exploration
00:19:53<pumpkin>but I'm trying to decide what a good way is to explore multidimensional input in such a way that will still reveal meaningful trends
00:20:25<smorg>@faq Can haskell do what haskell cannot do?
00:20:26<lambdabot>The answer is: Yes! Haskell can do that.
00:20:40<ray>the actual answer is "occurs check &c"
00:21:29<Cale>@ghc
00:21:29<lambdabot>ghc says: You can get a PhD for explaining the True Meaning of this last construct
00:21:32<Cale>@ghc
00:21:33<lambdabot>ghc says: From-type of Coerce differs from type of enclosed expression
00:21:41<Cale>@ghc
00:21:42<lambdabot>ghc says: Can't match unequal length lists
00:22:11<smorg>@gcc
00:22:12<lambdabot>ghc says: GHC internal error
00:22:49<Cale>(it's full of funny error messages and comments from GHC)
00:22:51<Cale>@ghc
00:22:52<lambdabot>ghc says: Only unit numeric type pattern is valid
00:22:55<Cale>@ghc
00:22:55<lambdabot>ghc says: On Alpha, I can only handle 4 non-floating-point arguments to foreign export dynamic
00:23:06<thoughtpolice>applicative parsers rox my sox
00:23:13<pumpkin>thoughtpolice: zomg
00:23:22<pumpkin>thoughtpolice: u dun wit flaout3?
00:23:38<ray>nice command
00:23:49<jeffersonheard_h>okay. I'm stumped. completely. stumped
00:23:49<thoughtpolice>pumpkin: ftm, beat another game too while I was playing it
00:23:57<pumpkin>lol
00:24:07<mcnster>wow, that's pretty cool. thanks again cale :)
00:24:08<smorg>@faq Can haskell help Smorg understand Haskell?
00:24:08<lambdabot>The answer is: Yes! Haskell can do that.
00:24:23<jeffersonheard_h>I've been poking at this bug in hieroglyph all day and I've solved half a dozen others, but not the one I came to solve
00:24:38<ray>@faq Can Haskell make UPS go faster?
00:24:39<lambdabot>The answer is: Yes! Haskell can do that.
00:25:27<jeffersonheard_h>does anyone care to look at why I seem to be missing saving the cache once per iteration?
00:29:44<jeffersonheard_h>I'll take that as a no
00:32:09<Cale>jeffersonheard_h: Well, if you posted a link, I would look at it, but I don't really understand what that means.
00:32:32<malouin>why is the Identity monad not Applicative?
00:32:42<Cale>malouin: Probably no good reason.
00:32:53<smorg>> [ helpers | helpers <- people in channel, elem (people paying attention), elem (people who know the answer) ]
00:32:55<lambdabot> <no location info>: parse error on input `in'
00:33:08<Cale>malouin: Other than that it existed prior to Applicative and nobody's added the instance.
00:33:23<jeffersonheard_h>Cale: thanks. I shall in a sec...
00:36:50<malouin>does instance Applicative Identity where pure = return ; (<*>) = ap make sense?
00:37:08<pumpkin>that works for all Monads
00:37:14<malouin>great!
00:37:20<pumpkin>:)
00:37:29<pumpkin>it's not necessarily the only valid instance for all Monads though
00:37:36<malouin>@src ap
00:37:36<lambdabot>ap = liftM2 id
00:37:42<malouin>ah
00:37:53<jeffersonheard_h>Cale: http://www2.renci.org/~jeff/hieroglyph/Graphics/Rendering/Hieroglyph/
00:38:47<jeffersonheard_h>the problem is either in OpenGL/Compile.hs::compileText, OpenGL/Render.hs, or OpenGL.hs in the functions that actually call render
00:39:55<jeffersonheard_h>basically i've got a texture cache for holding onto images so that youdon't have to reload them between frames. speeds things up like 10x for medium sized images.
00:41:33<jeffersonheard_h>but, the problem is that once the textures that are allocated have been expended, I start freeing textures from the cache, but they don't stay out of the cache between iterations
00:42:34<jeffersonheard_h>it's a really odd little problem. I've narrowed it down to the render function in OpenGL/Render.hs -- it has to happen before that function is finished
00:44:06<jeffersonheard_h>I thought initially it was between calls to render, but since then I've discovered that's not correct -- it happens so long as there are multiple cache misses on the same call to render
00:44:15<malouin>...so... Text.Formlets stuff is parameterized by an (Applicative m, Monad m), but I don't see why I need it, so... Identity!
00:47:37<ray>if monad were a subclass of applicative like it SHOULD be that wouldn't happen
00:48:13<ray>you can blame those fat cats on wall str-i mean, haskell 98
00:54:52<SamB>ray: we didn't HAVE applicative in Haskell 98
00:55:07<SamB>I think it's much more realistic to complain about Functor ...
00:55:15<TheColonial>:t (.*.)
00:55:16<lambdabot>Not in scope: `.*.'
00:56:08<Peaker>I think maybe Functor => Applicative => Monad subclassing is a different kind of subclassing than other kinds, in the sense that each subclass contains all the methods to be as powerful as its super-class. Maybe this kind of sub-classing does not need to be tied to the definition of the class, but define-able separately, like type-classes and instances are definable separately from types
00:56:32<ray>don't forget pointed, and i was thinking something similar
00:57:14<Peaker>The methods in the Monad class don't really depend on Applicative's methods, as you can obviously reimplement <*> and pure as ap and return -- if there's no real dependency, why should it be a class restriction? It should probably be a different kind of relationship between the classes
00:57:42<ray>it's not something that can currently be expressed in haskell
00:57:49<pumpkin>well, those should all be unified into one name?
00:57:50<ray>it should be
00:57:51<Peaker>yeah, it would be nice if it were
00:58:21<ray>ap is used infix anyway, so just having <*> would be nice
00:58:24<Peaker>pumpkin: of course, my point is that maybe a class restriction (=subclassing) is the wrong approach when your sub-class has all the power in its own methods to define all the super-class methods
00:58:30<ray>and i prefer "pure" to "return"
00:58:34<hatds>it is expressed by wrapped newtypes, basically
00:58:50<Peaker>ray: how about "wrap" ?
00:59:01<pumpkin>I don't like wrap
00:59:04<ray>i was thinking of being able to include default definitions
00:59:06<Peaker>pumpkin: why?
00:59:09<ray>i still prefer pure
00:59:13<ray>but return is terrible :)
00:59:37<hatds>what about Eq and Ord then?
00:59:54<Peaker>hatds: Similarly, I think
01:00:03<ray>and also being able to define the methods of the superclass in instance declarations for the subclass
01:00:33<ray>i should write something
01:00:34<Peaker>hatds: the question is how these class relations should be expressed. Perhaps an auto-deriving rule (That either disallows or is overridden by more-specific instances)
01:01:31<ray>if i don't write something, i can't get decisively shot down by the ghc hackers
01:02:19<hatds>I think if you took away this kind of subclassing then instance declarations would be messier... if 'a' is an instance of Eq and Ord what should the instance of Eq [a] be?
01:03:08<hatds>well, I guess just using Eq
01:04:18<Berengal>Thanks guys, you're a big help
01:04:40<Berengal>(I was about to ask a question, but in doing so the answer, which had previously eluded me for quite a while, appeared)
01:04:54<EvilTerran>hatds, well, Eq usually has a natural recursive definition for algebraic data types
01:05:05<EvilTerran>Ord likewise, to a certain extent - see deriving (Eq, Ord)
01:05:10<hatds>yea.. my example wasn't what I thought it was
01:07:03<ray>hmm, copure isn't quite as nice sounding as pure
01:07:18<pumpkin>pucore
01:07:30<EvilTerran>pureco
01:07:38<EvilTerran>... (tm) programming languages. now with more pure!
01:07:45<ray>category-extras has point and extract
01:09:20<EvilTerran>Peaker, i thought the point of the Functor (=> Pointed) => Applicative => Monad heirarchy was that each class would only contain a couple of methods, but each class's semantic equations would involve methods of its superclasses
01:10:20<ray>if you include pointed it's only one method each (bind is borderline)
01:10:24<EvilTerran>so a definition of Monad would only need join or >>=, as fmap and pure are defined by virtue of the superclass constraint
01:10:57<ray>the problem is you end up having to write 4 instances
01:10:58<SamB>EvilTerran: it would be preferable to be able to instanciate several classes in one go
01:11:27<SamB>ray: and typically, some of the superclass methods are the ones you'd want defaulted
01:12:00<ray>if we want prettiness all around, something's got to give
01:12:01<EvilTerran>i agree; got to get some class aliases going
01:12:04<EvilTerran>ACTION goes tobed
01:12:10<Berengal>SamB: Can be done by going the other way for instances: instance Monad m => Applicative m => (Pointed m) => Functor m
01:12:36<SamB>Berengal: what the?
01:12:59<hatds>I'm wary of instances which don't peel off type constructors
01:13:26<SamB>hatds: eh?
01:13:35<Berengal>SamB: making a monad instance then automatically makes the type an instance of all the other classes, with default implementations
01:14:10<SamB>Berengal: I don't think it's safe to do it that way
01:14:41<hatds>SamB: instance Eq a => Eq [a] would be an example
01:15:05<hatds>(reading right to left)
01:15:07<Berengal>instance (Monad m) => Functor m where fmap = liftM
01:15:09<SamB>hatds: well, that kind of thing doesn't make sense for Monad
01:15:14<SamB>or Applicative
01:15:18<SamB>or Functor
01:15:20<SamB>or Pointed
01:15:28<SamB>or CoPointed
01:15:33<SamB>or CoMonad
01:15:34<pumpkin>or ContraFunctor
01:15:42<hatds>SamB: which is why I'm wary of using instance declarations to express a super-class like hierarchy
01:15:43<pumpkin>or AppliCotive
01:15:45<pumpkin>;)
01:15:51<SamB>what the hell?
01:15:57<ray>ContraFunctor is fun
01:16:05<SamB>what happened to putting Co at the beginning?
01:16:15<ray>it went into cofashion
01:16:16<pumpkin>well, CoApplicative didn't feel right
01:16:22<pumpkin>SamCoB
01:16:37<Cale>Coapplicative seems good to me
01:16:48<SamB>yeah, and Alan x comaintains part of the Linux kernel
01:17:42<hatds>is there a coapplicative?
01:18:16<SamB>probably
01:18:32<SamB>in Haskell? I have no idea
01:21:27<BMeph_>Are there Pointed, non-Functor things?
01:21:41<ray>monoids?
01:22:03<byorgey>I guess it depends what you mean by Pointed.
01:22:06<BMeph_>It reminds me of everything I dislike about for Arrow.
01:22:24<BMeph_>S/for//
01:22:25<ray>i guess it depends on what you mean by non-Functor
01:22:40<byorgey>the way Pointed is usually used in a Haskell context it is an abbreviation for 'pointed functor', so the answer would be no.
01:22:53<pumpkin>ACTION pointed
01:23:00<byorgey>but you could imagine having it just mean "any type for which we can pick out a distinguished element"
01:23:26<SamB_XP>mattam: help! http://mattam.org/repos/coq/prelude/html/index.html is down!
01:24:10<BMeph_>ray, byorgey: I meant where there's an a -> p a, but not an (a -> b) -> (p a -> p b); hmm, both things are stuff to ponder. :)
01:24:20<SamB_XP>BMeph: looks like Pointed is a subclass of Functor: http://mattam.org/repos/coq/prelude/Functor.v
01:25:59<SamB_XP>well, there might be things that have a function with "point"'s signature but not "fmap"'s
01:26:15<ray>well, a -> p a is easy if you have any data constructors that take arguments
01:26:28<ray>finding things that aren't functors is probably harder
01:26:42<ray>er, finding things like that
01:27:13<byorgey>BMeph_: sure, for example, if p a = a -> Int
01:28:17<byorgey>maybe that's sort of cheating though, since the a -> p a would just have to be 'const (const 3)' or something like that
01:28:38<BMeph_>I just "know" that Pointed + Applicative gives you fmap anyway, so I'm trying to see if there's another way to put all of those types together.
01:39:13<Berengal>Well, in haskell at least Set isn't a functor, but it could be pointed... maybe...
01:39:24<mattam>SamB_XP: ah yeah... I need to regenerate the doc it seems
01:39:42<Berengal>If there was a fromSingletonSet function
01:41:56<mattam>The Pointed hierarchy comes from category-extras, I didn't invent anything.
01:42:05<pumpkin>Berengal: it could be an RFunctor
01:42:28<ray>set really is a functor, it's just that ord constraint getting in the way
01:42:36<ray>which is what pumpkin means
01:42:36<pumpkin>and that's what the R deals with
01:42:47<pumpkin>@hackage rmonad
01:42:47<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rmonad
01:42:58<BMeph>Sets can be empty, so that doesn't work. Maybe it's CoPointed, though? ;)
01:43:40<ray>other way around
01:43:52<pumpkin>I think Pointed should be called Pointy
01:43:53<pumpkin>it's cuter
01:44:23<Berengal>I think Functor should be called Functron
01:44:59<Berengal>Hmm, Applicatron also sounds nice
01:46:09<ray>i think they should be called Mappable, Purable, Appable, and Joinable
01:46:18<pumpkin>lol
01:46:33<BMeph>CT bots, from the planet Funcatron! ;p
01:46:41<Berengal>s/pure/purè/ ?
01:48:08<Berengal>We need an Acme category on hackage
01:48:48<ray>category-extras-extras: nonsense too abstract for category-extras
01:50:48<byorgey>is MonadSupply (from http://www.haskell.org/haskellwiki/New_monads/MonadSupply) packaged anywhere?
01:52:03<pumpkin>can't we just use a captcha instead of disabling signup?
01:52:11<pumpkin>(to the wiki)
01:52:44<SamB_XP>I think we should just put the name of the person you have to ask for an account in text on the page where you would ordinarily sign up
01:52:49<ray>there's a cmptcha instead
01:53:01<BMeph>pumpkin: We could if you'd hurry up and write a haskell-y captcha package! ;)
01:53:02<SamB_XP>and anyone smart enough to figure out how to email that person can have an account
01:53:14<SamB_XP>how's that for a captcha?
01:53:37<SamB_XP>(of course, they also have to ask for an account on haskellwiki in that email ;-)
01:54:01<ray>otherwise the viagra spammers would get in
01:54:11<SamB_XP>quite
02:11:26<roconnor>@djinn () -> ()
02:11:27<lambdabot>f a = a
02:13:06<sjanssen>@djinn a -> b
02:13:06<lambdabot>-- f cannot be realized.
02:14:09<pumpkin>little does djinn know, unsafeCoerce to the rescue
02:14:17<pumpkin>to prove anything and everything!
02:14:49<idnar>haha
02:14:55<idnar>ex falso, quodlibet
02:18:39<adu>@djinn (a, b) -> b
02:18:40<lambdabot>f (_, a) = a
02:18:43<roconnor>@src Const
02:18:43<lambdabot>Source not found.
02:18:57<adu>@djinn (a, b) -> a
02:18:57<lambdabot>f (a, _) = a
02:19:13<adu>@djinn a -> b -> a
02:19:14<lambdabot>f a _ = a
02:20:30<pumpkin>@@ @djinn @type on
02:20:32<lambdabot> f a b c _ = a (b c) (b c)
02:21:08<BMeph>@type on
02:21:10<lambdabot>forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
02:21:28<pumpkin>does the programmatic interface to djinn allow us to enumerate all functions?
02:21:49<SamB_XP>pumpkin: ALL functions?
02:21:55<SamB_XP>you must be kidding!
02:22:25<SamB_XP>ACTION doesn't think djinn accepts types suitable for such in any case
02:22:44<pumpkin>I meant all functions that fit :P
02:23:09<pumpkin>and yeah, even if there are infinite ones, I don't see why I shouldn't be able to enumerate them
02:23:33<SamB_XP>well, there *are* types that have countless functions
02:23:45<SamB_XP>which is to say, uncountably many
02:24:05<SamB_XP>that is, you can't give them each an ordinal
02:24:13<pumpkin>I know :P
02:24:48<pumpkin>@djinn Integer -> Integer
02:24:48<lambdabot>Error: Undefined type Integer
02:24:54<SamB_XP>yeah, I'm half kidding and half just not sure I'm using the right terminology, with my over-repetetiveness ;-)
02:26:22<pumpkin>I haven't heard much about the GSOC projects recently
02:27:07<dino->I still feel confused about seq. Specifically, when would I use it myself as opposed to using ($!)
02:27:24<pumpkin>sometimes you want to force something without evaluating a function, I guess?
02:27:35<pumpkin>*applying
02:32:19<adu>ACTION <3 λ
02:32:30<byorgey_>@src ($!)
02:32:30<lambdabot>f $! x = x `seq` f x
02:32:40<adu>byorgey!
02:32:51<byorgey_>dino-: $! is just a convenient shorthand for seq, essentially
02:32:54<byorgey_>adu!
02:33:03<adu>byorgey_: how are you doing?
02:33:26<byorgey>adu: I'm very well, enjoying summer. =) how are you?
02:33:29<adu>I started a blog, wanna see?
02:33:31<dino->But I feel like just chalking it up as seq exists basically so we can have ($!) is not right.
02:33:36<byorgey>adu: sure!
02:33:42<adu>http://straymindcough.blogspot.com/
02:33:47<adu>its about Haskell and XML mostly
02:34:02<byorgey>dino-: no, I mean, $! just encapsulates a common pattern of using seq
02:34:13<byorgey>dino-: so there's no particular reason to use seq vs. $!
02:34:21<dino->But what's the other pattern(s)?
02:34:27<dino->er, what is/are
02:34:30<monochrom>Suppose I want "f x y z" and I want to force y but not x or z. How would you write it with $! ? It's much easier with seq.
02:34:37<adu>byorgey: I also am between jobs... got an interview in 3 days
02:34:59<byorgey>adu: ah, good luck with that
02:35:07<adu>thanks
02:35:10<byorgey>adu: coming to Hac phi? =)
02:35:20<adu>byorgey: dunno, what is it?
02:35:49<byorgey>a Haskell hackathon, in Philadelphia!
02:35:50<dino->hm, so you're saying it could be y `seq` f x y z
02:35:52<byorgey>http://haskell.org/haskellwiki/Hac_%CF%86
02:36:51<byorgey>ok, off to bed, night all
02:36:58<dino->byorgey: Thank you
02:37:02<monochrom>Yes I would just write y `seq` f x y z
02:37:26<dino->monochrom: So simple, but I was having a crazy time thinking about other uses than ($!) expresses. :o
02:37:31<dino->monochrom: Thank you
02:37:50<adu>byorgey: I registered
02:38:12<pumpkin>@hoogle getCPUTime
02:38:13<lambdabot>System.CPUTime getCPUTime :: IO Integer
02:38:38<dino->As far as when you know you need these things, that's really more like you get into space leakage situation, I'm guessing. Or your profiling is pointing to it.
02:49:15<Marake>What is this channel?
02:52:35<pumpkin>I love curiosity
02:52:40<jeff_s_>why?
02:53:35<Berengal>Presumably because he hates cats
02:53:55<p_l>Berengal: or loves, depending on version
02:54:22<Berengal>p_l: Maybe a love-hate relationship?
02:55:07<p_l>Berengal: or trains future cat army :P
02:56:52<ceilingcat>ACTION iz watchin u
02:58:25<Apocalisp>> unsafePerformIO $ print "Can haz IO"
02:58:26<lambdabot> Not in scope: `unsafePerformIO'
02:58:40<ceilingcat>no can not haz IO
02:59:40<Apocalisp>ceiling cat iz watching u mutate ur data
03:00:14<pumpkin>my quickbench is working hard now
03:00:36<pumpkin>mmorrow: I haz quickbench almoast!
03:01:01<mmorrow>pumpkin: ?
03:01:22<pumpkin>my quickcheck-inspired benchmarking system
03:01:45<mmorrow>pumpkin: oh nice, so you mean you;ve almost got it packaged?
03:02:01<pumpkin>oh no, I still need to figure out some things, and I haven't been writing it as a separate library
03:02:14<pumpkin>it's just that my integer benchmarking suite got overengineered so I decided to give it a name
03:02:20<mmorrow>hehe
03:02:38<SamB_XP>lol
03:08:06<pumpkin>> maximum []
03:08:08<lambdabot> * Exception: Prelude.maximum: empty list
03:08:09<pumpkin>grr
03:08:13<pumpkin>damn partial functions
03:08:24<pumpkin>I NEED MOAR
03:09:14<thoughtpolice>pumpkin: ORLY?
03:09:18<pumpkin>YARLY
03:09:27<pumpkin>MUST HAZ MOAR
03:10:00<pumpkin>@src maximum
03:10:00<lambdabot>maximum [] = undefined
03:10:01<lambdabot>maximum xs = foldl1 max xs
03:10:50<pumpkin>@type foldl' (liftA2 max) Nothing
03:10:51<lambdabot>forall a. (Ord a) => [Maybe a] -> Maybe a
03:11:18<pumpkin>@type foldl' (liftA2 max) Nothing . map Just
03:11:19<lambdabot>forall a. (Ord a) => [a] -> Maybe a
03:12:30<thoughtpolice>oh yeah and like I said earlier: applicative parsers rox my sox
03:12:45<pumpkin>lol
03:12:50<pumpkin>which one are you using?
03:12:57<thoughtpolice>i was playing with attoparsec
03:16:59<pumpkin>clearly that function sucks
03:16:59<pumpkin>dammit
03:17:13<pumpkin>not sure why I thought it would work just cause it had the right type :P
03:17:31<pumpkin>> foldl' (liftA2 max) Nothing . map Just $ []
03:17:32<dino->pumpkin: I was just realizing that too in ghci, non workingness. :D
03:17:33<lambdabot> Nothing
03:17:37<pumpkin>> foldl' (liftA2 max) Nothing . map Just $ [1, 2, 3]
03:17:38<lambdabot> Nothing
03:17:40<pumpkin>lol
03:18:19<dino->Because the right type is so often a harbinger of success.
03:19:57<pumpkin>dammit, there must be an elegant way to write this
03:20:11<pumpkin>that doesn't involve hardcoding a Nothing for empty lists
03:20:43<pumpkin>@type maybeToList
03:20:45<lambdabot>forall a. Maybe a -> [a]
03:23:31<Berengal>pumpkin: For an extra Bounded constraint, you can have a monoid
03:23:52<pumpkin>yeah, but I don't really want one
03:24:18<pumpkin>I'm mostly working with Integers here
03:24:27<pumpkin>anyway, I just wrote a total maximum in Maybe
03:24:28<pumpkin>*sigh*
03:24:36<pumpkin>no golfing to be seen :(
03:24:52<Berengal>if' <$> null <*> const Nothing <*> foldl1' max
03:25:14<pumpkin>lol
03:25:31<pumpkin>I thought of doing something like that but didn't want to write if'
03:25:47<pumpkin>it should be in the prelude, and the if syntax should be eradicated!
03:25:54<pumpkin>it's too conventional!
03:25:56<Berengal>Indeed!
03:26:11<Berengal>We don't need no stinkin' ifs!
03:27:49<Berengal>We need a fold-with-default
03:28:14<Berengal>foldx1-with-default that is
03:28:21<Berengal>like maybe...
03:28:25<pumpkin>yeah
03:28:59<RyanT50001>has anyone tried doing OpenGL stuff on ubuntu (in haskell)?
03:29:32<Berengal>unsafePerformIO (evaluate $ Just . foldl1' max list) `catch` const Nothing
03:29:32<RyanT50001>glxgears runs fine, and the output of glxinfo doesn't have any problems (that I can detect, anyhow), but haskell-based opengl stuff is all strange
03:29:45<pumpkin>Berengal: lol, not a fan of those approaches :)
03:29:53<RyanT50001>it either flashes a lot (~30 hz) or doesn't ever redraw window borders
03:30:33<Berengal>pumpkin: That's okay, I'll put it in a library :P
03:30:43<pumpkin>oh okay, then it's fine :P
03:30:52<Berengal>ACTION creates a new file: Acme/Tricks.hs
03:31:35<Berengal>By the way, anyone have any nice instances for Acme.Orphanage?
03:32:14<SamB_XP>how about Acme.Dynamite or Acme.Fan or Acme.DistancePaintedOnABrickWall
03:32:41<Berengal>I wouldn't know what to put in them...
03:33:44<SamB_XP>but you DO know what they'll end up doing to the coyote, yes?
03:34:19<pumpkin>:t when
03:34:20<lambdabot>forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
03:34:33<pumpkin>that's an annoying type signature
03:35:00<pumpkin>why can't it be Bool -> m a -> m a ?
03:35:13<SamB_XP>because it wouldn't know what to return when NOT
03:35:21<pumpkin>stick MonadPlus on
03:35:31<SamB_XP>you mean MonadFail?
03:35:39<thoughtpolice>ACTION attemps to build ThreadScope to look at DPH programs...
03:35:50<pumpkin>MonadFail doesn't exist though :(
03:35:56<pumpkin>ceiling cat disapproves
03:36:21<mmorrow>@let f <!> a = join (f `ap` a); infixr 1 <!>
03:36:23<lambdabot> Defined.
03:36:23<SamB_XP>ACTION tries to figure out what that has to do with ^|^
03:36:46<pumpkin>@type (<!>)
03:36:48<lambdabot>forall (m :: * -> *) a a1. (Monad m) => m (a -> m a1) -> m a -> m a1
03:36:51<mmorrow>@type \f a b c d -> f <$> a <*> b <*> c <!> d
03:36:52<lambdabot>forall a a1 a2 a3 (m :: * -> *) a11. (Applicative m, Monad m) => (a -> a1 -> a2 -> a3 -> m a11) -> m a -> m a1 -> m a2 -> m a3 -> m a11
03:36:58<mmorrow>bindN
03:37:04<pumpkin>ooh
03:37:14<mmorrow>@type \f a b c -> f <$> a <*> b <!> c
03:37:15<pumpkin>I like the operator name too
03:37:16<lambdabot>forall a a1 a2 (m :: * -> *) a11. (Applicative m, Monad m) => (a -> a1 -> a2 -> m a11) -> m a -> m a1 -> m a2 -> m a11
03:37:24<mmorrow>heh, yeah it fits nicely
03:37:29<mmorrow>join!!!!
03:38:07<monochrom>/join
03:38:10<monochrom>/part
03:38:46<monochrom>Hmm! "part" could be a nice name for an operation in co-monads! part :: cm a -> cm (cm a) :)
03:39:01<mmorrow>heh
03:39:04<pumpkin>@let part x = x >>= const
03:39:06<lambdabot> Defined.
03:39:07<monochrom>question: "why is it called part?" answer: "because I learned in on IRC"
03:39:15<pumpkin>oh
03:39:23<pumpkin>dammit, I stole your comonadic operation, sorry :/
03:39:49<SamB_XP>@type part
03:39:50<lambdabot>forall b a. (b -> a) -> b -> a
03:39:54<pumpkin>:P
03:39:59<pumpkin>really useful, eh
03:40:01<SamB_XP>that's pretty dumb looking ...
03:40:04<mmorrow>> fix part
03:40:06<lambdabot> Overlapping instances for GHC.Show.Show (b -> a)
03:40:06<lambdabot> arising from a use of `...
03:40:09<mmorrow>> fix part 99
03:40:14<lambdabot> mueval-core: Prelude.read: no parse
03:40:14<lambdabot> mueval: ExitFailure 1
03:40:22<SamB_XP>@pl part x = x >>= const
03:40:22<SamB_XP> in part
03:40:23<lambdabot>part = (const =<<)
03:40:33<pumpkin>wow, that's really smart of it :P
03:40:37<SamB_XP>oh, woops
03:40:42<SamB_XP>I meant to say "let
03:40:50<SamB_XP>and not put the newline in there
03:40:59<SamB_XP>but it worked out okay ...
03:41:14<SamB_XP>but still, it's not going as far as it could!
03:41:25<SamB_XP>> part 1
03:41:26<lambdabot> No instance for (GHC.Num.Num (b -> a))
03:41:27<lambdabot> arising from the literal `1' at <...
03:41:34<SamB_XP>> part (+1)
03:41:35<lambdabot> Overlapping instances for GHC.Show.Show (b -> b)
03:41:36<lambdabot> arising from a use of `...
03:41:38<SamB_XP>> part (+1) x
03:41:40<lambdabot> x + 1
03:41:54<SamB_XP>@check ($) == part
03:41:55<lambdabot> Not in scope: `part'
03:42:03<SamB_XP>aww
03:42:13<SamB_XP>oh, but the == wouldn't have worked ...
03:44:39<pumpkin>> part (+1) 2
03:44:41<lambdabot> 3
03:44:45<pumpkin>ZOMG!
03:46:02<thoughtpolice>whoa
03:46:20<malouin>Is there some name for getting a value out of a monad, ie namethisfunc (Identity a) = a
03:46:34<roconnor>@type runIdentity
03:46:35<lambdabot>forall a. Identity a -> a
03:46:36<pumpkin>for certain specific monads yes, but not in general
03:48:01<malouin>is it usually called runMymonad?
03:48:20<malouin>I think runMonad is not what I am looking for.
03:48:21<jmcarthur>ACTION realizes he is creating something which may venture into unholy territory
03:48:22<pumpkin>@hoogle runST
03:48:23<lambdabot>Control.Monad.ST runST :: ST s a -> a
03:48:23<lambdabot>Control.Monad.ST.Lazy runST :: ST s a -> a
03:48:23<lambdabot>Data.Array.ST runSTArray :: Ix i => ST s (STArray s i e) -> Array i e
03:48:51<pumpkin>jmcarthur: quick, kill it with fire!
03:48:55<pumpkin>jmcarthur: what is it?
03:48:58<malouin>ok,nm.
03:49:17<pumpkin>malouin: but in general, it's not even meaningful to ask to get a value out of a monad
03:49:32<thoughtpolice>threadscope is really neat
03:49:38<thoughtpolice>although it does still need a lot of work
03:49:55<jmcarthur>pumpkin: some of my test code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5708#a5708
03:50:25<malouin>I think I see how this works.
03:50:54<wagle>@zow
03:50:55<lambdabot>YOU!! Give me the CUTEST, PINKEST, most charming little VICTORIAN
03:50:55<lambdabot>DOLLHOUSE you can find!! An make it SNAPPY!!
03:50:57<malouin>Incidentally, I understand that IO is a one way monad, but what is to prevent me from writing "pluckIO IO a = a"?
03:50:58<jmcarthur>essentially i'm using IO to fill in the thunks after binding the variable
03:51:03<jmcarthur>one at a time
03:51:08<pumpkin>malouin: the fact that the constructor isn't public
03:51:17<pumpkin>@hoogle unsafePerformIO
03:51:18<lambdabot>Foreign unsafePerformIO :: IO a -> a
03:51:18<lambdabot>System.IO.Unsafe unsafePerformIO :: IO a -> a
03:51:21<pumpkin>ACTION whistles
03:51:29<malouin>pumpkin: that would do it!
03:51:46<pumpkin>malouin: but in general don't use it unless it would be pure to do so otherwise (but something's in the way)
03:51:46<jmcarthur>mentally substitute True and False with Cons and Nil
03:52:06<pumpkin>malouin: it'll break some assumptions the compiler makes if you use it impurely and will lead to all sorts of headaches, it's not just a philosophical thing
03:52:11<malouin>I'm not doing that!
03:52:16<pumpkin>just making sure :)
03:52:43<malouin>I'm using formlets, it wants a monad. I gave it Identity. I wasn't sure how to get a value out of Identity.
03:52:58<aavogt>@hoogle Identity
03:52:58<lambdabot>module Control.Monad.Identity
03:52:58<lambdabot>Control.Monad.Identity newtype Identity a
03:52:58<lambdabot>Control.Monad.Identity Identity :: a -> Identity a
03:53:04<pumpkin>malouin: ah okay :)
03:53:14<malouin>so I wrote "pluckIdentity Identity a = a", but now I see that that is just called runIdentity
03:53:50<jmcarthur>with overlapping instances i could get rid of the map getValue part
03:54:09<thoughtpolice>http://img198.imageshack.us/img198/7665/threadscopeosx.png <- mac view of threadscope
03:54:16<thoughtpolice>unfortunately the interface is horribly buggy
03:54:28<thoughtpolice>but it does display the parallel execution nicely
03:54:50<jmcarthur>thoughtpolice: that's pretty sexy though
03:55:09<thoughtpolice>the binary trees dph benchmark with GHC HEAD is just as fast as parallel strategies with HEAD
03:55:16<thoughtpolice>it was a few seconds slower with 6.10.1 or so
03:55:49<thoughtpolice>although, the parallel strategies code seems to have changed a little, which is something I have not accommodated for in the dph version
03:57:22<pumpkin>we need a repeatM
03:57:32<jmcarthur>@hoogle repeatM
03:57:32<lambdabot>No results found
03:57:43<Cale>:t forever
03:57:44<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> m b
03:57:53<pumpkin>not the same though
03:58:02<jmcarthur>pumpkin: i hear no cries of terror. does my code not frighten you?
03:58:02<Cale>I suppose
03:58:19<pumpkin>jmcarthur: maybe I didn't look closely enough, let me look again :)
03:58:36<jmcarthur>i guess in a perverted way it could be considered pure. no more pure than unsafeInterleaveIO, for sure
03:58:41<Cale>I suspect there wouldn't be too many monads in which repeatM would be all that useful...
03:58:47<jmcarthur>heh
03:58:59<pumpkin>there are several monads for which forever is pretty useless too aren't there?
03:59:17<jmcarthur>@src forever
03:59:17<lambdabot>Source not found. Have you considered trying to match wits with a rutabaga?
03:59:20<Cale>> (sequence . repeat $ reverse) "hello"
03:59:22<lambdabot> ["olleh","olleh","olleh","olleh","olleh","olleh","olleh","olleh","olleh","o...
03:59:31<Cale>It works in Reader
03:59:41<Cale>and probably Identity
04:00:05<pumpkin>I'm looking for something I can feed randomRIO to
04:00:08<jmcarthur>:t iterateM
04:00:09<lambdabot>Not in scope: `iterateM'
04:00:10<Cale>pumpkin: But with forever, the focus is on effects, since it never produces a result.
04:00:15<pumpkin>yeah, exactly
04:00:25<jmcarthur>@hoogle iterateM
04:00:25<lambdabot>No results found
04:00:30<jmcarthur>i thought one existed...
04:00:44<Cale>So it's actually useful in all the monads in which repeatM is useless, and vice versa.
04:00:52<pumpkin>jmcarthur: I don't quite get it, although I sort of see what's happening
04:01:03<jmcarthur>pumpkin: not sure if you saw my explanation earlier
04:01:21<pumpkin>oh I see
04:01:43<pumpkin>sort of a mutable list?
04:01:49<jmcarthur>not mutable
04:01:50<jmcarthur>write-once
04:01:53<pumpkin>ah
04:01:54<jmcarthur>from IO
04:02:02<pumpkin>what if you write twice?
04:02:03<jmcarthur>but the list itself is a pure value
04:02:09<jmcarthur>epic fail if you write twice
04:02:18<pumpkin>seems like you could stick it in ST in that case
04:02:33<jmcarthur>the point is that you can pass the list around before it is complete
04:02:36<pumpkin>ah
04:02:37<jmcarthur>as a pure value
04:02:44<pumpkin>oh
04:03:10<pumpkin>so it's like passing around a volatile explosive
04:03:13<jmcarthur>since it is built one thunk at a time, you can even use parts of it when other parts aren't done
04:03:23<jmcarthur>basically
04:03:51<pumpkin>I feel there should be a minimumMaximum function
04:05:08<pumpkin>@src sequence
04:05:09<lambdabot>sequence [] = return []
04:05:09<lambdabot>sequence (x:xs) = do v <- x; vs <- sequence xs; return (v:vs)
04:05:09<lambdabot>--OR
04:05:09<lambdabot>sequence xs = foldr (liftM2 (:)) (return []) xs
04:08:14<jmcarthur>there, comments http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5708#a5710
04:22:17<RyanT50001>is there any way to get -prof to output wall-clock time instead of user time?
04:22:47<RyanT50001>(i'm trying to track down why something's spending ~99.9% of its time blocking)
04:24:37<pumpkin>what's an efficient way of taking the elements of a list until the sum that far exceeds a particular value?
04:25:10<RyanT50001>pumpkin: using an accumulator?
04:25:20<RyanT50001>there's probably some syntactically-awesome way of doing that that i don't know
04:25:31<pumpkin>well, I'd prefer not to recurse by hand
04:25:58<pumpkin>I guess I could foldl and stop asking for the next element
04:26:52<pumpkin>but then I'd need to build the list myself
04:26:56<ClaudiusMaximus>> let xs = [1,2,3,4] in takeWhile ((<5) . fst) (zip (scanl1 (+) xs) xs)
04:26:57<lambdabot> [(1,1),(3,2)]
04:27:14<pumpkin>yeah, I thought of the scanl but that seemed inefficient
04:27:18<pumpkin>or is it not?
04:27:30<pumpkin>I guess it wouldn't be
04:30:20<dibblego>how can one use lambdabot to quantify on functions using @check since overlapping instances for Show?
04:30:54<sjanssen>dibblego: fix lambdabot's imports?
04:32:24<dibblego>I wonder why there were broken
04:32:38<sjanssen>it's been like that for some time
04:42:38<pumpkin>is there a good way to get unsafeInterleaveIO to get me part of a mapM on an infinite list?
04:42:54<pumpkin>or is that not what it does?
04:43:52<ClaudiusMaximus>@src getContents
04:43:53<lambdabot>getContents = hGetContents stdin
04:44:16<ClaudiusMaximus>@src hGetContents
04:44:16<lambdabot>Source not found. Your mind just hasn't been the same since the electro-shock, has it?
04:45:54<ClaudiusMaximus>> let a 0 n k = (n+1, k+1) ; a m 0 k = a (m-1) 1 (k+1) ; a m n k = let (a', k') = a m (n-1) k in a (m-1) a' (k' + 2) ; work m n = snd (a m n 0) in work 3 3
04:45:55<lambdabot> 3619
04:46:00<pumpkin>ah well, I can just replicateM it
04:46:24<ClaudiusMaximus>is there a name for that function (amount of work done by ackermann's function)?
04:59:04<Hunner>ACTION wonders how `func x | "foo" `isPrefixOf` x = ...` works
05:04:48<Berengal>@src mapM
05:04:49<lambdabot>mapM f as = sequence (map f as)
05:05:04<Berengal>@src sequence
05:05:04<lambdabot>sequence [] = return []
05:05:04<lambdabot>sequence (x:xs) = do v <- x; vs <- sequence xs; return (v:vs)
05:05:04<lambdabot>--OR
05:05:04<lambdabot>sequence xs = foldr (liftM2 (:)) (return []) xs
05:17:10<RyanT50001>so, i'm profiling this program, and i run it for like 30 seconds
05:17:34<RyanT50001>and then the profiling output says that it's been running for .06 seconds
05:17:46<RyanT50001>3 ticks @ 20ms/tick
05:17:58<RyanT50001>i presume it's blocking on something
05:18:02<RyanT50001>how can i debug this?
05:18:54<asoare>hi guys, I'm having a problem with gtk2hs, can someone please help me ? http://pastebin.com/d67647e90 - nothing happens when I select a file :-s
05:20:36<araujo>asoare, i recommend you to use fileChooserDialog
05:21:28<asoare>araujo: make a button and onClicked => launch a fileChooserdialog ?
05:21:45<sclv_>RyanT50001: does it use mvars?
05:21:48<araujo>ACTION also points asoare to check the himerge code which use extensively these functions
05:21:58<sclv_>or does it use io? and if so does it use -threaded?
05:22:01<RyanT50001>sclv_: almost certainly; it's FRP
05:22:24<sclv_>does it use Reactive?
05:23:01<RyanT50001>sclv_: yeah
05:23:05<asoare>thanks
05:23:23<sclv_>is it a problem that it blocks, or is it just weird profiling output?
05:23:33<RyanT50001>it's a problem that it blocks
05:23:41<RyanT50001>it should be an FPS display
05:23:52<RyanT50001>but it only updates like once every 10 seconds at best
05:24:36<sclv_>sorry i don't have better advice, but i'd start by simplifying it, and especially looking for recursive dependencies.
05:24:39<araujo>asoare, fileChooserDialog already connects signals to buttons
05:24:51<RyanT50001>sclv_: well, the problem is that my code is quite simple
05:25:05<RyanT50001>sclv_: and i'm really looking to improve Reactive itself
05:25:09<araujo>asoare, so yeah, you only need to create the fileChooserDialog and connects a signal handler to it
05:25:13<RyanT50001>i.e.: by making situations like this harder to run into
05:25:18<RyanT50001>and i also want to understand reactive
05:25:35<RyanT50001>so i want to figure out how to track down whatever's blocking, if possible
05:25:52<RyanT50001>is there really no way to track wall-clock time in the Haskell profiler?
05:26:35<asoare>araujo: i want a main window, with a few buttons and when I press a button I want it to launch a FileChooserDialog, so I think I need my buttons as well :)
05:26:49<sclv_>the one thing i can think of is defining lots of trace calls (carefully, so they evaluate each time a value is updated, say) and littering them about.
05:27:26<sclv_>attaching them to your various reactive values.
05:27:30<RyanT50001>sclv_: hm, alright
05:28:30<araujo>asoare, the fileChooserDialog includes its own buttons ..... you specify them during its creation
05:29:09<araujo>asoare, now, if you are talking about other buttons, sure, you need to create other widgets buttons manually, but the fileChooserDialog makes this easy for its own buttons, it is pretty standard
05:29:24<asoare>araujo: yes, I know what you're talking about, but I need other windows apart from the Dialog in my program, anyway, I know what to do, thanks for you help ;)
05:29:54<pumpkin>ugh, underscored module names! http://hackage.haskell.org/packages/archive/game-tree/0.1.0.0/doc/html/Data-Tree-Game_tree-Game_tree.html
05:30:12<araujo>asoare, correct, if you need more buttons in other widgets, you have to do them manually, fCD is just a convenient function for a standard file chooser, welcome
05:37:35<Cale>asoare: glade is a handy way to create user interfaces if you're using gtk2hs
05:43:21<mxc>good morning..
05:43:41<mxc>just curious, performance wise, how does Rational compare with Floats and Doubles?
05:44:33<mxc>since it uses Integers and not Ints, seems like it might be worse.. on the other hand, integer ops are faster than floating point, so not sure
05:45:57<sjanssen>mxc: they probably compare rather poorly
05:46:22<sjanssen>mxc: the fraction is simplified after each operation, which isn't terribly fast
05:46:24<quicksilver>very poorly I imagine.
05:46:50<ClaudiusMaximus>@hoogle Double -> Rational
05:46:51<lambdabot>Prelude toRational :: Real a => a -> Rational
05:46:51<lambdabot>Data.Ratio approxRational :: RealFrac a => a -> a -> Rational
05:46:51<lambdabot>Prelude floatRadix :: RealFloat a => a -> Integer
05:46:59<quicksilver>integer ops aren't *that* much faster than floating point, if your code generator is good.
05:48:19<mxc>thinking about it, arb precision int ops are probably worse
05:49:54<quicksilver>much worse, yes.
05:49:59<quicksilver>they involve function calls!
05:50:22<_willard>Can anyone answer a quick question? I am looking for a function in the standard library which tokenises (splits into parts) a list according to a predicate. It would (ideally) have the type (a -> Bool) -> [a] -> [[a]]. Any ideas?
05:50:41<Tsion>@hoogle (a -> Bool) -> [a] -> [[a]]
05:50:42<lambdabot>Distribution.Simple.Utils breaks :: (a -> Bool) -> [a] -> [[a]]
05:50:42<lambdabot>Prelude dropWhile :: (a -> Bool) -> [a] -> [a]
05:50:42<lambdabot>Prelude filter :: (a -> Bool) -> [a] -> [a]
05:51:13<ClaudiusMaximus>@hoogle Data.List.Split
05:51:14<lambdabot>Data.List splitAt :: Int -> [a] -> ([a], [a])
05:51:14<lambdabot>Data.List genericSplitAt :: Integral i => i -> [b] -> ([b], [b])
05:52:00<ClaudiusMaximus>@type groupBy
05:52:01<lambdabot>forall a. (a -> a -> Bool) -> [a] -> [[a]]
05:52:10<mornfall>Almost. :)
05:52:39<mornfall>_willard: Does your predicate say True -> drop this element and break the list here?
05:53:20<mornfall>_willard: (with groupBy, the predicate says False -> break between these two elements...)
05:54:10<mxc>weir,d i couldn't find breaks
05:54:16<mxc>I just stick this in my code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5717#a5717
05:54:25<_willard>mornfall: @True->drop: That would be preferable, although the reverse case would be easy to work with as well.
05:54:27<mornfall>mxc: It's in the Cabal lib.
05:54:56<mornfall>_willard: Well, the question is whether you want to drop and break, or break between elements. The former case is probably not in the standard lib for whatever reason...
05:55:09<mornfall>It does exist for bytestrings though.
05:55:32<mxc>mornfail: I realize from the module, but i'm looking for that function in the haddock docks for that module and dont see it
05:55:41<mxc>i'm on 6.10.1, i wonder if its new
05:56:03<mxc>(about it being in the cabal libs)
05:57:24<mornfall>Dunno.
06:00:33<_willard>mornfall: Great, thanks
06:01:00<mornfall>The best I invented so far is split p = map (dropWhile p) . groupBy (curry $ not . p . snd) :)
06:03:48<_willard>mornfall: Then this makes for a challenging exercise for my students ;-)
06:04:13<_willard>mornfall: (... one they cannot easily Google away from, at least)
06:04:48<mornfall>:)
06:06:10<_willard>mornfall: I got filter (/= " ") (groupBy (\x y -> x /= ' ' && y /= ' ') "Hello, Dolly") , although that runs through the list twice.
06:06:34<_willard>mornfall: (umm, "Hello, Dolly" is a test string)
06:11:48<mornfall>_willard: Hard to reformulate with a generic predicate though, seems to me.
06:11:57<mornfall>Anyway, breakfast time. :) See you around...
06:13:50<Hunner>What do I need to put on the command line to use this: "Could not find module `Control.Monad.Reader' it was found in multiple packages: monads-fd-0.0.0.1 mtl-1.1.0.2"
06:14:43<Berengal>_willard: The "split" package provides for most of your splitting needs
06:15:14<_willard>mornfall: @ generic predicate: The definition tok t xs = filter (/= [t]) (groupBy (\x y -> x /= t && y /= t) xs) should work ;-)
06:17:32<_willard>Berengal: Got it. Thanks
06:20:04<BMeph>@unpl liftM2 (&&) (/= ' ')
06:20:05<lambdabot>(\ e -> (\ f -> f /= ' ') >>= \ b -> e >>= \ a -> return (b && a))
06:20:51<sjanssen>Hunner: -package mtl or monads-fd, whichever you intend to use
06:21:44<Hunner>thanks
06:22:10<Hunner>or -hide-package for the one I'm not
06:23:51<quicksilver>Wild_Cat: I note that it's "wrong" to use groupBy that way.
06:23:58<quicksilver>_willard: oops that was for you.
06:24:27<quicksilver>_willard: the spec for groupBy only covers the case where the predicate is a binary equivalence relation. If you use it elsewise, it may choose to emit nasal demons.
06:41:30<mxc>hi byorgey_
06:41:46<mxc>was curious, who's your advisor at penn?
07:26:18<jinjing>@bot
07:26:18<lambdabot>:)
07:26:18<lunabot> :)
07:56:01<rob__>is there a way to print every a in [a] in a new line, given that a is showable?
07:56:25<shachaf>@ty mapM_ print
07:56:26<lambdabot>forall a. (Show a) => [a] -> IO ()
07:56:39<Zao>@src print
07:56:40<lambdabot>print x = putStrLn (show x)
08:02:01<rob__>can I use this IO monad in an instance declaration of Show?
08:08:51<Zao>rob__: That depends on what you mean.
08:09:28<Zao>If you're talking about the implementation of "show" for Show YourType, unlikely.
08:09:32<Zao>@src Show
08:09:33<lambdabot>class Show a where
08:09:33<lambdabot> showsPrec :: Int -> a -> ShowS
08:09:33<lambdabot> show :: a -> String
08:09:33<lambdabot> showList :: [a] -> ShowS
08:11:09<integral>@type unsafePerformIO
08:11:09<lambdabot>Not in scope: `unsafePerformIO'
08:11:09<Zao>As it's pure, you can't run IO actions inside.
08:11:09<Zao>(unless you unsafePerform it, but you most probably do not need or want to)
08:11:09<Zao>Escape hatches are rather useless if you don't need to run away :P
08:11:11<rob__>I want to print a binary tree, and each level in a new line, so I was trying to define Show for the Tree
08:12:07<mmorrow>what's people opinion on which endianness to choose for bitmasks (they cannot depend on the endianness of the system)?
08:12:13<Zao>rob__: So spit out a String with newlines in it.
08:12:25<mmorrow>(context: you're writing a program that has to make this choice)
08:12:45<Zao>instance Show Pie where show x = "omg\nlol"
08:12:46<mmorrow>i kinda want to go with little
08:13:05<rob__>Zao: so does this only work with strings, or with all a's that are showable?
08:13:17<Zao>show shouldn't print anything by itself, it should just provide a String suitable for displaying.
08:13:26<Zao>rob__: Eh?
08:13:54<Zao>(mapM_ print) will work with any a that has a Show instance.
08:14:02<mmorrow>ACTION goes with big
08:14:18<rob__>Zao: instance (Show a) => Show (Tree a) where ...?
08:14:55<Zao>instance Show Tree where show tree = ...
08:15:39<Zao>Similarly formatted to the class lambdabot showed above, but with instance instead of class, your concrete type instead of a, and function bodies.
08:16:15<Zao>You can do whatever you want inside the show :: a -> String function, as long as you get a nice and shiny String out of it in the end.
08:17:34<rob__>Does this still work with a (Tree a) datatype?
08:18:38<mmorrow>if (Show a)
08:19:14<mmorrow>rob__: i wouldn't use Show for that
08:19:45<rob__>mmorrow: what would you use?
08:19:47<mmorrow>personally i'd just translate your tree type to Data.Tree and then use its excellent drawTree function
08:20:03<mmorrow>@type putStrLn . drawTree . fmap show
08:20:05<lambdabot>forall a. (Show a) => Tree a -> IO ()
08:20:35<mmorrow>, text . drawTree . fmap show $ Node 0 [Node 1 [], Node 2 []]
08:20:38<lunabot> 0
08:20:38<lunabot> |
08:20:38<lunabot> +- 1
08:20:53<rob__>I didn't know about that, thanks for the tip
08:20:56<mmorrow>(or just snake the drawTree function from the Data.Tree src)
08:20:56<Zao>Making your own nicely indenting pretty printing tree display function is bothersome.
08:21:22<mmorrow>yeah, it's definitely a pita
08:23:55<rob__>ok I'm glad it's not trivial
08:27:55<Yrogirg>Hello! How to convert Int64 to Int?
08:28:03<Lemmih>Yrogirg: fromIntegral.
08:35:31<quicksilver>be aware that on a 32bit platform that is a lossy conversion.
08:35:38<quicksilver>on a 64bit platform is should compile down to a nop.
08:36:16<ClaudiusMaximus>> (maxBound,maxBound)::(Int,Int64)
08:36:17<lambdabot> (9223372036854775807,9223372036854775807)
08:36:25<quicksilver>LB is on a 64bit platform.
08:36:38<mmorrow>, (maxBound,maxBound)::(Int,Int64)
08:36:40<lunabot> (2147483647,9223372036854775807)
08:42:20<zeno>is there a version of haskell for the jvm?
08:42:40<zeno>or arm
08:42:43<ivanm>no
08:43:56<quicksilver>there have been three or four projects for haskell on the jvm
08:44:08<quicksilver>they're all more-or-less dead but they might be ressurectable
08:44:20<quicksilver>GHC does compile on arm.
08:44:28<quicksilver>there is a package in debian-arm, for example.
08:44:29<quicksilver>It's slow.
08:44:50<zeno>ah ok thx
08:45:11<doserj>debian has hugs for arm, too
08:45:23<quicksilver>hugs is in pretty portable C
08:45:28<quicksilver>it compiles for most platforms.
08:46:04<psygnisfive>hm
08:46:09<psygnisfive>i had an idea! :o
08:46:09<zeno>more practical just to ssh into my home box i guess
08:46:39<psygnisfive>it might actually already be implemented in haskell, i dont really know, but
08:47:07<Ferdirand> -
08:47:24<ClaudiusMaximus>my implementation of untyped lambda calculus does roughly the same amount of work to calculate factorial 4, fib 6, and ackermann 2 3, - any ideas for similar-cost functions i might try out?
08:47:55<psygnisfive>hm.. well, actually, it might be identical to CPS, so nevermind :D
08:51:50<dirk_>after one week of Hasekll I can finally parse nested tables, something I thought I would never manage
08:51:51<zeroflag>!seen mauke
08:51:58<zeroflag>mmh?
08:52:03<zeroflag>don't you guys have a bot?
08:52:12<cizra>nope. No bots here. Pass along.
08:52:19<zeroflag>:\
08:52:22<abbe>@slap zeroflag
08:52:22<lambdabot>ACTION hits zeroflag with a hammer, so they breaks into a thousand pieces
08:52:24<purplepenguins>there is lambdabot
08:52:34<zeroflag>can anybody tell me if mauke has been active in the past couple of days?
08:52:39<zeroflag>been trying to reach him.
08:52:44<zeroflag>@seen mauke
08:52:44<lambdabot>mauke is in #xmonad and #haskell. I don't know when mauke last spoke.
08:52:51<zeroflag>damn.
08:54:43<ivanm>dirk_: how do you define a "nested table"? i.e. what are you calling a table?
08:54:56<ivanm>preflex: seen mauke
08:54:56<preflex> mauke was last seen on #perl 10 hours, 34 minutes and 9 seconds ago, saying: hmm, now I get no output at all
08:55:01<ivanm>@uptime
08:55:01<lambdabot>uptime: 2d 5h 26m 9s, longest uptime: 1m 10d 23h 44m 29s
08:55:13<ivanm>OK, mauke has just been avoiding haskellers then
08:55:42<zeroflag>well, he joined you haskellers because the perl "compiler" was somehow using haskell...
08:55:46<zeroflag>:P
08:55:57<ivanm>ummmm..... no?
08:56:08<ivanm>isn't pugs just an interpreter for perl6?
08:56:16<ivanm>with "perl" usually taken to mean pearl5?
08:56:17<zeroflag>dunno what it is.
08:56:32<zeroflag>yeah, I meant perl6.
08:56:35<ivanm>*perl5
08:56:50<zeroflag>perl5 is a write-only language that's almost as terrible as C++.
08:57:41<dirk_>ivanm paste http://de.wikibooks.org/wiki/Benutzer:Dirk_Huenniger/haskell
08:58:22<ivanm>ahhhhh
08:58:35<dirk_>what?
08:58:48<ivanm>ahhhh == I understand what you're talking about now
08:58:49<ivanm>;-)
08:59:21<ivanm>though I don't think your data structure is necessarily the best approach... (that is, using lists everywhere; that could just be the way it's printed there though)
09:00:03<dirk_>don't understand: that could just be the way it's printed there though?
09:00:31<ivanm>yeah
09:00:57<dirk_>I did not understand what you meant with that sentences
09:01:02<dirk_>-s
09:02:28<ivanm>at first glance, the way you represent the tables in Haskell looks a bit weird
09:02:37<dirk_>maybe
09:02:42<ivanm>but that could just be the way you've printed/pasted it there
09:03:24<dirk_>I want to write latex files in the end
09:03:40<ivanm>ahhh
09:12:22<mmorrow>heh, this could be useful... from ghc's nativeGen/PprBase.hs http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2671#a2671
09:12:58<Berengal>I need a map that can be indexed by different keys... how do I do this best?
09:13:09<Berengal>The simple solution is to simply use more than one map...
09:13:10<mmorrow>what does that mean?
09:13:18<mmorrow>oh
09:13:40<Berengal>But it's not optimal... you'd have to make sure to update the other maps as well when one is changed
09:13:42<mmorrow>are they all the same type?
09:13:47<mmorrow>(the keys)
09:14:06<Berengal>No, but the keys can all be created from the values
09:14:28<mmorrow>so how many different keys do you need then?
09:14:33<mmorrow>(different types of...)
09:14:50<mmorrow>(because if that's fixed then i have one idea)
09:14:51<Berengal>Take for example data Person = Person {firstName, lastName :: String, phoneNumber :: Int}, then create a map that can be indexed by lastName or phoneNumber
09:15:16<mmorrow>oh, so you're looking the make a bunch of indexes here, similar to a db
09:15:21<mmorrow>s/the/to/
09:15:26<Berengal>Yes, very similar to a db
09:15:26<mmorrow>i've used:
09:15:31<Berengal>Except a db would be overkill...
09:15:38<mmorrow>err, lemme paste
09:15:43<Berengal>And I'd rather it not live in IO
09:15:59<mmorrow>oh no need
09:15:59<quicksilver>make a bunch of maps and stick them in a data structure
09:16:11<quicksilver>and have functions which update them all at once
09:16:17<quicksilver>(and don't cheat and update them by hand)
09:16:25<mmorrow>the beauty of indexes too is that when you do queries, you get to union/isect/diff the *index* maps
09:16:40<Berengal>quicksilver: Yes, that's the fixed version of the simple solution. I'm just wondering if there's a more elegant one
09:16:42<mmorrow>then after all those shenanigans are done, you finally index into the real map
09:18:19<quicksilver>Berengal: I'm not sure if that's inelegant.
09:18:30<quicksilver>I certainly don't know of a super-clever multi-way map
09:18:39<quicksilver>and I don't offhand see how it could be significantly different.
09:18:55<mmorrow>Berengal: err, so here's just the whole module http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2672#a2672
09:19:00<Berengal>quicksilver: I didn't say it was inelegant, I just wondered if there's an even more elegant way to do it...
09:19:00<quicksilver>perhaps you could treat the different keys and different dimensions and preternd it was a spetial indexing problem.
09:19:01<mmorrow>so the highlights are:
09:19:20<mmorrow>type Ix k = Map k IntSet
09:20:05<Berengal>Ah, so the values proper are indexed by int, with a bunch of key -> int maps?
09:20:07<mmorrow>and suppose you want to query "where phonenumber = 18273464387 and name in ('mitch','sally')"
09:20:40<mmorrow>==> look up the locations of the recs for that phonenumber in the phonenumber index
09:20:54<mmorrow>then look up both mitch and sally in the name map
09:21:09<quicksilver>I think mmorrow's is just a refinement to explicitly permit multiple values to have the same key.
09:21:11<mmorrow>and union mitch and sally, and intersect that with phonenumber
09:21:18<quicksilver>It could easily just be Map k [v], couldn't it?
09:21:26<quicksilver>you just get worse complexity on the [v]
09:21:35<mmorrow>quicksilver: actually that won't work, because
09:21:54<mmorrow>what if you have *more that one* key? you have to dup vals
09:22:15<mmorrow>(but if you don't care about duplicating the values in each map, then you could do that i suppose)
09:22:31<mmorrow>oh, and the value map that i'm assuming is:
09:22:36<mmorrow>IntMap value
09:22:51<mmorrow>and the IntSets are sets of indexes into *that* map
09:23:48<Berengal>This looks even more powerful than what I need
09:24:21<mmorrow>Berengal: i like that general idea though
09:24:51<mmorrow>data DB k v = DB {dat :: IntMap v, indexes :: [Map k IntSet]}
09:25:05<Berengal>Yeah, I like it too. It's the dbs without the annoying parts
09:25:11<mmorrow>(where you've done something like data Key = StringK String | IntKey Int | ...)
09:25:35<mmorrow>queries are pretty efficient this way too
09:25:56<Berengal>Looks like it needs a bit of wrapping though, to make a cleaner interface to what I need
09:26:16<Berengal>But shouldn't be too difficult
09:26:21<mmorrow>totally
09:26:46<Yrogirg>I still cant understand what to to do. I have:
09:26:46<Yrogirg>toInt :: Integer -> Int
09:26:46<Yrogirg>toInt a = fromIntegral a
09:26:46<Yrogirg>toInt $ BL.length (encode points)
09:26:46<Yrogirg>and I get:
09:26:47<Yrogirg>Couldn't match expected type `Integer' against inferred type `GHC.Int.Int64'
09:27:03<Berengal>Essentially, I'd want something like 'createMap [lastName, phoneNumber]' to create an empty map...
09:27:31<mmorrow>Berengal: exactly. my equiv of that in that module is:
09:27:35<mmorrow>index :: (Ord v) => [(id, a -> v)] -> [a] -> [(id, Ix v)]
09:27:43<MyCatVerbs>Yrogirg: you want to just write fromIntegral $ BL.length (encode point)
09:27:50<mmorrow>(type Ix k = Map k IntSet)
09:28:12<integral>:t fromIntegral
09:28:14<lambdabot>forall a b. (Integral a, Num b) => a -> b
09:28:23<MyCatVerbs>Yrogirg: the type signature you put on toInt makes it only work on Integers specifically, but BL.length returns an Int64.
09:28:25<quicksilver>mmorrow: OK. I think it's a small refinement on my suggestion, but yes I agree.
09:28:26<mmorrow>Berengal: err, so that `index' function only does half of the work your `createMap' would do
09:28:59<mmorrow>quicksilver: yes totally, they'd accomplish the same thing, differing only in efficiency
09:29:42<mmorrow>hmmm, actually they differ also in that the separate-index approach support queries with AND and OR
09:29:54<quicksilver>my approach was also separate-index.
09:30:00<Yrogirg>thanks, it works now
09:30:01<mmorrow>hmm
09:30:04<mmorrow>ohhh, i see ok
09:30:06<quicksilver>I just wasn't doing the clever IntSets-as-values part
09:30:11<quicksilver>which is a natural refinement.
09:30:20<mmorrow>i gotcha, yeah they're the same thing then
09:30:22<Berengal>mmorrow: I should be able to either easily make the rest, or steal the idea to build what I want easily
09:30:46<mmorrow>Berengal: cool! yeah that module/general-idea has worked really nicely for me
09:31:07<Berengal>mmorrow: Much obliged :)
09:42:02<ManateeLazyCat>Hi, all. In code "date Page = forall a . PageBuffer a => Page {pageBuffer :: a}", what's mean `forall`? I know it's a keyword, someone can explain that when time use `forall`? Thanks!
09:42:25<quicksilver>ManateeLazyCat: it means that constructor works for all types a
09:42:38<quicksilver>:t map
09:42:39<lambdabot>forall a b. (a -> b) -> [a] -> [b]
09:42:46<quicksilver>ManateeLazyCat: just like map works for all types a and b
09:42:48<quicksilver>hence "forall"
09:43:01<dcoutts>Page :: PageBuffer a -> Page
09:43:27<dcoutts>ie the Page data constructor (when looked at as a function) has that type
09:43:36<dcoutts>note that the 'a' does not appear in the result type
09:43:48<dcoutts>so it's effectively hidden
09:43:57<BONUS>usually you'd do data Page a = Page {pageBuffer :: a}, but if you don't want the type parameter and only need to assume that the a is part of the PageBuffer typeclass, you can kind of transfer the a to the other side of =
09:44:15<dcoutts>erm, Page :: PageBuffer a => a -> Page
09:44:17<BONUS>so the type is Page instead of Page Int, Page Char, etc.
09:46:11<dcoutts>ManateeLazyCat: in GADT syntax we'd write it:
09:46:15<dcoutts>data Page where
09:46:16<dcoutts> Page :: PageBuffer a => a -> Page
09:46:27<ManateeLazyCat>dcoutts: Yep, i use GADTs for solution my problem.
09:46:50<ManateeLazyCat>dcoutts: And someone help me that use this style.
09:46:52<BONUS>you don't need the forall if you use GADT syntax? cool, i didnt know that
09:47:01<dcoutts>the forall there is implicit (I think), because the 'a' isn't in scope at the top
09:47:18<ManateeLazyCat>BONUS: No, i need forall.
09:47:38<ManateeLazyCat>BONUS: "data Page a = ... " is can't fix my problem.
09:47:52<BONUS>i mean if you use GADT syntax, the forall is implicit
09:48:04<BONUS>otherwise with normal ADT syntax you need it yeah
09:49:20<ManateeLazyCat>ACTION pasted "my code" at http://paste2.org/get/256982
09:49:23<ManateeLazyCat>Above is my code.
09:49:31<ManateeLazyCat>that use forall
09:50:13<ManateeLazyCat>If i need get `pageBuffer` from page, i can write code "case page of Page {pageBuffer = x} -> do something with `x`"
09:54:34<ManateeLazyCat>Before this solution, i found "data Page a = ..." (GADTs) is not i want, because i can't store Page object in other data structure, i can't reference Page instance. And "data Page = forall a . PageBuffer a => ..." is i want, and GADTs puzzle me long time.
09:58:01<quicksilver>BONUS: well, the forall is implicit in normal ADT syntax too. Unfortunately it's implicit in the wrong place ;)
09:58:02<dirk_>can I split a list with respect to a predicate?
09:58:12<quicksilver>:t break
09:58:13<lambdabot>forall a. (a -> Bool) -> [a] -> ([a], [a])
09:58:16<BONUS>haha that's true
09:58:27<dirk_>ok
09:58:41<ziman>:t partition
09:58:42<BONUS>there's also span and partition
09:58:42<lambdabot>forall a. (a -> Bool) -> [a] -> ([a], [a])
09:58:58<dirk_>it breaks into pairs
09:59:10<dirk_>but I want it to break into a list of lists
09:59:19<quicksilver>you have to call it repeatedly then.
09:59:36<Berengal>Or use Data.List.Split
09:59:36<quicksilver>there are some functions on hackage in Data.List.Split
09:59:37<ManateeLazyCat>Thanks all for detail explain! :)
09:59:41<ziman>or use unfoldr
09:59:47<dirk_>so "aa|asa|aswe" -> ["aa","asa","aswe"]
09:59:55<dirk_>looking at it
10:00:30<ManateeLazyCat>Now i remove all code that use Dynamic, Dynamic is evil...
10:00:45<quicksilver>Dynamic is a sledgehammer
10:00:59<quicksilver>it's normally nicer to use your own existential, or even just an enumeration.
10:01:09<quicksilver>Dynamic is like the 'magic all-seeing existential'
10:01:20<Berengal>Sometimes you've got big nails...
10:01:29<quicksilver>but it's almost always nicer to use something more specific.
10:01:43<quicksilver>Berengal: If you become too fond of your sledgehammer, everything looks like a big nail.
10:02:10<ziman>I don't understand why -cafe and everything is full of Typeable and Dynamic, i'd definitely consider it bad style; when is it really necessary?
10:02:28<ziman>can't people just use plain old ADTs?
10:02:43<Berengal>When all you've got is a fully automatic 12-gauge, everythink look like zombies
10:03:10<Berengal>Also, your spelling turns bad
10:03:22<ManateeLazyCat>quicksilver: Before i use "data Page = forall a. PageBuffer a => {pageBuffer :: a}", i use "data Page = {pageBuffer :: Dynamic}", when i use pageBuffer from Page, i need use "case pageBufferType of TypeA -> x :: A; TypeB -> x :: B;", and those code ugly.
10:03:41<feret_mercedes>it could be the greatest
10:03:47<feret_mercedes>haskell forth and common lisp
10:03:48<BONUS>> unfoldr (\xs -> let (a,b) = break (=='|') xs in guard (not $ null xs) >> Just (a, drop 1 b)) "saf|asf|af"
10:03:50<lambdabot> ["saf","asf","af"]
10:03:55<feret_mercedes>what other langs offer power?
10:03:59<quicksilver>ManateeLazyCat: yup.
10:04:25<dirk_>ok thank you, but will try to use a library function
10:04:42<BONUS>yeah i suggest doing that too
10:04:46<ManateeLazyCat>quicksilver: I'm happy now, because i just use one line replace 30 line that use Dynamic. And code is clearer.
10:05:07<quicksilver>;)
10:05:40<ManateeLazyCat>quicksilver: Haskell is pretty cooool, but it's puzzle me long time... :)
10:05:56<quicksilver>;)
10:05:58<ManateeLazyCat>quicksilver: Now continue explore Haskell....
10:09:43<ManateeLazyCat>ACTION I think i need ask more in haskell-cafe... or else i'm still puzzle now.
10:11:51<jthing>I had a bit of trouble with Maybe
10:12:18<dirk_>can I multiply int and string like "ab"*3 = "ababab" ?
10:12:27<BONUS>no
10:12:32<jthing>Seems problematc to extract the values
10:12:32<BONUS>but you can do
10:12:52<Berengal>jthing: How so?
10:12:58<BONUS>> concat $ replicate 3 "ab"
10:13:00<lambdabot> "ababab"
10:13:03<dirk_>ok
10:13:39<jthing>well it's all down to pattern match which sems inefficient
10:13:55<Berengal>jthing: It's not
10:14:17<jthing>would you elaborate?
10:14:27<Berengal>Pattern matching is not inefficient
10:14:37<jthing>duh
10:14:47<Berengal>Not sure there's much more to say about that...
10:15:07<jthing>you mean it is done at compile time i suspect
10:15:26<Berengal>No, you can't match on values that don't exist yet...
10:15:32<quicksilver>it can be done at compile time
10:15:37<quicksilver>if it's statically visible which case it is.
10:15:43<Berengal>True...
10:15:47<quicksilver>pattern matching is, in a sense, the most basic construct of haskell
10:15:49<Zao>dirk_: Using multiplication to replicate + concat a string is a rather leaky abstraction.
10:16:00<Berengal>On the other hand, pattern matching is what's driving evaluation
10:16:07<quicksilver>pattern matching is the wheel which turns.
10:16:10<ManateeLazyCat>I understand, if i don't write "forall a ." before "PageBuffer a =>" GHC will occur error "Not in scope: type variable `a`", so keyword `forall` like
10:16:10<ManateeLazyCat> [18:15:50]
10:16:14<Berengal>So if it was all done at compile time, there'd be no runtime
10:16:16<ManateeLazyCat>explicitly
10:16:25<Zao>ManateeLazyCat: That's a whole lot of tabs you pasted there.
10:16:36<ManateeLazyCat>type [18:16:25]
10:16:42<ManateeLazyCat>Bad Emacs ERC
10:16:42<Zao>ManateeLazyCat: Needs more parens?
10:16:44<ManateeLazyCat>Sorry.
10:17:02<ManateeLazyCat>Zao: Sorry, it's a bug of ERC
10:17:27<dirk_>the syntax does not matter, but the function is important
10:17:34<Zao>ManateeLazyCat: I was more thinking about the PageBuffer a bit, but I'm inexperienced in those parts.
10:18:37<jthing>Pagebuffer is a monad
10:18:51<Beelsebob>Has anyone here played with Graphics.Rendering.OpenGL.GLU.Tesselation?
10:18:57<Zao>ManateeLazyCat: Something like f :: Show a => a -> a works for me.
10:19:07<ManateeLazyCat>ACTION pasted "PageBuffer" at http://paste2.org/get/257036
10:19:12<ManateeLazyCat>Zao: Above PageBuffer
10:19:38<ManateeLazyCat>Zao: PageBuffer is interface for all type in Page.
10:20:02<ManateeLazyCat>Zao: Then i can use Page contain all type in `pageBuffer`
10:21:03<ManateeLazyCat>`forall` is an explicitly quantified type. Now clear enough...
10:21:22<Zao>Do you have a piece of code that doesn't work without the quantificatoin?
10:22:19<ManateeLazyCat>Zao: Sorry?
10:23:12<Zao>The error you got above. In what context was that?
10:23:53<ManateeLazyCat>ACTION pasted "Page.hs" at http://paste2.org/get/257078
10:24:18<ManateeLazyCat>Zao: That's my Page.hs file that use "forall a . PageBuffer a =>"
10:25:04<Zao>Ah, it's in that context.
10:25:45<ManateeLazyCat>Zao: My english is not always best. :)
10:27:42<ManateeLazyCat>Zao: So i can't understand others mean sometime....
10:30:17<ManateeLazyCat>How to leave message to someone through lambdabot? I need thanks someone that help me.
10:31:00<Zao>What about data Page a = PageBuffer a => ...?
10:31:13<Zao>Or am I misunderstanding the purpose of the code?
10:31:59<quicksilver>@tell ManateeLazyCat Here is a mesage for you
10:31:59<lambdabot>Consider it noted.
10:32:53<ManateeLazyCat>@tell ryan Thank you so much, you help me solution my problem, and it puzzle me long time. Thank you! :)
10:32:53<lambdabot>Consider it noted.
10:33:17<ManateeLazyCat>quicksilver: That's okay?
10:33:17<lambdabot>ManateeLazyCat: You have 1 new message. '/msg lambdabot @messages' to read it.
10:34:44<mmorrow>this must be really fast or something "indexWord8OffFastPtrAsFastChar" :P
10:35:16<Zao>I'm not pleased until it has at least one unsafe in it.
10:35:22<ManateeLazyCat>Zao: If you use "Page a = PageBuffer a => s", how to create Page instance.
10:35:24<quicksilver>ManateeLazyCat: that was right, yes.
10:35:32<ManateeLazyCat>quicksilver: Thanks.
10:36:56<ManateeLazyCat>Zao: I just want `pageBuffer` of `Page` use all type. `PageBuffer a` is interface, and Page is just container that contain PageBuffer object.
10:37:11<ManateeLazyCat>Zao: That's my purpose.
10:40:06<ManateeLazyCat>dcoutts: I use your suggestions, use child widget get event then callback to parent container, and works well. Thanks.
10:40:20<dcoutts>ManateeLazyCat: great
10:40:33<ManateeLazyCat>dcoutts: Use EventBox need setAbove with True, and it more complicate.
10:42:07<ManateeLazyCat>dcoutts: If i use EventBox, i need filter all Event to child widgets, and it's not agility. Use child widget with callback is neat. Thanks for your help
10:43:47<Zao>ManateeLazyCat: I defer that question to someone that actually knows what they are talking about.
10:43:50<Zao>eg. not me
10:51:14<ManateeLazyCat>ACTION Dinner....
10:51:55<MyCatVerbs>ManateeLazyCat: odd time for dinner, unless you're somewhere within about twenty degrees of India?
10:52:43<MyCatVerbs>(Longitude, I mean)
10:56:06<dirk_>I am working with Parsec and I want to revert the stream to a certain position
10:56:48<jml>MyCatVerbs: a pretty large chunk of humanity are eating dinner right now. :)
10:57:00<dirk_>So I consumed something, and I got some information that way, but I want to go on parsing, as if I had not consumed it
10:59:19<doserj>dirk_: lookahead p
10:59:42<dirk_>lookahead is not in the documentation
10:59:51<dirk_>http://legacy.cs.uu.nl/daan/download/parsec/parsec.html
11:00:29<doserj>that's over 7 years old!
11:01:56<doserj>http://hackage.haskell.org/packages/archive/parsec/3.0.0/doc/html/Text-ParserCombinators-Parsec-Combinator.html#v%3AlookAhead
11:03:45<dirk_>yes works, thank you
11:26:50<ManateeLazyCat>MyCatVerbs: China
11:53:59<ManateeLazyCat>I have type like this "data Page = forall a . PageBuffer a => Page {pageBuffer :: a}", if i need pick up pageBuffer from Page, i need write code like this "case page of Page {pageBuffer = x} -> do something with `x`". Have other way that pick up pageBuffer and don't use "case page of ... " style? Thanks
11:58:32<Cale>ManateeLazyCat: no, you absolutely must use pattern matching
11:59:53<Cale>ManateeLazyCat: Suppose that pageBuffer was allowed as a function, as field names normally are. What type would it have?
12:00:52<Cale>ManateeLazyCat: Well, it would take a Page, and give you... well, we don't know, it's just some type a which satisfies PageBuffer. Not just *any* type a, but a specific one that we don't know.
12:01:05<Cale>Another way to write that would be
12:01:27<BONUS>how about pageBuffer :: PageBuffer a => Page -> a
12:01:40<Cale>BONUS: too polymorphic :)
12:01:41<doserj>Page -> exists a. PageBuffer a => a
12:01:50<BONUS>ah, hmm
12:01:56<Cale>pageBuffer :: Page -> (exists a. PageBuffer a => a), yes
12:02:15<Cale>But Haskell doesn't have that type.
12:02:16<BONUS>ah yeah, it's not universally quantified inside
12:02:23<ManateeLazyCat>Cale: pageBuffer is *any* type that interface with PageBuffer type.
12:02:39<BONUS>it can't produce any type that's part of PageBuffer
12:02:44<BONUS>because it only has a value of one type inside it
12:02:45<BONUS>i see
12:03:19<Cale>ManateeLazyCat: inside of each Page value, you might have a value from a different type, as long as it's from a type which is an instance of that class
12:03:39<Cale>ManateeLazyCat: Applying the Page data constructor "forgets" the original type
12:04:44<BONUS>all that remembers is that the type is some type in the PageBuffer typeclass
12:04:45<Cale>and there's no way to recover that type information unless you do something to explicitly preserve it in the first place
12:08:27<ManateeLazyCat>If i write function "pageGetBuffer page = case page of Page {pageBuffer = x} -> x", how to write type signature?
12:08:44<doserj>you can't
12:08:51<Cale>ManateeLazyCat: Exactly. There is no valid type signature you could give it.
12:09:09<Cale>(because GHC does not have first-class existentials)
12:09:58<ManateeLazyCat>Cale: So i need write "case page of Page{pageBuffer = x} -> ... " everytime that i need pick up pageBuffer from Page instance?
12:10:29<wjt>You can write withPageBuffer :: PageBuffer a => (a -> b) -> Page -> b
12:10:45<inbuninbu>question for you gentlemen... is there an easier way to do control on an algebraic data type than pattern matching?
12:10:59<inbuninbu>for example, if i have an adt:
12:10:59<inbuninbu>data Mydata = Data1 Int String Int | Data2 String Int String | Data3 ...
12:11:20<inbuninbu>and have (monadic) functions (say, print) that will operate on ints and strings, and want a function that will arbitrarily apply them on the components of Data...
12:11:48<inbuninbu>is there a way to do that? basically, i want to avoid a gigantic case statement that uses pattern matchin
12:12:33<Cale>wjt: not quite... withPageBuffer :: (forall a. PageBuffer a => a -> b) -> Page -> b
12:12:55<BONUS>inbuninbu: make your type part of Functor? then you can map over it
12:13:24<BONUS>or make a function that extracts certain fields depending on the constructor
12:13:33<Cale>inbuninbu: It sounds as if you're looking for Data.Generics
12:13:39<wjt>Cale: aye
12:13:43<wjt>ACTION forages for coffee :)
12:13:46<Cale>inbuninbu: But that's usually overkill
12:13:56<quicksilver>inbuninbu: alternatively, you only have to do it once, generically.
12:14:07<inbuninbu>BONUS: in the functor impl, though, won't i still have to have a big case statment based on the constructor of the adt?
12:14:07<quicksilver>(write the case statement I mean)
12:14:34<mux>GHC can derive Functor automagically nowadays, I think
12:14:46<inbuninbu>Cale: thanks, i'll take a look
12:14:49<ManateeLazyCat>I wonder have way that avoid write duplicate case statement.
12:15:12<inbuninbu>quicksilver: you mean with Data.Generics
12:15:29<inbuninbu>mux: i'll give it a whirl
12:15:43<deeflex>Hey can anyone help me with this: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5728#a5728 .
12:16:12<ManateeLazyCat>wjt: withPageBuffer :: (forall a. PageBuffer a => a -> b) -> Page -> b ?
12:16:22<Cale>inbuninbu: If you have lots of very similar cases like that, chances are that thinking a bit more about how your datatypes are structured might help.
12:16:44<Cale>ManateeLazyCat: yes
12:17:00<BONUS>hmm why is the forall inside
12:17:01<inbuninbu>mux: Cannot derive well-kinded instance of form `Functor(Payload ...)' Class `Functor' expects an argument of kind `* -> *' In the data type declaration for `Payload'
12:17:12<BONUS>im not that good with existentials beyond the basic uses
12:17:14<Cale>BONUS: Because the argument itself is what has to be polymorphic
12:17:35<inbuninbu>Cale: unfortunately there isn't a way around it. it's a data structure as part of a protocol
12:17:36<Cale>BONUS: It won't do to pick some type a and pass an a -> b function
12:17:39<quicksilver>BONUS: because it only works on functions which guarantee they work with all "a"
12:17:47<BONUS>aha
12:17:59<quicksilver>BONUS: if the forall outsie, it would accept any function which worked on some particular a
12:18:00<BONUS>and not the a's bound by the outer forall
12:18:00<BONUS>i see
12:18:13<mux>inbuninbu: the Functor class only applies to type constructors of kind * -> *
12:18:27<MyCatVerbs>ManateeLazyCat: cool! How's the weather? :)
12:18:30<inbuninbu>Cale: and i just want to apply a put (or custom put) function based on the type
12:18:45<ManateeLazyCat>MyCatVerbs: Too hot.
12:18:49<ManateeLazyCat>MyCatVerbs: In my city.
12:18:58<MyCatVerbs>ManateeLazyCat: :/
12:19:15<inbuninbu>Cale: so i have a great many functions like putDataX (DataX a b c) = put32 a >> put16 b >> put8 c
12:19:45<ManateeLazyCat>MyCatVerbs: If at other city of China, won't too hot.
12:20:06<inbuninbu>and then, because i have to decide which function to use, i need a big case statement with pattern matching...
12:20:25<inbuninbu>it's a lot of repetitive stuff
12:20:59<dirk_>haskell is turning philosophical pa.hs:211:20: Not in scope: `ruinParser'
12:21:21<BONUS>see if you can farm that pattern matching out to a function
12:21:24<BONUS>which you then use
12:22:39<inbuninbu>BONUS: you just mean move the pattern matching elsewhere?
12:23:18<doserj>deeflex: the problem is in "let result = map (\ x y -> string2seq x y) mylines"
12:23:25<inbuninbu>BONUS: i was hoping that there may be a way to at least get it down to a lookup function
12:23:30<deeflex>deeflex, yes I know
12:23:59<deeflex>:t lines
12:24:01<BONUS>the best way is to think about your data structures and try to put all the pattern matching in one simple function that you then call
12:24:02<lambdabot>String -> [String]
12:24:15<inbuninbu>BONUS: is there no way to refer to the constructor of the ADT outside of pattern matching? in an expression
12:24:24<BONUS>it really depends on the data types
12:24:27<Cale>inbuninbu: How many cases do you actually have?
12:24:38<BONUS>did you post your code?
12:24:38<ManateeLazyCat>Cale: How to write code for "withPageBuffer :: (forall a. PageBuffer a => a -> b) -> Page -> b"?
12:24:39<inbuninbu>Cale: about 26
12:24:40<deeflex>doserj, yes I know *
12:24:55<ManateeLazyCat>Cale: I can't understand why need (a -> b)
12:25:03<inbuninbu>BONUS: i can post some now... you'll get the idea
12:25:09<Cale>ManateeLazyCat: withPageBuffer f (Page x) = f x
12:26:04<Cale>inbuninbu: Writing functions across that many cases seems really awkward. Are you sure that there's no way to factor the type at all?
12:26:58<deeflex>doserj, if I try this at the prompt: map (\x y -> string2seq x y) ["test","test2"] I get ERROR Cannot find "show" function for <myexpression> . The lambda expression takes two elements from the list, right?
12:27:13<doserj>no
12:27:31<inbuninbu>data Payload = Tversion {msize::Word32,version::String}|Rversion{msize::Word32,version::String}| Tauth{afid::Word32,uname::String,aname::String}| Rauth {aqid::Qid}| Rerror {ename::String}|..
12:27:34<doserj>it takes only one, and returns a function that takes another one
12:27:48<inbuninbu>Cale: there are 26 different message types
12:28:10<inbuninbu>Cale: there isn't really a way around it
12:28:11<doserj>deeflex: if you want to map over pairs, you first have to build a list of pairs
12:28:34<BONUS>yeah but what are you then doing with that type
12:28:34<ManateeLazyCat>Cale: Cool, thank you!
12:28:42<BONUS>extracing out the version? or something?
12:28:43<Cale>inbuninbu: Well, at least as long as you want types checked at compile time :)
12:28:48<ManateeLazyCat>Cale: withPageBuffer is cool function.
12:28:59<deeflex>doserj, aha ok.
12:29:04<ManateeLazyCat>withPageBuffer f (Page {pageBuffer = x}) = f x
12:29:27<Cale>ManateeLazyCat: or that, yes
12:29:40<ManateeLazyCat>Sweet. :)
12:29:51<inbuninbu>BONUS: reading from the network and writing from the network. i call a lookup function based on a message type field
12:30:06<inbuninbu>and from that i call getTversion
12:30:20<inbuninbu>which is , getTversion = liftM2 Tversion safeGet32 getS
12:30:24<ManateeLazyCat>wjt: Thanks too.
12:30:55<inbuninbu>but for my put method, i have a problem, i'm going from a full-on haskell adt, and need to put it. there is not way but to pattern match, it seems
12:31:28<deeflex>doserj, Btw..im just learning IO and wonder if all pure functions must have 'let = <expression>' ..?
12:31:52<ik>deeflex: all of them? no
12:31:59<ik>deeflex: just the ones you felt like using that construct in
12:32:03<Cale>deeflex: well... if you want to make definitions in the middle of a do-block, that's the way to do it
12:32:29<Cale>deeflex: But otherwise, you can make use of pure functions elsewhere
12:32:34<ManateeLazyCat>Cale: For function "withPageBuffer :: (forall a. PageBuffer a => a -> b) -> Page -> b", i need enable option `-XRankNTypes`, what's mean -XRankNTypes?
12:32:38<Cale>do x <- getLine; print (reverse x)
12:32:58<Cale>Here, reverse :: String -> String is a pure function.
12:33:02<deeflex>ik, Cale hmmf ok.
12:33:38<Cale>ManateeLazyCat: See the "forall a." in the type there?
12:33:42<Cale>ManateeLazyCat: It's that.
12:34:03<Cale>Basically, the ability for functions to demand that their parameters be polymorphic values.
12:35:04<ManateeLazyCat>Cale: I found a problem, if i use "{-# OPTIONS_GHC -XRankNTypes #-}" can pass compile, if i use "{-# LANGUAGE -XRankNTypes #-}" GHC report "ghc: panic! (the `impossible` happend)"
12:35:24<Cale>{-# LANGUAGE RankNTypes #-}
12:35:45<Cale>GHC doesn't handle misparsing of LANGUAGE pragmas very well
12:36:28<ManateeLazyCat>Cale: Thanks.
12:37:17<inbuninbu>Cale,BONUS: it would be easier if i could derive Enum from my data type, but it won't let me
12:37:55<ivanm>:o what kind of weird datatype do you have that it can't derive Enum?
12:37:58<deeflex>Cale, ye for definitions. Just tried removing 'let' and I got an error.
12:38:20<BONUS>ivanm: a data type with fields?
12:38:40<ivanm>BONUS: I've derived Enum for records before, IIRC
12:39:05<ivanm>the only time I couldn't was when I had a field with a RandomGen or something, or when I had a function...
12:39:11<BONUS>i don't recall ever doing that
12:39:18<ivanm>ACTION tests
12:39:54<BONUS>to derive Enum, all constructors have to be nullary afaik
12:39:55<ivanm>hmmm, you're right
12:40:08<ivanm>ACTION must be remembering it wrong
12:40:16<ivanm>nullary = constructor only?
12:40:27<inbuninbu>ivanm: "(`Payload' has non-nullary constructors)"
12:40:38<ivanm>so it can only derive Enum for newtypes and things like A | B | C | ... ?
12:40:52<ivanm>ACTION thought as long as all the fields were instances of Enum, it could derive them...
12:41:34<doserj>instantiating Enum for something like data A = A Int | B Int is non-trivial
12:43:00<ivanm>*nod*
12:43:09<ivanm>doserj: because B 1 might be < A 2 ?
12:43:37<quicksilver>you can derive Ord
12:43:39<quicksilver>just not Enum
12:43:44<quicksilver>maybe that's what you were thinking of?
12:43:51<ivanm>oh, yeah :s
12:44:01<ivanm>ACTION bangs his head against a convenient wall
12:44:50<inbuninbu_>too bad ord won't help me...
12:45:25<ivanm>anyone know why hmatrix had 0.5.2.1 released two days after 0.5.2.0 was released?
12:46:22<quicksilver>inbuninbu_: why would deriving Enum for your datatype help you?
12:46:33<quicksilver>inbuninbu_: I don't understand what you'd use it for.
12:51:56<inbuninbu_>quicksilver: onelinecase n = lookup n $ zip (fromEnum payload) [putTversion,putRversion,..]
12:53:08<BONUS>i still don't understand which function you're using those big pattern matches in. what does that function do
12:53:17<quicksilver>inbuninbu_: but would putTversion, putRversion have the same type?
12:53:25<quicksilver>it seems to me they wouldn't
12:53:29<quicksilver>so you're not putting them in a list.
12:53:46<inbuninbu_>quicksilver: yes. they both are of type Put
12:53:47<quicksilver>You have to write the case statement once. If you think that's boilerplate, fair enough.
12:53:56<quicksilver>you certainly shouldn't have to write them more than once.
12:54:02<lilac>seems like you should be able to derive Enum if there's one Enum field per constructor, or all the fields are Enum and Bounded
12:54:03<quicksilver>inbuninbu_: no, because they have parameters don't they?
12:54:20<quicksilver>lilac: Bounded doesn't implie finitely enumerable.
12:54:27<quicksilver>lilac: oh, Enum *and* bounded. sorry.
12:54:30<quicksilver>lilac: yes, agreed.
12:54:41<quicksilver>inbuninbu_: aren't they like a -> b -> c -> Put ?
12:54:44<inbuninbu_>quicksilver: nope, they are all of type PAyload -> Put
12:54:53<lilac>quicksilver: i'm not sure it's a /useful/ Enum instance though
12:55:07<quicksilver>basically you have to write one case statement in your program.
12:55:13<quicksilver>it shouldn't be necessary to write more than one.
12:55:24<inbuninbu_>quicksilver: *Main> :t putRversion
12:55:24<inbuninbu_>putRversion :: Payload -> PutM ()
12:55:24<inbuninbu_>*Main> :t putTversion
12:55:25<inbuninbu_>putTversion :: Payload -> PutM ()
12:55:29<quicksilver>you should be able to write a generic destructor
12:55:36<quicksilver>inbuninbu_: did you paste some code yet?
12:55:57<inbuninbu_>quicksilver: i did, i'm going to post some more in a minute, per BONUS's request
12:57:21<lilac>if you have 'data Foo = A | B X | C X Y', GHC could generate 'foo :: a -> (X -> a) -> (X -> Y -> a) -> Foo -> a' (is this a catamorphism?)
12:58:22<lilac>indeed, i thought that's how GHC internally represents boxed data
12:59:06<inbuninbu_>BONUS,quicksilver:putPayload p = case p of
12:59:06<inbuninbu_> Tversion _ _ -> putTversion p;Rversion _ _ -> putRversion p; Tauth _ _ _ -> putTauth p
12:59:50<inbuninbu_>and it goes on and on
12:59:50<quicksilver> inbuninbu_ well to be honest I don't see a problem with that.
13:00:06<quicksilver>you've got N functions to call, you have to write them all once.
13:00:16<quicksilver>if you had to write them twice, that would be annoying.
13:00:35<quicksilver>but if you put the actual complete code in hpaste I may be able to suggest something
13:00:46<inbuninbu_>quicksilver: i know it works. it's just it would be nice if i could zip them all up, like with lookup
13:01:11<quicksilver>I don't see why it would be nice.
13:01:19<quicksilver>I don't see why it's nice to turn a case statement, which is a fast dispatch
13:01:24<quicksilver>into a slow list-based dispatch.
13:01:42<quicksilver>I also don't think it's significantly shorter.
13:02:32<inbuninbu_>quicksilver: i didn't think there was any significant difference between lookup and case. shows what i know, i guess :-)
13:02:50<quicksilver>lookup is O(n) - the length of the list.
13:03:01<quicksilver>case is, sort-of, constant time.
13:03:11<quicksilver>it's certainly conceptually constant time.
13:04:44<inbuninbu_>quicksilver: ok. i just assumed since the list is known at compile time, the compiler would optimize it
13:04:54<inbuninbu_>and make it constant time
13:05:01<eu-prleu-peupeu>hello
13:05:24<EvilTerran>inbuninbu_, unfortunately, i don't believe recursive functions are inlined at all
13:05:54<quicksilver>right, GHC doesn't do any unrolling yet.
13:05:59<ivanm>EvilTerran: otherwise, the entire program could be "run" during compilation if it doesn't require any inputs?
13:06:14<quicksilver>and it doesn't do constant folding on recursive data types either
13:06:26<quicksilver>still I'm not quite sure that's the point.
13:06:41<quicksilver>I honestly don't see why the lookup/fromEnum version is preferable even in principle
13:06:58<quicksilver>why associate a synthetic number (fromEnum) with constructors just to use it to look up in a list?
13:07:20<quicksilver>even ignoring issues of runtime complexity, it seems less attractive to me not more.
13:08:05<EvilTerran>ivanm, sure, if you don't mind compilation failing to terminate sometimes
13:08:11<ivanm>heh
13:08:45<quicksilver>I imagine any unroll/inline pass under consideration woudl have termination guarantees ;)
13:08:46<ivanm>and being a lot slower than actually running the program
13:08:56<quicksilver>experimental unrolling work suggests it can be a huge performance benefit.
13:10:52<inbuninbu_>quicksilver: i just wanted to shorten code. but looking at it, the payoff isn't that great, like you said
13:20:27<inbuninbu_>anyway, thanks guys!
13:48:39<b_jonas>hello
13:49:06<gwern>i like pie
13:49:07<lambdabot>gwern: You have 2 new messages. '/msg lambdabot @messages' to read them.
13:49:12<gwern>@messages
13:49:12<lambdabot>kowey said 4h 19m 28s ago: gitit-2009-06-10T10:26 uploaded (plus I now have an update-all.sh which makes this more mindless)
13:49:12<lambdabot>tux_rocker said 3h 6m 8s ago: The wiki search seems to be broken for pages with spaces. Try searching for 'buildbot' and clicking either of the top two results.
13:49:21<b_jonas>I have a vague question. I'm looking for a coroutine monad or monad transformer that allows me to switch between coroutines explicitly, but I'm not sure how exactly it would work
13:49:53<PeakerWork>b_jonas: ContT?
13:49:57<PeakerWork>b_jonas: or something higher-level?
13:50:03<b_jonas>that is, whether it would encapsulate just one coroutine and have a run which would return when that yields, or whether it would switch between multiple coroutines like a restricted contT
13:50:12<b_jonas>PeakerWork: yes, it's certainly possible to restrict ContT
13:50:14<PeakerWork>b_jonas: look at roconnor's http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5308
13:50:15<b_jonas>but that's not trivial
13:50:22<b_jonas>so I'm wondering both if that's the best way,
13:50:29<b_jonas>and whether there's an existing library implementation.
13:50:41<PeakerWork>or is that someone else?
13:50:47<PeakerWork>oh its mmorrow's, oops
13:51:02<b_jonas>I seem to remember there was also some kind of example in some monad tutorial,
13:51:14<PeakerWork>b_jonas: isn't that paste almost exactly what you need?
13:51:17<b_jonas>which showed how you ran two computations concurrently and stop when the first stops
13:51:24<b_jonas>PeakerWork: looking
14:00:02<b_jonas>looks quite complicated. I'm lost in the heaps of type variables and don't know where to start. I guess maybe this is another example of something I have to write first to understand.
14:00:12<b_jonas>thanks for the link anyway
14:00:22<b_jonas>it may help me _after_ I write my version :-)
14:02:20<PeakerWork>b_jonas: writing coroutines on top of callCC confused the hell out of me too :)
14:02:32<lilac>b_jonas: you are trapped in a twisty maze of type variables, all alike
14:02:37<PeakerWork>b_jonas: do you think there's a good alternative except using/reimplementing something like ContT?
14:02:57<PeakerWork>I dislike Haskell conventions of using single-letter names even where names *could* pass useful information
14:03:23<b_jonas>PeakerWork: I know, that confuses me too
14:03:27<b_jonas>that's why I said it wasn't trivial
14:03:33<PeakerWork>data Accessor whole part = ... ; and not data Accessor a b = ...
14:03:43<b_jonas>PeakerWork: and I don't know if there is a different implementation
14:03:47<b_jonas>that's part of why I'm asking
14:17:28<jeffersonheard>are there comments in cabal files?
14:17:47<dcoutts>jeffersonheard: -- but they have to be on a line on their own
14:17:52<jeffersonheard>k
14:17:52<dcoutts>not at the end of another line
14:18:06<dcoutts>since tool flags use --
14:53:16<kowey>does anybody know what the latest thinking is on hacking a hackathon at ICFP this year?
14:53:21<kowey>*having :-)
14:56:18<Lemmih>Isn't there always a hackathon at the ICFP.
14:56:54<Lemmih>Err, s/./?/
14:57:07<kowey>has somebody stepped up and taken charge of this?
14:57:25<kowey>ACTION will not be there and is therefore not volunteering
14:58:02<skorpan>Lemmih: "?sn't there always"
14:58:04<skorpan>har har har
15:05:47<lilac>skorpan: s/./!/g
15:06:42<skorpan>lilac: but that becomes "!!!!!!!!!!!!!!!" doesn't it?
15:18:02<QtPlaty[HireMe]>ACTION ponders "Would it a good idea to have a type class "Relation" that had instances of list, hashes and functions, with a unified lookup operator for all of them?
15:18:06<QtPlaty[HireMe]>"
15:22:11<lilac>QtPlaty[HireMe]: 'Mapping' might be a better name. 'Relation' usually means a set of pairs (or a mapping from (a, a) to Bool)
15:22:42<QtPlaty[HireMe]>lilac: I was thinking Relation in the mathmatical sence.
15:23:13<QtPlaty[HireMe]>And mapping is already used.
15:23:23<QtPlaty[HireMe]>well Map is.
15:27:00<lilac>QtPlaty[HireMe]: I was thinking Relation in the mathematical sense too (a relation on set A being a subset of A x A)
15:28:06<QtPlaty[HireMe]>lilac: A relation between sets A and B being a subset of A x B or are we thinking of diffrent things.
15:29:32<QtPlaty[HireMe]>Functions are a type or relation, and lists can be seen as subsets of N x A (with further restrictions) and Maps/Hashes are also A x B
15:30:35<quicksilver>QtPlaty[HireMe]: but the ones you can lookup, generally, are functions
15:30:48<quicksilver>QtPlaty[HireMe]: a funciton is a single-valued relation, defined everywhere
15:30:56<quicksilver>although it's common to relax 'defined everywhere'
15:30:59<QtPlaty[HireMe]>quicksilver: True.
15:31:01<quicksilver>(which makes it a partial function)
15:31:07<tiedtoatree>where can i read about how lists are implemented in Haskell? and generally how one figures out the time complexity of a haskell function?
15:31:21<quicksilver>tiedtoatree: lists in haskell are cons cells, like in lisp and ML
15:32:09<lilac>QtPlaty[HireMe]: it sounds like you want a type class for functions, not for relations, in any case?
15:32:10<mib_leftyi>hello
15:33:04<QtPlaty[HireMe]>lilac: Well I wish to include functions, and the things that look like functions when you look at them from a high enought hight.
15:33:08<QtPlaty[HireMe]>mib_leftyi: Hi
15:33:13<lilac>QtPlaty[HireMe]: ... such as ([1,2,3]!!) or (array (1,2) [(1,'a'),(2,'b')]!) or (\x -> ...)?
15:33:35<QtPlaty[HireMe]>lilac: Exactly.
15:33:59<lilac>QtPlaty[HireMe]: it hardly seems worthwhile to me, given how easy it is to convert such things into real functions
15:34:19<tiedtoatree>so is ++ implemented as a series of cons?
15:34:32<QtPlaty[HireMe]>tiedtoatree: Yes.
15:34:41<lilac>QtPlaty[HireMe]: that said, I could imagine a 'class Function f a b | f -> a b where ($) :: f -> a -> b'
15:34:59<lilac>where ($) is pronounced 'thunderbirds'
15:35:09<EvilRanter>...
15:35:25<quicksilver>tiedtoatree: ++ rebuilds the left list and points the tail of it to the right list.
15:35:34<quicksilver>hence it is O(left list)
15:35:51<QtPlaty[HireMe]>lilac: What does the bar | represent there?
15:35:59<mib_leftyi>[if snd (quotRem a 5) == 0 then a else <don't put it in the list> | a <- list] <- what am I missing here? What do I need to put in place of <don't put it in the list> part so I only have a list of numbers that are multiples on 5?
15:36:26<quicksilver>mib_leftyi: [a | a <- list, snd (quotRem a 5) == 0 ]
15:36:27<mib_leftyi>this assumes list is filled w/ Integers, of course... :)
15:36:40<mib_leftyi>quicksilver: wow, ok... thanks!
15:36:43<lilac>QtPlaty[HireMe]: a functional dependency. it means, there's only one value of a and b for any given value of f
15:36:43<quicksilver>there is nothing you can put to the left of the | to do exactly this
15:36:49<quicksilver>but you can put booleans ont he right of the |
15:37:48<QtPlaty[HireMe]>quicksilver: Is that a ghc extention of a part of standard haskell (I haven't encounted that syntax before)?
15:37:58<QtPlaty[HireMe]>s/of/or/
15:38:51<tiedtoatree>so what does (cons 1 (cons 2 (cons 3 nil))) look like in memory? something simple like a linked list?
15:39:19<QtPlaty[HireMe]>tiedtoatree: Effectively yes.
15:39:21<quicksilver>tiedtoatree: In my head (cons 1 (cons 3 (cons 3 nil))) *already* looks like a linked list.
15:39:27<quicksilver>tiedtoatree: in fact, I'd say it is a linked list.
15:40:00<quicksilver>in memory it looks similar but a haskell implementation is likely to need an extra level of indirection throughout.
15:40:06<quicksilver>(for laziness)
15:40:35<tiedtoatree>great! thanks everyone.
15:43:22<gwern>:t ignore x = x >> return ()
15:43:24<lambdabot>parse error on input `='
15:43:29<gwern>:t x >> return ()
15:43:30<lambdabot> Couldn't match expected type `m a' against inferred type `Expr'
15:43:30<lambdabot> In the first argument of `(>>)', namely `x'
15:43:30<lambdabot> In the expression: x >> return ()
15:43:35<gwern>:t \x -> x >> return ()
15:43:37<lambdabot>forall (m :: * -> *) a. (Monad m) => m a -> m ()
15:43:49<gwern>@src sequence_
15:43:49<lambdabot>sequence_ ms = foldr (>>) (return ()) ms
15:44:12<gwern>:t let ignore x = x >> return () in map ignore
15:44:13<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> [m ()]
15:44:29<gwern>:t let ignore x = x >> return () in mapM_ ignore
15:44:30<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m ()
15:44:55<gwern>hm. that looks like a nicer definition than using foldr, but I don't know if the left-to-rightness of sequence is important
15:45:16<EvilRanter>isn't mapM_ defined in terms of sequence_, though?
15:45:19<EvilRanter>?src mapM_
15:45:19<lambdabot>mapM_ f as = sequence_ (map f as)
15:45:23<lilac>QtPlaty[HireMe]: it's a GHC extension. quicksilver was coincidentally talking about | in list comprehensions.
15:45:37<gwern>EvilRanter: drat!
15:45:54<lilac>QtPlaty[HireMe]: {-# LANGUAGE FunctionalDependencies #-}
15:45:59<gwern>but wait, why is a map using a fold?
15:46:02<QtPlaty[HireMe]>lilac: URL for documentation or is it in someone's paper?
15:46:13<lilac>QtPlaty[HireMe]: IIRC it's actually | f -> a, f -> b that you need
15:46:17<pumpkin>gwern: because it doesn't return anything
15:46:23<pumpkin>(useful)
15:46:25<EvilRanter>gwern, er, because maps are folds?
15:46:25<gwern>a fold forces dependencies; when you're using mapM_, you're trying to say that each item is independent
15:46:34<EvilRanter>you are?
15:46:46<EvilRanter>they don't strike me as independent in, eg, a MonadState
15:46:53<gwern>EvilRanter: I know I've only used mapM_ in the context of things like mapM_ (forkIO)
15:46:53<lilac>QtPlaty[HireMe]: http://citeseer.ist.psu.edu/jones00type.html
15:47:01<pumpkin>you still want to sequence them
15:47:09<lilac>QtPlaty[HireMe]: these days, type families seem to be more in vogue than fundeps
15:47:09<PeakerWork>gwern: a fold allows dependencies, it doesn't force them
15:47:18<gwern>pumpkin: why's that?
15:47:35<QtPlaty[HireMe]>ACTION seems to never stop learning new stuff about Haskell.
15:47:53<pumpkin>gwern: because the state of the world depends on it! :P
15:48:07<gwern>ACTION doesn't follow
15:48:35<pumpkin>gwern: if they all started with the "same" RealWorld, they'd all be splitting reality off into parallel universes
15:48:48<pumpkin>instead, they need to work off each other's changes to the real world, so we can stay in the same universe ;)
15:49:15<gwern>obviously you're making some arcane joke related to the implementation of the IO monad which I'm not appreciating, nor would care much about
15:49:26<pumpkin>my point is, they aren't indepdendent
15:49:39<pumpkin>they need to be sequenced together for them to do anything meaningful
15:49:47<pumpkin>even if separate forkIOs "feel" independent
15:50:52<kowey>ACTION waves a pom-pom - http://www.haskell.org/pipermail/haskell-cafe/2009-June/062678.html
15:51:08<pumpkin>rah rah!
15:55:29<jeffersonheard>is there any way to get the runtime to give a more explicit error than "Map.find: element not in the map", like with a line number or stack trace or something?
15:55:54<Botje>write a wrapper for Map.find?
15:56:10<Botje>then again, that won't change much :}
15:56:28<jeffersonheard>Botje: no. I mean, at least I'd get the key if there was an exception...
15:56:29<pumpkin>use the CPP to substitute __LINE__ and stuff in for you?
15:57:15<jeffersonheard>pumpkin: is there any good reason GHC can't do that if compiled with -g or some such?
15:57:23<Botje>jeffersonheard: what find function is this?
15:57:24<pumpkin>probably not :)
15:57:27<jeffersonheard>Map.!
15:57:29<Botje>Data.Map doesn't have it
15:57:36<jeffersonheard>it's not exported
15:57:42<pumpkin>jeffersonheard: but it should be coming soon
15:57:47<pumpkin>with all that stack trace stuff
15:57:48<jeffersonheard>Data.Map.! == Data.Map.find
15:57:51<pumpkin>even though we still won't know the key
15:57:52<Botje>oh
15:58:35<Botje>don't use !, then? :)
15:58:47<Botje>or wrap ! with a Debug.trace thing
15:59:01<quicksilver>shadow (!) with a local defintion
15:59:04<quicksilver>which gives better errors
15:59:10<quicksilver>is probably your best option
15:59:16<jeffersonheard>yeah, probably...
15:59:23<quicksilver>(call the safe lookup function and give a sensible error if it returns not found)
15:59:38<jeffersonheard>not entirely sure this is in my code
15:59:55<quicksilver>let m ! k = case lookup m k of Just v -> v; Nothing -> error $ "lookup failed for " ++ show k
16:00:03<quicksilver>which will chuck a show constraint on k, of course
16:00:11<quicksilver>but hopefully that's going to be ok :)
16:00:41<gwern>quick question: what do y'all make of the idea of adding 'ignore :: m a -> m (); ignore x = x >> return ()' to Control.Monad?
16:01:22<maltem>gwern, i guess it wouldn't hurt :)
16:01:38<quicksilver>I like it.
16:01:46<quicksilver>Although it means a new base version of course.
16:01:46<quicksilver>Yay!
16:02:17<gwern>quicksilver: presumably there's going to be a new base version eventually anyway
16:02:31<quicksilver>right
16:02:39<quicksilver>I was being flippant. (flipping?)
16:02:55<gwern>hm. I'm doing a recursive grep through my sources for examples of '>> return ()', but I have so many haskell source dirs that it's only up to the 'b's
16:03:03<doserj>quicksilver: adding things doesn't imply a major version bump
16:03:26<gwern>(it's very handy, incidentally, to have most of the haskell world on your hard drive so you can search for idioms when you're arguing for something :)
16:03:52<gwern>doserj: I though the minor ones were only supposed to be bugfixes? and that top level additions or removals or type changes had to be major
16:04:29<doserj>removals are major, additions not. (if you don't import qualified, it's your own fault)
16:05:06<gwern>argh. so slow! up to 'bi'
16:05:15<gwern>I shouldn't've skimped on the hard drive building this computer!
16:05:37<SamB_XP>gwern: what kind of skimping did you do?
16:06:01<gwern>SamB_XP: bought only a ~7600rpm drive, iirc
16:06:07<gwern>thought about going up, but...
16:06:13<SamB_XP>gwern: as opposed to?
16:06:23<SamB_XP>also, that doesn't sound like the best speed measure to me
16:06:27<seliopou>anybody remember off the top of their heads in which version of base the types for containers changed?
16:06:27<gwern>9k or 16k iirc are the next major steps up
16:06:40<p_l>gwern: shouldn't that be be 7200?
16:06:47<SamB_XP>well, I guess it might affect access time
16:06:51<SamB_XP>well, would
16:06:56<gwern>SamB_XP: for random access seeks like grepping a couple gigabytes? rpm is iirc the measure of interest
16:07:02<SamB_XP>but there may be other factors?
16:07:30<SamB_XP>gwern: well, RPM tells you how long it takes to spin once
16:07:43<p_l>gwern: for grepping large amount of data, tons of RAM plus good cache ;-)
16:07:46<SamB_XP>but then there's also how long it takes to move from one track to the next
16:07:55<gwern>SamB_XP: of course there are other factors; like the number of disk heads matter
16:08:05<SamB_XP>or, perhaps more importantly, from hub to rim
16:08:23<quicksilver>doserj: are you sure that's true?
16:08:33<quicksilver>doserj: in practice, nobody imports qualified.
16:08:40<quicksilver>doserj: so all additions can and will break code.
16:09:10<gwern>here we go, I bought a 'HD 500G|SAMG 7K 16M SATA2 HD501LJ '
16:09:23<SamB_XP>and then there's the distribution of data across the tracks, which would affect how much radial motion was typically needed
16:10:16<doserj>quicksilver: just checked, that is what is specified on http://www.haskell.org/haskellwiki/Package_versioning_policy
16:10:20<quicksilver>doserj: ah, you're right.
16:10:26<quicksilver>doserj: so the PvP is broken, but pragmatic.
16:10:26<gwern>could've gone all the way up to 15k; why did I decide to go with more ram...
16:10:31<quicksilver>possibly that's the right choice.
16:10:42<quicksilver>it's particularly glaring for base, though.
16:11:02<quicksilver>since modules from base are very rarely imported qualified, but they are imported in all kinds of haskell programs.
16:11:05<doserj>for basic libraries like Control.Monad, Data.List, etc, it is a bit problematic, yes
16:11:11<jeffersonheard>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5731#a5731
16:11:59<doserj>quicksilver: you don't have to import qualified, though. it also sufficient to give an explicit import list
16:12:20<jeffersonheard>in that last hpaste, can anyone tell me how using nothing but get/put/free on a non-full cache can occasionally lead to the IntMap.findMin (times cache) not existing in (store cache)
16:12:21<doserj>which is a bit more reasonable
16:12:34<jeffersonheard>it seems to happen at entirely random times.
16:12:34<SamB_XP>quicksilver: what did you say would cause a bump in base's version?
16:12:52<quicksilver>SamB_XP: adding ignore to Control.Monad, in particular
16:13:04<quicksilver>SamB_XP: but obviously the general discussion is just about adding any new functions to an API
16:13:04<SamB_XP>they're bumping the second component anyway
16:13:29<SamB_XP>... but hey, that's better than the first component like before, isn't it?
16:13:33<quicksilver>doserj: I find both import qualified, and explicit import lists, ugly/inconvenient in slightly different ways.
16:13:33<pumpkin>ACTION petititions for &&&, ***, first, second, and <$> to be added to Prelude :P
16:13:51<jeffersonheard>ACTION seconds pumpkin's petition
16:14:15<SamB_XP>pumpkin: ooh, that'd be kinda nice!
16:14:26<pumpkin>not sure where to petition though :)
16:14:31<SamB_XP>libraries@
16:14:33<pumpkin>ACTION writes a sign and holds it up
16:14:37<pumpkin>oh
16:14:47<doserj>quicksilver: I don't think explicit import lists are ugly, there is not enough tool support to keep them synchronized, though
16:14:53<SamB_XP>oh, but doesn't that need Control.Arrow in base?
16:15:00<SamB_XP>(is it in base?)
16:15:17<doserj>ACTION would like &&&, ***, etc. specialized ot (->)
16:15:20<byorgey>maybe we could just have function-specific versions of &&&, ***, first, and second in base
16:15:21<SamB_XP>I guess ideally Prelude would *not* be in base
16:15:40<byorgey>then if you want the general Arrow versions you can just hide them in the Prelude, or import Arrow qualified, or something
16:15:43<SamB_XP>doserj: that'd mean you'd need to hide them if you wanted to use the Arrow versions :-(
16:15:49<doserj>SamB: yes
16:15:57<SamB_XP>that's not fun
16:16:07<byorgey>but the point is that MOST of the time people only want the (->) versions.
16:16:23<SamB_XP>byorgey: &&& and *** would look horrible qualified ...
16:16:35<pumpkin>byorgey: it still wouldn't hurt to just put in the regular ones, except that it might scare people if they :t'ed them
16:16:37<byorgey>that's true. what's so bad about hiding them?
16:16:38<EvilTerran>put 'em in Data.Tuple
16:16:49<doserj>you can also call the Arrow version &&&& and **** :)
16:16:53<byorgey>yup, Data.Tuple is where they ought to go
16:16:57<EvilTerran>or Data.Function
16:17:00<pumpkin>&&&&&&&&&&&&&&& and *********************
16:17:00<SamB_XP>@doc Control.Arrow
16:17:00<lambdabot>http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html
16:17:06<EvilTerran>(although surely that should be Control.Function...)
16:17:23<byorgey>SamB_XP: actually, I'm pretty sure Control.Arrow is already in base anyway
16:17:26<PeakerWork>Is it possible for SECs (like first, second) to be composed alongside getters, like data-accessors/lens?
16:17:27<pumpkin>it is
16:17:38<ray>preludes suck
16:17:42<SamB_XP>okay, Control.Arrow is in base so there's no technical issue with including the Arrow versions in Prelude
16:17:50<pumpkin>yeah
16:17:55<SamB_XP>byorgey: yes, I just checked with @doc
16:17:57<pumpkin>only downside is scaring people who type :t I think
16:18:05<SamB_XP>byorgey: the URL reveals that it is still in base
16:18:09<pumpkin>we should change their type signature to use ~> infix
16:18:10<PeakerWork>Data accessor setters are limited to not modifying the whole's type, whereas first/second/SECs in general do modify the whole's type
16:18:39<ray>~> is nice
16:18:43<SamB_XP>PeakerWork: whole type?
16:18:44<ski>(`SEC' ?)
16:18:50<pumpkin>you accidentally the whole type?
16:18:57<ray>it represents a vagueomorphism, which is what arrows are
16:19:15<lilac>gwern: fwiw, i have 'ignore = (>> return ())' in Utils.hs in one of my projects
16:19:23<gwern>which one?
16:19:28<SamB_XP>anyway, wouldn't including less polymorphic versions in Prelude be Haskell 98 all over again?
16:19:35<byorgey>ski: 'Semantic Editor Combinators', presumably
16:19:42<lilac>gwern: it's about 3% of a c++ parser
16:19:42<ray>maximum polymorphism
16:19:55<pumpkin>ULTIMATE POLYMORPHISM
16:19:58<ray>generalize maps and folds to functors
16:19:58<pumpkin>multimorphism
16:20:02<ski>(oh .. a la conor's combinators ?)
16:20:07<ray>not folds
16:20:11<ray>that's a different class
16:20:20<ray>infinimorphism
16:20:24<byorgey>ski: conal, but yes
16:20:26<ray>or vagueomorphism
16:20:30<SamB_XP>lilac: what's the difference between that and Language.C?
16:20:37<ray>it's annoying how there's two different meanings of "morphism" at work here
16:20:37<ski>byorgey : sorry, that's what i meant yes
16:20:50<ski>(my fingers apparently mixed the two names up)
16:20:55<byorgey>hehe =)
16:20:57<lilac>SamB_XP: two pluses :)
16:21:16<lilac>SamB_XP: plus drastically different design goals
16:21:50<ray>drastically
16:21:56<SamB_XP>lilac: I was implying that Langauge.C also parses about 3% of C++
16:22:01<ski>it might be nice if one could reexport operations with more restricted types .. and then, import both those and the original, and get the general types back
16:22:12<lilac>SamB_XP: yeah, a different 3% ;)
16:22:12<SamB_XP>the joke being that C++ is ...
16:22:27<ski>(since istr the system keeps track of whether they come from the same source anyway, no ?)
16:22:28<SamB_XP>> 1/0.03
16:22:30<lambdabot> 33.333333333333336
16:22:45<ray>generalize ($) to a -> a!
16:22:54<lilac>ski: yeah, that'd be neat
16:22:57<SamB_XP>33 and 1/3 times as complicated to parse as C
16:23:04<ray>if you use it wrong you'll get type errors anyway
16:23:16<ski>ray : which two meanings of `morphism' ?
16:23:20<lilac>SamB_XP: is that all? i assume that means you're comparing C++98 to C99? :)
16:23:31<quicksilver>doserj: if there was tool support to manage the import lists that would help, but...
16:23:35<ray>morphism as in "monomorphism" and morphism as in "catamorphism"
16:23:43<quicksilver>doserj: isn't it nasty to have to keep running tools over your source code to update things
16:23:43<SamB_XP>lilac: no, to GNUC, actually
16:23:50<ray>one of those shouldn't use "ism"
16:23:55<ski>ray : why is that different meanings of `morphism' ?
16:23:57<SamB_XP>isn't that what Language.C parses?
16:24:12<ray>consider that one is a noun and one is an adjective
16:24:16<byorgey>ray: both of those are names for arrows in some category.
16:24:28<SamB_XP>ACTION also thinks the "generalize" thing would be neat
16:24:28<byorgey>no, both are nouns
16:24:42<EvilTerran>it's (monomorph)ism and cata(morphism), isn't it?
16:24:49<ray>yes
16:24:49<doserj>quicksilver: you don't have to do it more frequently than compiling your code
16:24:50<SamB_XP>the trouble being that it'd be a new keyword
16:24:51<ski>a `monomorphism' is a `morphism' which is `monomorphic', a `catamorphism' is a morphism in some category satisfying some property
16:25:14<SamB_XP>how could the need for a new keyword there be prevented?
16:25:18<byorgey>EvilTerran: what? why?
16:25:37<byorgey>mono(morphism), epi(morphism), ...
16:26:01<SamB_XP>I thought monomorphism was an adjective meaning monomorphic ...
16:26:02<EvilTerran>byorgey, i dunno, i'm just extrapolating from what seems to make most sense to me
16:26:06<SamB_XP>er.
16:26:16<SamB_XP>no, a noun version of the adjective monomorphic
16:26:31<ray>hence "monomorphism restriction" for example
16:26:31<SamB_XP>referring to the property itself
16:26:33<doserj>quicksilver: but I think we agree mostly
16:26:45<SamB_XP>ACTION wonders if he fed the cats
16:26:46<byorgey>SamB_XP: indeed.
16:27:39<uzytkownik>> pl \x -> (f x, g x)
16:27:41<lambdabot> <no location info>: parse error on input `\'
16:28:03<byorgey>ACTION suddenly realizes that 'monomorphic' has two entirely different meanings
16:28:05<ski>@pl \x -> (f x, g x)
16:28:06<lambdabot>liftM2 (,) f g
16:28:36<byorgey>depending whether it is referring to a type or an arrow in a category
16:28:46<byorgey>le sigh.
16:28:54<uzytkownik>ski: Thank you. Wiki is not clear what syntax should be used...
16:29:01<lilac>import Control.Arrow ((***) :: (a -> b) -> (a' -> b') -> (a, a') -> (b, b'), (&&&) :: ...)
16:29:04<ray>that is what i mean
16:29:24<ski>byorgey : yes `monomorphic' and `polymorphic' vs. `monomorphic' and `epimorphic' :)
16:29:31<byorgey>right, exactly =)
16:29:51<ski>@help pl
16:29:52<lambdabot>pointless <expr>. Play with pointfree code.
16:30:01<byorgey>hmm, the word 'morphism' is sort of odd etymologically.
16:30:18<ski>ray : ok
16:30:34<byorgey>ACTION ponders
16:31:29<ski>lilac : if we even have something like JohnMeachams superclass proposal (?), we should allow restricting operations in superclasses, too
16:32:05<PeakerWork>SamB_XP: whole type as in the whole tuple in the case of first/secodn
16:32:08<quicksilver>doserj: yes, I know. I just don't like part of my code to have to be "written to" by the tool I run to compile it.
16:32:08<PeakerWork>@type first
16:32:09<lambdabot>forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a (b, d) (c, d)
16:32:13<quicksilver>doserj: I don't know why I don't like it, but I don't.
16:32:18<Taejo>@where listToMaybe
16:32:18<lambdabot>I know nothing about listtomaybe.
16:32:18<quicksilver>doserj: it feels wrong.
16:32:26<pumpkin>@index listToMaybe
16:32:27<lambdabot>Data.Maybe
16:32:27<Taejo>@hoogle [a] -> Maybe a
16:32:28<lambdabot>Data.Maybe listToMaybe :: [a] -> Maybe a
16:32:29<lambdabot>Data.List find :: (a -> Bool) -> [a] -> Maybe a
16:32:29<lambdabot>Prelude head :: [a] -> a
16:32:35<quicksilver>what if it doesn't have a steady state, for example ;)
16:32:44<PeakerWork>SamB_XP: you can change the type of the whole tuple with first and second. With lens you can't, but you can compose the getter as well as the setter. I wonder if its possible to get both advantages
16:32:51<dirk_>> break ('c'==) "abcd"
16:32:52<lambdabot> ("ab","cd")
16:32:53<ski>lilac : btw, that (`import ...') would be a nice idea, even if one couldn't restrict operations .. i sometimes list the types of imported (and exported) operations in comments, like that
16:33:13<dirk_>I want only the first part
16:33:35<quicksilver>dirk_: so pattern match it out
16:33:37<ski>> takeWhile ('c' /=) "abcd"
16:33:39<lambdabot> "ab"
16:33:42<quicksilver>let (x,y) = break ....
16:33:44<quicksilver>and use the 'x'
16:33:49<dirk_>ok
16:33:51<quicksilver>of course, takeWhile is more sensible for this case.
16:33:55<ski>`takeWhile', folks !
16:34:03<quicksilver>but I think it's good to understand how to use pattern matches to unpack pairs
16:34:07<quicksilver>you'll want it sooner or later.
16:34:18<ski>yes
16:35:33<ski>ACTION wonders why `break' and `takeWhile', but not `span' and `dropWhile' is in LB `src'
16:35:43<Taejo>@pl (\z -> z - f z/f' z)
16:35:43<lambdabot>ap (-) (liftM2 (/) f f')
16:36:06<doserj>quicksilver: you need to trust the tool to do the right thing, otherwise you feel like you lose control, I guess. We switched from assembler to higher-level languages because we trust the compiler nowadays
16:38:55<doserj>ACTION doesn't yet trust fancy tools, like eclipse has, either...
16:41:22<ski>gwern : i've sometimes wanted `done :: Monad m => m (); done = return ()' too .. but maybe people feel that's too trivial ?
16:41:52<ski>`if blah then done else do bleh' looks nice :)
16:42:14<doserj>ski: when (not blah) bleh
16:42:25<ski>yes, but consider a `case'
16:43:05<Taejo>@hoogle Complex a -> a
16:43:05<lambdabot>Data.Complex imagPart :: RealFloat a => Complex a -> a
16:43:06<lambdabot>Data.Complex magnitude :: RealFloat a => Complex a -> a
16:43:06<lambdabot>Data.Complex phase :: RealFloat a => Complex a -> a
16:43:08<EvilTerran>i believe the conventional name would be "skip"
16:43:16<ski>ACTION took an `if'-`then'-`else' because he didn't want to write as much .. but should have taken `case', instead
16:43:34<ski>i suppose that could work, as well
16:44:01<ski>(it may be i've seen `done' in "Haskell: The Craft of Functional Programming" ..)
16:44:36<alexsura1i>Is there a way to get the nth root of a number?
16:44:36<ski>(at least that's where i've seen `(>@>)', which now seems to be called `(>=>)')
16:44:49<ski>> 27 ** (1/3)
16:44:51<lambdabot> 3.0
16:44:54<ski>> 64 ** (1/3)
16:44:55<lambdabot> 3.9999999999999996
16:45:21<jeffersonheard>Weird. Okay, so that problem I reported on earlier seems to be a bug in Data.IntMap
16:45:22<alexsura1i>Thanks
16:45:36<jeffersonheard>I switched the data structure to Data.Map and no longer see the clobbering
16:47:12<ski>@let nthRoot radix radicand = radicand ** recip radix
16:47:14<lambdabot> Defined.
16:47:16<ski>@type nthRoot
16:47:18<lambdabot>forall a. (Floating a) => a -> a -> a
16:47:36<ski>> nthRoot 5 32
16:47:38<lambdabot> 2.0
16:47:44<Gracenotes>D:
16:47:53<Lemmih>jeffersonheard: Clobbering?
16:48:15<gwern>ski: yeah, done probably isn't worthwhile; return () is only a little longer than done
16:48:28<jeffersonheard>Yeah -- see my cafe post... I was seeing map entries in Cache.times simply disappear and others fail to be deleted
16:48:36<Axman6>i think done is a good idea
16:48:47<mux>return should be called unit or inject or something
16:48:49<Lemmih>jeffersonheard: URL? I don't subscribe to haskell-cafe@
16:48:51<Axman6>ACTION raises his hand to vote for adding done
16:48:59<ski>mux : or `pure' :)
16:49:18<mux>ACTION nods
16:49:31<jeffersonheard>http://www.nabble.com/Weird-and-entirely-random-problem...-td23966061.html
16:50:33<doserj>jeffersonheard: what is actually the problem with the result there?
16:51:02<mux>ACTION likes `inject' somehow
16:51:05<ski>when on the topic of `ignore :: Monad m => m a -> m ()' ..
16:51:18<ski>@let ma `after` mb = do b <- mb; ma; return b
16:51:20<lambdabot> Defined.
16:51:23<ski>@type after
16:51:25<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> m b -> m b
16:51:29<ski>is handy sometimes, too
16:51:32<jeffersonheard>well, in the hpasted module, times and store should always be symmetrical. that is... "times" should always have as values exactly the keys in "store"
16:51:43<mux>ski: that's <*
16:51:51<ski>that may be
16:51:55<mux>(in an applicative functor setting)
16:52:11<jeffersonheard>get, put, and free all preserve this invariant
16:52:14<ski>ACTION hasn't really looked that closely at all the applicative operations
16:52:15<ski>mux : ty
16:52:30<ski>(though i still think some of those operations have bad names)
16:54:09<Asztal><**> is a weird name.
16:54:19<ski>as is `<*>'
16:54:44<gwern>ok, there goes the email to library
16:54:56<ski>(about ?)
16:55:05<Asztal>is <,> a valid name? I have a feeling it's not :(
16:55:27<gwern>ski: ignore. the thing I've been discussing and mentioning for the last hour or so
16:55:37<ski>@type (<,>) = () in (<,>)
16:55:38<lambdabot>parse error on input `,'
16:55:40<ski>nope
16:55:53<ski>gwern : ok
16:56:01<gwern>> let (<,>) = (+) in 1 <,> 2
16:56:02<lambdabot> <no location info>: parse error on input `,'
16:56:14<gwern>> let (<.>) = (+) in 1 <.> 2
16:56:16<lambdabot> 3
16:56:23<gwern>guess commas are reserved for lists
16:56:35<byorgey>and tuples
16:56:44<ski>and records
16:57:25<doserj>import and export lists...
16:58:01<byorgey>record field separators...
16:58:14<byorgey>oh, ski already said that, whoops =)
16:59:22<ski>(and list comprehension and pattern guards :)
17:00:38<doserj>and functional dependencies
17:00:51<byorgey>COMMAS ARE SPESHUL
17:01:38<doserj>and context lists
17:02:13<ski>and coordination in type signatures
17:02:17<ski> foo,bar :: Baz
17:04:43<ski>ACTION wonders if the "name uses of comma" game is over
17:05:07<byorgey>that depends whether anyone names any more.
17:05:30<byorgey>going once... going twice...
17:05:31<ski>so it's a refutative question
17:05:57<doserj>fixity declarations
17:06:08<FliPPeh>If I use "main" somewhere in my code to restart the program, just like a loop, will it some day in the future, after a lot of "main" calls stack overflow, or will that be optimized?
17:06:12<byorgey>oho!
17:06:50<gwern>no, not the dreaded tail call question
17:06:53<gwern>!
17:07:01<byorgey>FliPPeh: nope, the memory associated with the old calls will get garbage-collected
17:07:17<FliPPeh>:)
17:07:21<SamB>FliPPeh: if you do a generalized tail call you're fine
17:07:34<FliPPeh>I just call it on a single line in a DO block
17:07:52<byorgey>as long as nothing is supposed to happen after that call to main returns
17:08:06<SamB>yeah, there'd better be noplace to return to but main's caller
17:08:17<FliPPeh>Left e -> do liftIO $ putStrLn ("Failure receiving data: " ++ show e)
17:08:17<FliPPeh> liftIO $ hClose h
17:08:17<FliPPeh> liftIO main
17:08:20<FliPPeh>Thie is it
17:08:24<FliPPeh>this*
17:08:38<hackagebot>fft 0.1.4 - Bindings to the FFTW library. (JedBrown)
17:08:57<BONUS>do people usually factor out lifting operations
17:09:08<SamB>FliPPeh: would the program exit without doing anything else if you didn't have that main call there?
17:09:17<FliPPeh>Yes
17:09:26<FliPPeh>Well, no
17:09:26<SamB>well, you're probably safe then
17:09:29<BONUS>e.g. do a; liftIO $ do a; b; c;
17:09:39<FliPPeh>It would do nothing
17:09:42<FliPPeh>Lock up I suppose
17:09:51<pumpkin>@quote bonus
17:09:51<lambdabot>No quotes match. Just what do you think you're doing Dave?
17:09:53<SamB>FliPPeh: eh?
17:09:58<SamB>what do you mean, lock up?
17:10:14<FliPPeh>Not lock up
17:10:19<SamB>I believe when main returns, all threads are killed
17:10:21<FliPPeh>I have actually no idea what would happen
17:10:28<jix_>FliPPeh: just try it then
17:10:30<ski>BONUS : i would usually, i think
17:10:35<FliPPeh>It's in a try-catch block
17:10:44<BONUS>yeah me too. less characters to type
17:10:45<FliPPeh>Captures and exception
17:11:05<SamB>FliPPeh: oh. I guess you'd overflow some sort of stack, then
17:11:12<ski>(i suppose in some cases one could expect that some non-`liftIO'ed operations would be inserted later, and then not do it)
17:11:14<SamB>with all those try/catches piling up
17:11:34<FliPPeh>How else could I restart there?
17:11:55<SamB>FliPPeh: well, you could factor out the thing inside the try/catch
17:12:06<FliPPeh>It's a socket error
17:12:09<SamB>and call that instead
17:12:13<FliPPeh>The connection code is in main
17:12:28<SamB>FliPPeh: I meant, the code that gets called with the exception handler in place
17:12:36<SamB>you could put that in it's own function
17:12:40<SamB>realMain, or something
17:12:56<SamB>then call THAT instead of main in your tail call
17:13:32<SamB>it'd be nice if there was some kind of tail recursion checker tool ...
17:13:44<SamB>to see if you're actually doing tail recursion when you want to be
17:13:45<ski>ah
17:14:03<ski>@type catch
17:14:04<lambdabot>forall a. IO a -> (IOError -> IO a) -> IO a
17:14:23<ski>you want an `IO a -> (IOError -> IO b) -> (a -> IO b) -> IO b' :)
17:14:35<SamB>ski: eh?
17:15:34<ski>see <http://martin.jambon.free.fr/extend-ocaml-syntax.html#lettry>
17:15:54<ski>SamB : actually, i meant that for FliPPeh
17:16:11<SamB>ski: I'm puzzled a bout why FliPPeh wants it, though
17:16:20<FliPPeh>It's a bot
17:16:29<FliPPeh>Automatic recover on connection failure
17:16:36<ski>i suppose it depends on the structure of FliPPeh's actual code
17:16:47<SamB>or rather how you came to the conclusion that FliPPeh wants it
17:17:24<ski>but the case where you want to have a loop, where the body of the loop is inside a "try-catch block", but not the recursive call is what that link was about
17:17:32<SamB>hmm. I wonder if I can read exception-using ML
17:17:43<ski>the point is that in `catchBind :: IO a -> (IOError -> IO b) -> (a -> IO b) -> IO b'
17:18:14<ski>say `catchBind body handler continue', only `body' has the new exception handler, not `continue'
17:19:31<SamB>ski: how does it get from b to b'?
17:19:50<SamB>oh, wait, that's supposed to be a right single quote
17:20:03<ski>that's supposed to be a closing single-quote
17:20:07<SamB>you do know ` isn't really a left quote, right?
17:20:31<ski>(yes, but i don't know of a better alternative, rn)
17:20:42<Zao>» do it like the french « ?
17:20:53<ray>that's backwards
17:21:12<Zao>Apparently one is supposed to use the angles »like this» over here.
17:21:54<ray>that's rightwards
17:23:10<ski>(SamB : `Some',`None' is the O'Caml version of `Just',`Nothing')
17:23:14<dirk_>is there a way to flatten a list ["a","b","c"] -> "abc"
17:23:23<ski>> concat ["a","b","c"]
17:23:24<lambdabot> "abc"
17:23:36<dirk_>ok
17:23:44<doserj>»do it like the germans«, or «do it like the french»
17:23:50<glguy>‘single quotes’
17:23:58<glguy>“double quotes”
17:24:15<doserj>actually, »do it like the germans«, or « do it like the french », I guess
17:24:44<FliPPeh>!hpaste
17:24:46<FliPPeh>@hpaste
17:24:47<lambdabot>Haskell pastebin: http://hpaste.org/new
17:29:38<uzytkownik>@pl \(x, y) -> (Just x, Just y)
17:29:39<lambdabot>Just *** Just
17:29:53<FliPPeh>If anyone has time, please take a look at my code (http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5736#a5736) and help me figure out how to implement part 4 of my TODO list? I already tried doing that with a thread, but it fails for StateT, since threads have to do IO
17:29:57<FliPPeh>:(
17:30:30<uzytkownik>@hoogle (***)
17:30:31<lambdabot>Control.Arrow (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
17:38:16<gwern>huh. what a surprisingly positive response on libraries
17:38:57<gwern>usually proposals get eaten alive there
17:39:27<BONUS>for ignore?
17:39:34<SamB>ACTION decides to look rather than ask
17:41:45<gwern>BONUS: yah
17:42:03<Taejo>@pl \n x -> (,) n <$> x
17:42:03<lambdabot>(<$>) . (,)
17:42:07<BONUS>cool. i also like the previous suggestion of return () = done
17:42:13<gwern>no, it's for my proposal to make ghc insert unsafeCoerces whenever statements don't typecheck, so as to make haskell more friendly to noobs
17:42:17<gwern>-_-
17:42:27<BONUS>haha
17:42:32<gwern>BONUS: well, one thing at a time
17:42:35<FliPPeh>Spam!
17:42:36<BONUS>also add goto
17:42:39<FliPPeh>If anyone has time, please take a look at my code (http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5736#a5736) and help me figure out how to implement part 4 of my TODO list? I already tried doing that with a thread, but it fails for StateT, since threads have to do IO
17:42:43<gwern>I didn't suggest forkIO's type sig change either, even though that's sensible
17:42:53<hackagebot>Hieroglyph 3 - Purely functional 2D drawing (JeffersonHeard)
17:43:05<SamB>gwern: huh, funny how ZMachine is at the beginning of "alphabetical" order ;-P
17:43:18<gwern>SamB: no, it's perfectly logical
17:43:30<gwern>you see, my ~/bin goes agda, archive/ZMachine, ...
17:44:03<conal>ack "functional drawing" -- oxymoron?
17:44:14<jeffersonheard>latest upload of Hieroglyph fixes OpenGL support seriously
17:44:15<SamB>is that in ext2fs_dir_entry order?
17:44:30<jeffersonheard>uh... yeah. I guess that package descriptor is left over from when I made the original
17:44:37<jeffersonheard>could change that in the next release
17:44:41<jeffersonheard>:P
17:44:43<conal>jeffersonheard: :)
17:45:32<Taejo>@pl \n x -> ((,) n) <$> x
17:45:33<lambdabot>(<$>) . (,)
17:45:39<conal>jeffersonheard: could even be "functional 2d drawings" if that's what you mean.
17:45:52<conal>noun==functional, verb==imperative
17:46:21<jeffersonheard>functional 2d graphics for visualization more like, but yes, that's the general picture.
17:46:30<conal>sounds good :)
17:46:36<Taejo>Haskell: where doing is a thing
17:47:02<conal>as in "haskell: the world's finest imperative programming language"
17:47:14<jeffersonheard>starting to get a better handle on what a Primitive is, considering making it a typeclass, allowing people to define their own primitives
17:47:42<conal>jeffersonheard: a handle on a denotational model for Primitive?
17:47:49<jeffersonheard>gradually
17:47:54<jeffersonheard>not ready to completely replace it
17:47:55<jeffersonheard>yet
17:48:11<jeffersonheard>but yes. supporting the primitives in OpenGL has given me a much better handle on what they are
17:49:58<conal>i've been puzzling over memoizing *polymorphic* functions. anyone ever played with the idea?
17:50:28<jeffersonheard>also getting closer to a release of a 3D fork of hieroglyph. main barrier has been caching and supporting buffer objects for larger geometries
17:50:32<Saizan>conal: so you'd take the concrete type as part of the key?
17:50:47<jeffersonheard>but getting the cache nailed down today thanks to Neil has solved that problem
17:50:57<conal>Saizan: perhaps. in somehow-reified form
17:51:47<pumpkin>hieroglyph needs support for hieroglyphs!
17:51:48<conal>Saizan: though with "lazy" (Hughes-style) memoization, one doesn't need to delve into the representation.
17:52:05<conal>Saizan: so a stable name is enough, except for getting types right.
17:53:08<conal>i have a form that can handle polymorphic functions of type 'forall a. HasType a => k a -> v a', where HasType involves the GADT of type-equality proofs.
17:53:30<conal>but i don't think that type is flexible enough for my uses.
17:53:44<jeffersonheard>I hate to release a single module as a separate library, but if anyone wants the polymorphic LRU cache that i'm using in Hieroglyph split out into a separate library speak now
17:54:14<jix_>sounds interesting
17:54:29<conal>jeffersonheard: what do you use LRU for in Hieroglyph?
17:54:52<Saizan>jeffersonheard: polymorphic in which sense?
17:55:08<jeffersonheard>conal: caching images and soon bufferobjects in the OpenGL version of Hieroglyph
17:55:32<conal>jeffersonheard: neat.
17:55:42<jeffersonheard>just standard polymorphism: Anything you can store in Data.Map you can store in the cache
17:56:04<jeffersonheard>cache supports upper bounds on size, and is compatible with the State monad if you desire to use it that way
17:56:33<jeffersonheard>as in keys must be Ord, but no other restrictions on storage
17:56:41<m00re>Has anyone here useed the hscurses package?
17:58:17<Saizan>jeffersonheard: but do you store polymorphic values or just values of different types?
17:58:45<jeffersonheard>just values of different types. I suppose it'd be a neat trick to support polymorphic values...
17:59:16<Saizan>jeffersonheard: however i think i'd like to see it available, bonus points if it manages serialization :)
18:16:58<FliPPeh>I just HAVE to run a Thread in a StateT-started code, to access the state..
18:17:03<FliPPeh>I can't do it :(
18:20:02<anq>Mh. I have seen on multiple occasions type classes that appear not to declare any methods. What are such constructs used for? Perhaps it's obvious, I just don't get it.
18:20:20<sboult>how can i import a library?
18:21:11<pumpkin>import Library
18:21:14<FliPPeh>:)
18:21:45<FliPPeh>Hah, fixed
18:21:46<pumpkin>anq: to make statements about a class that people are expected to follow even if the rules aren't representable in haskell
18:21:57<FliPPeh>Okay..
18:22:05<FliPPeh>How do I get the current time in UNIX seconds?
18:22:30<FliPPeh>Not that big bulky CalendarTime or ClockTime
18:22:48<FunctorSalad_>System.Posix.Time
18:22:51<FunctorSalad_>.epochTime
18:22:59<sboult>but i need to write, for example "import Array", on my xt
18:23:00<Zao>System.Posix.Time.epochTime
18:23:05<sboult>txt*
18:23:07<FliPPeh>Thanks :)
18:23:10<Zao>ACTION blames his slow internets.
18:23:13<FliPPeh>@t epochTime
18:23:13<pumpkin>anq: say you have Monoid and CommutativeMonoid as classes... we can write the Monoid methods just fine, but CommutativeMonoid is just a Monoid whose mappend is commutative... we can't express that, but if we have a function that has a constraint on CommutativeMonoid, it's saying that "we expect that if you've made an instance of this, that we can use your mappend commutatively"
18:23:14<lambdabot>Maybe you meant: tell thank you thanks thx ticker time todo todo-add todo-delete topic-cons topic-init topic-null topic-snoc topic-tail topic-tell type . ? @ ft v
18:23:19<FunctorSalad_>Zao: :)
18:23:30<FliPPeh>:t epochTime
18:23:31<lambdabot>Not in scope: `epochTime'
18:23:33<FliPPeh>:d
18:24:03<pumpkin>anq: does that make sense? that's one reason I can see for a typeclass with no methods, but there may be others :)
18:24:21<anq>pumpkin, perhaps. Let me think for a moment. :)
18:24:34<FunctorSalad_>and type-level functions..
18:24:46<FunctorSalad_>(with fundeps)
18:25:15<pumpkin>ah
18:25:21<dino->pumpkin: Are phantom types related to this?
18:25:44<FliPPeh>Okay, and how do I get the epoch time under WINDOWS?
18:26:16<dino->FliPPeh: Let me look, something with Data.Time... I think
18:26:35<pumpkin>dino-: not sure, I've seen them used for various things where you want to enforce limits on the kinds of types you can use together without there being any "value-representable" reason for doing so
18:26:45<pumpkin>dino-: but I'm no expert :)
18:26:53<_Stefan_>hello everyone
18:27:40<FliPPeh>If I can't use threads here, I'll just use the pauses from the "hWaitForInput" call to check if 5 minutes have passed, and run a command to check the connection status :)
18:27:41<anq>pumpkin, therefore, given 'class Monoid [...] => CommutativeMonoid [...]' we would imply, by the name of the subclass, for the user that if he makes instances of it, then the mappend function is supposed to be commutative without the actual ability to enforce it by Haskell itself. Similarly to the Monad laws?
18:27:43<_Stefan_>is someone willing to answer a noob a question
18:28:18<pumpkin>anq: I think so, yeah... a typeclass can just be seen as a statement about the "capabilities" of a type (sometimes with methods to access those capabilities)
18:28:35<pumpkin>or rather, a typeclass instance can be seen as a statement
18:28:48<pumpkin>I'm not sure if that's a good way of looking at it
18:28:53<pumpkin>ACTION shrugs :)
18:29:04<FunctorSalad_>can you make rewrite rules for such dummy typeclasses?
18:29:16<pumpkin>what for?
18:29:19<Cale>_Stefan_: yeah :)
18:29:20<FunctorSalad_>that would be a possible use...
18:29:32<pumpkin>oh I see
18:29:38<_Stefan_>@Cale
18:29:38<lambdabot>Unknown command, try @list
18:29:52<_Stefan_>thanks, but i'm not very good with this
18:29:52<Cale>_Stefan_: (Though it's impossible for anyone to answer if you will not ask it ;)
18:29:59<pumpkin>can you put constraints on rewrite rules? I've never written any with constraints, but I don't see why it shouldn't be possible
18:30:02<dino->FliPPeh: Does this work? > Control.Monad.liftM (truncate . Data.Time.Clock.POSIX.utcTimeToPOSIXSeconds) Data.Time.getCurrentTime
18:30:04<anq>pumpkin, aye, but then such constructs would be of a rather transient nature. More like synonyms that by their naming add some sense that is beyond Haskell's capabilities of expression. Still, not useless. :) Thanks for the perspective.
18:30:28<voker57_>@hoogle (Floating a) (Integral b) => a -> b
18:30:29<lambdabot>Parse error:
18:30:29<FliPPeh>Yep
18:30:29<lambdabot> --count=20 "(Floating a) (Integral b) => a -> b"
18:30:29<lambdabot> ^
18:30:29<FunctorSalad_>for commutativity, rewrite rules are sort-of a bad idea though ;)
18:30:30<FliPPeh>Thanks!
18:30:33<dino->coool
18:30:39<anq>FunctorSalad_, what are rewrite rules?
18:30:40<voker57_>@hoogle (Floating a), (Integral b) => a -> b
18:30:41<lambdabot>Parse error:
18:30:41<lambdabot> --count=20 "(Floating a), (Integral b) => a -> b"
18:30:41<lambdabot> ^
18:31:14<_Stefan_>How would I go about writing a program, that reads multiple lines from STDIN, and stores them in a list
18:31:14<pumpkin>anq: maybe Cale has more perspective on it :) he's been around way longer than I have and seems to be good at expressing things clearly
18:31:14<FunctorSalad_>anq: pragmas that tell ghc that it can simplify expressions in a given way
18:31:58<FunctorSalad_>anq: like "{-# RULES "head/cons": forall x xs. head (x:xs) = x #-}" (not sure if that was the exact syntax0
18:32:20<anq>Ah, right.
18:33:00<anq>FunctorSalad_, covered here ( http://www.haskell.org/haskellwiki/GHC/Using_rules ) I suppose.
18:33:39<FunctorSalad_>yep
18:34:04<anq>Thanks. :)
18:38:06<jix_>if i have a recursive algorithm on a tree that mutates the tree and have a lot of subtree sharing... how can i optimize that in haskell?
18:39:17<FunctorSalad_>hmm... that wiki site says "We assume that non-confluent rewriting systems are bad design, but it is not clear how to achieve confluence for any system." -- what about Knuth-Bendix?
18:40:18<EvilTerran>voker57_, the syntax you're looking for is (Floating a, Integral b) =>
18:41:23<byorgey_>jix_: this algorithm is already written in Haskell and you want to optimize it? or it is just an algorithm and you want to know how to write an optimized version in Haskell?
18:41:36<jix_>byorgey_: not written already
18:42:09<byorgey>jix_: well, from the way you've described it, it sounds like it would fit Haskell very naturally. I don't think you'll need to do any "optimization", just write it.
18:42:15<jix_>if i was to implement it in an imperative language i'd use pointers and thereby transform all shared subtrees automatically
18:42:22<byorgey>jix_: in particular, the subtree sharing will happen automatically.
18:42:41<pumpkin>not always
18:42:44<jix_>byorgey: it seems it doesn't
18:42:57<pumpkin>I've had trouble writing DAWGs
18:43:00<jix_>byorgey: i did some simple test cases where the sharing was a lot more obvious than for the real problem
18:43:12<jix_>and used trace to see how often things are evaluated
18:43:15<pumpkin>jix_: used vacuum?
18:43:31<jix_>pumpkin: what's that?
18:43:41<pumpkin>@hackage vacuum
18:43:41<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/vacuum
18:43:43<byorgey>jix_: well, then I'd have to see your code, or more details on exactly what you are trying to do
18:44:10<anq>pumpkin, http://tinyurl.com/lmffz7 -- Here the application of said type class variant is demonstrated in X Monad's source. It's interesting.
18:44:13<jix_>byorgey: ok i'll write a small subset of the problem unoptimized first then
18:44:25<byorgey>ok.
18:44:46<pumpkin>anq: ah yeah, cool :)
18:46:02<conal>jix_: check out functional memoization, e.g., http://conal.net/blog/tag/memoization/
18:47:26<conal>jix_: if you write a tree-transforming recursive function naively, you'll lose sharing & do redundant work -- possibly exponentially so.
18:48:09<conal>jix_: one solution is memoization. another is to avoid the traversal and build optimized trees bottom-up, e.g., with "smart constructors".
18:48:18<jix_>conal: there isn't so much sharing that it would be exponentially...
18:48:30<anq>Is there a comprehensive list of Haskell's features?
18:48:37<jix_>conal: and not so much sharing that i think memoization using hash tables would help
18:48:47<jix_>even tho i have to try it to be sure
18:48:50<conal>jix_: or memo tries
18:49:14<uzytkownik>To construct TypeRep for type Module.Type do I need to call mkTyConApp (mkTyCon "Module.Type") []? If not how should I do it?
18:49:35<conal>jix_: if sharing is rare, then a naive functional recursive traversal may be efficient enough.
18:50:18<jix_>conal: but i'd still loose sharing after a transform
18:50:31<jix_>i'd probably have a lot of sharing... but not a lot of sharing of the same subtrees
18:51:00<jix_>but otoh memory usage might turn out to be not a problem at all
18:51:09<conal>jix_: sharing but not of trees? leaves?
18:51:30<jix_>conal: sharing of trees but not that i have one tree like 400 times... but 100 subtrees like 4 times
18:52:00<conal>jix_: and you don't think memoization will help?
18:52:28<gwern>anq: not really. features is so subjective
18:53:00<jix_>i haven't tried it but i think that since most of the time it won't be computed already the lookup etc will cost more than it saves in the end
18:53:30<conal>jix_: because the avoided computation is cheap?
18:53:40<jix_>yeah very
18:53:46<anq>gwern, perhaps - but there is (for me) new terminology all over the place in almost every respectable paper or lecture note about Haskell and I have no idea to approach the study of the language systematically without a compilation of concepts that are central to Haskell.
18:53:56<conal>jix_: oh. then why worry about sharing?
18:53:57<anq><how to>
18:54:00<gwern>anq: wikipedia is pretty good in that respect
18:54:54<jix_>conal: because i have to do that cheap calculation a lot
18:55:07<jix_>conal: and if i can halve that... i'd be happy
18:56:47<jix_>conal: building the optimized version right away sounds interesting and might be the solution to my problem
18:57:09<conal>jix_: that's what i usually do.
18:57:20<jix_>but i'm not sure i can do that
18:57:25<anq>gwern, mhh. Not sufficiently exhaustive. :P But thanks.
18:57:37<conal>jix_: see, e.g., "compiling embedded languages"
18:59:22<mmorrow>omg, just built pimped-out doxygen docs for the linux kernel... 3.7GB or callEE/ER graphs (graphviz-rendered imagemaps), "cooperation diagram" graphs for every struct, header file dep graphs, global struct/function/defines index, highlighted source code with hyperlinked identifiers...
18:59:44<mmorrow>putting it online if it ever finished bzip2'ing then uploading
18:59:48<conal>mmorrow: holy crap!
18:59:50<mmorrow>s/ed/ing/
18:59:56<mmorrow>conal: they're amazing
19:00:42<conal>mmorrow: please publish some teasers for us to look at w/o having to graph the whole bz2 file.
19:01:09<mmorrow>heh, i was just trying to find the coolest few callgraphs to put up :)
19:02:29<jix_>conal: i think by returning functions that allow me to interleave the transforms before the complete tree is constructed instead of returning the complete tree or something similar might work...
19:03:06<conal>jix_: cool
19:10:16<hackagebot>Hieroglyph 3.1 - Purely functional 2D graphics for visualization. (JeffersonHeard)
19:10:51<jeffersonheard>just a minor bugfix for the selection buffer in OpenGL. I forgot to take out a debug print statement
19:10:57<conal>jeffersonheard: yay for the new description!
19:16:06<mmorrow>conal: here're a few http://moonpatio.com/linux/
19:16:44<conal>mmorrow: fun!
19:17:10<mmorrow>totally, each file has two of these for every function :o
19:17:39<mmorrow>(and each struct has an analogous graph with s/calls/member-types/)
19:18:11<conal>mmorrow: what does *red* mean in box color?
19:19:29<mmorrow>ah, one sec
19:20:55<mmorrow>err, so this is the legend for the stuct graphs: http://moonpatio.com/ghc/rts/html/graph_legend.html
19:21:13<PetRat>How do you make something an instance of Whow? I can't define 'print' because it tells me it's not a visible method of Show.
19:21:20<mmorrow>the red means "A graph is truncated if it does not fit within the specified boundaries." for those
19:21:23<PetRat>-> Show <-
19:21:30<mmorrow>so i guess maybe the same for the callgraphs
19:21:37<pumpkin>mmorrow: did you ever find a good way of compiling huge unboxed constructors without GHC's ram usage exploding?
19:21:54<conal>PetRat: print is defined via 'show'. so you define 'show'
19:22:28<dino->PetRat: It's also possible that Show can be derived for you. Try 'deriving Show' after the type definition.
19:22:33<mmorrow>pumpkin: i haven't, but i haven't tried anything since when we were talking about it though
19:22:38<pumpkin>ah
19:23:03<PetRat>I'm trying to make Identity an instance of Show so I'm not sure I can derive it.
19:23:22<conal>StandaloneDeriving
19:23:23<PetRat>What is the type sig of show? show :: a -> String?
19:23:28<MyCatVerbs>Yes.
19:23:43<PetRat>conal: is that something that can help me?
19:23:56<MyCatVerbs>If you want to define a Show instance, you need to define showsPrec rather than just show, IIRC.
19:24:15<conal>PetRat: yeah. if you want to derive an instance but do so separately from the data/newtype definition.
19:24:35<byorgey>so you will need GeneralizedNewtypeDeriving and StandaloneDeriving.
19:24:53<byorgey>then say 'deriving instance Show a => Show (Identity a)'
19:24:59<mauke>why generalized newtype?
19:25:02<mmorrow>the docs are 2.8 GB bzip2ed, uploading now..
19:25:13<mauke>we're not autolifting an instance here
19:25:18<mmorrow>eta 3hours and climbing
19:25:20<byorgey>oh, right, sorry
19:26:01<PetRat>byorgey: are those pragmas?
19:26:57<byorgey>PetRat: yes, just put {-# LANGUAGE StandaloneDeriving #-} at the top of your .hs file
19:27:27<byorgey>PetRat: and I was wrong, you don't need GeneralizedNewtypeDeriving
19:28:36<PetRat>byorgey: it works! thanks
19:28:45<byorgey>great!
19:29:01<PetRat>Obviously this is just an exercise. This is not for any practical purpose, just trying out a few things.
19:29:50<PetRat>byorgey: I'm working through typeclassopedia and currently looking at "Monad transformers step by step". What's valuable about your article is not jusst the article itself, but the references.
19:30:06<dino->Wait a second, that deriving above works?
19:31:01<PeakerWork>byorgey: why do you need standalone deriving and not attach it to the type?
19:31:53<byorgey>PetRat: good, I'm glad it's useful!
19:32:13<byorgey>PeakerWork: PetRat wanted an instance for Identity, which is already declared in another module.
19:32:58<byorgey>dino-: why not?
19:34:02<dino->byorgey: I hadn't seen that syntax, deriving instance...
19:39:58<byorgey>dino-: http://www.haskell.org/ghc/docs/latest/html/users_guide/deriving.html#stand-alone-deriving
19:41:00<byorgey>dino-: new since 6.8.1
19:42:41<mmorrow>conal: here're some struct graphs, which i think are more interesting than the callgraphs actually http://moonpatio.com/linux/structs/
19:43:33<conal>ACTION looks
19:44:52<conal>mmorrow: pretty
19:45:11<mmorrow>i like how they label the edges
19:45:26<mmorrow>(all of these are html imagemaps in the docs)
19:45:52<conal>mmorrow: my favorite: http://moonpatio.com/linux/structs/structtimer__list__coll__graph.png . i like the symmetry & asymmetry.
19:46:11<mmorrow>ooh yeah toally, i'm staring at that one too right now actually :)
19:46:22<conal>:)
19:46:25<mmorrow>not that many loops in these C graphs..
19:46:32<mmorrow>(haskell on the other hand..)
19:46:35<opqdonut>subprocess_info is cute
19:46:40<mmorrow>s/loops/cycles/
19:47:01<conal>mmorrow: i'm wishing for some kind of swirling animation. especially in the timer_list/tvec_base interdependence.
19:47:11<mmorrow>heh totally
19:52:10<mmorrow>the doxygen parser seems to barf on function ptrs
20:15:31<dino->byorgey: re: deriving Thanks! I was called away from my desk for a while.
20:16:16<bavardage>how do I chain a set number of monadic operations together
20:16:36<bavardage>i.e. I want to basically do f >> f >> f >> f >> f >> f
20:16:50<bavardage>oh wait, but I want a result
20:17:05<bavardage>so kinda like mapM, but not mapping over anything
20:17:09<dino->:t sequence
20:17:10<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m [a]
20:17:11<bavardage>just calling the function a set number of times
20:17:26<dino->Oh, same f
20:17:56<bavardage>oh kk
20:18:03<bavardage>so sequence
20:18:08<dino->Maybe replicateM
20:18:15<dino->:t Control.Monad.replicateM
20:18:17<lambdabot>forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a]
20:18:31<byorgey>bavardage: it depends. should the result of each action be the input to the next? or should the results be gathered in a list?
20:18:33<bavardage>yes
20:18:38<bavardage>replicateM I think is it
20:18:41<bavardage>byorgey: in a list
20:18:47<byorgey>ok, yeah, then replicateM.
20:20:00<PeakerWork>@hoogle replicateM_
20:20:00<lambdabot>Control.Monad replicateM_ :: Monad m => Int -> m a -> m ()
20:20:22<PeakerWork>bavardage: or that if you don't keep the list
20:20:43<bavardage>thanks
20:24:20<uzytkownik>@pl maybe (return Nothing) (\x -> Just `fmap` (undefined x :: Int -> IO Int) x)
20:24:21<lambdabot>(line 1, column 63):
20:24:21<lambdabot>unexpected ">"
20:24:21<lambdabot>expecting variable, "(", "`", "!!", ".", operator or ")"
20:24:39<uzytkownik>@pl \y -> maybe (return Nothing) (\x -> Just `fmap` (undefined x :: Int -> IO Int) x) y
20:24:40<lambdabot>(line 1, column 69):
20:24:40<lambdabot>unexpected ">"
20:24:40<lambdabot>expecting variable, "(", "`", "!!", ".", operator or ")"
20:24:53<uzytkownik>@pl \y -> maybe (return Nothing) (\x -> Just `fmap` (undefined :: Int -> IO Int) x) y
20:24:59<lambdabot>(line 1, column 67):
20:25:00<lambdabot>unexpected ">"
20:25:00<lambdabot>expecting variable, "(", "`", "!!", ".", operator or ")"
20:25:58<uzytkownik>@pl \y -> maybe (return Nothing) (\x -> Just `fmap` return x) y
20:25:59<lambdabot>maybe (return Nothing) (return . Just)
20:26:28<byorgey>what a strange error message.
20:27:14<uzytkownik>@pl \y -> maybe (return Nothing) (\x -> Just `fmap` (return :: a -> IO a) x) y
20:27:15<lambdabot>(line 1, column 62):
20:27:15<lambdabot>unexpected ">"
20:27:15<lambdabot>expecting variable, "(", "`", "!!", ".", operator or ")"
20:27:25<uzytkownik>it fails on ::
20:29:57<uzytkownik>May be some human will know. I have a function a -> IO (Maybe b). I need to put it in function b -> IO c to get a function a -> IO (Maybe c). Is there any short way of doing it?
20:31:14<uzytkownik>I've achived: firstFunction >>= maybe (return Nothing) (\x -> Just `fmap` secondFunction x)
20:31:26<mauke>:t (>=>)
20:31:27<lambdabot>forall a (m :: * -> *) b c. (Monad m) => (a -> m b) -> (b -> m c) -> a -> m c
20:32:25<mauke>:t \f g x -> f x >=> maybe (return Nothing) g
20:32:26<lambdabot>forall t a a1 (m :: * -> *) a2. (Monad m) => (t -> a -> m (Maybe a2)) -> (a2 -> m (Maybe a1)) -> t -> a -> m (Maybe a1)
20:32:40<mauke>:t \f g -> f >=> maybe (return Nothing) g
20:32:41<lambdabot>forall a a1 (m :: * -> *) a2. (Monad m) => (a -> m (Maybe a2)) -> (a2 -> m (Maybe a1)) -> a -> m (Maybe a1)
20:33:14<mauke>:t \f g -> f >=> maybe (return Nothing) (fmap Just . g)
20:33:15<lambdabot>forall a a1 (f :: * -> *) a2. (Monad f, Functor f) => (a -> f (Maybe a2)) -> (a2 -> f a1) -> a -> f (Maybe a1)
20:35:00<jix_>conal: i think i got an optimization that works in my case http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2699#a2699
20:43:42<QP>hello, I have a question about XMonad
20:43:57<QP>can anyone tell me how to change keyboard layout?
20:44:00<TomMD>QP: You can ask, but the best help is probably in #xmonad
20:44:11<TomMD>QP: You mean the hotkeys?
20:44:13<QP>oh, i didn't realise there was another channel
20:44:23<TomMD>Yes, xmonad has its own channel - sweet, huh?
20:44:28<QP>no, i want to change from qwerty to dvorak
20:44:39<TomMD>QP: That would be an X11/x.org change, would it not?
20:44:51<QP>ok...
20:44:52<TomMD>It isn't the window manager that dictates that.
20:45:27<QP>i'm getting confused, becuase my previous way of changing layout seemed to be the window manager
20:45:51<dino->QP: That may actually be an xmodmap thing, I'm wondering.
20:45:51<QP>so i'll just edit x.org then?
20:46:07<TomMD>QP: I've seen a number of photos of Xmonad setups complete with a Dvorak. I don't know how to help you but I see numerous people in #xmonad, they can probably help.
20:46:14<dino->QP: You may be able to run the program you used to use if it's some gui, to change that stuff
20:46:18<mauke>the command is setxkbmap
20:46:36<dino->mauke: ah
20:47:23<QP>ok, i'll head to #xmonad and see what's hanging there... thanks for your help
20:48:22<[bjoern]>I have a function f(x,y) and want to display the values as an ascii matrix in ghc; suggestions?
20:48:59<FunctorSal>[bjoern]: printf to get the values to fixed width
20:50:35<dino->That new machine I want (Sager NP8662) has 1 HDMI and 1 DVI
20:50:37<dino->ok!
20:50:40<dino->haha
20:50:48<FunctorSal>then something like "line y = concat [ printTheValue (f x y) | x <- someRange ]"
20:50:57<dino->Sorry my Haskell friends, wrong irssi window
20:56:10<Badger>@src cycle
20:56:10<lambdabot>cycle [] = undefined
20:56:10<lambdabot>cycle xs = xs' where xs' = xs ++ xs'
20:57:36<conal>hm. would black-hole detection spot the bottom if the [] case were missing?
21:01:56<Badger>so
21:02:11<Badger>why *is* -> needed in anonymous functions?
21:02:20<Badger>rather than plain old =
21:02:50<opqdonut>to simplify the syntax i guess
21:03:17<Twey>Because = is semantically confusing
21:03:21<opqdonut>foo = \x y = asdf
21:03:25<opqdonut>that also
21:03:33<opqdonut>and . was overloaded enough already
21:03:58<Badger>ah
21:04:06<Badger>good point.
21:04:22<Twey>= is used for definitions
21:04:31<Twey>A lambda is not a definition, it's a literal
21:05:28<dirk__>how can I find out if a string begins with an other string
21:05:38<Twey>dirk__: isPrefixOf, in Data.List
21:05:43<dirk__>ok
21:13:06<[bjoern]>Thanks. I was hoping for something more simple... I just did it manually instead.
21:19:02<warrie>@type group
21:19:04<lambdabot>forall a. (Eq a) => [a] -> [[a]]
21:19:23<warrie>> group "Three bees see Lee."
21:19:24<lambdabot> ["T","h","r","ee"," ","b","ee","s"," ","s","ee"," ","L","ee","."]
21:19:45<warrie>> map length . group . sort $ "jijiwjisjiwjijsijwijsijwijisjiwjsijiwjisjiwjisjiwjisjiwjisjiwjisjiwjij"
21:19:46<lambdabot> [24,25,10,11]
21:20:17<warrie>ACTION pats lambdabot on the head.
21:20:28<mauke>@botsnack
21:20:28<lambdabot>:)
21:20:28<lunabot> :)
21:21:19<QP>> sort "snthsntthsnttheuhnoteionetuhntsnthnthsnthsnthsnthsnth"
21:21:20<lambdabot> "eeehhhhhhhhhhhinnnnnnnnnnnnoossssssssttttttttttttttuu"
21:24:12<FunctorSal>ehnostu! ehnostu!
21:24:19<byorgey>it's like someone very slowly telling you how to pronounce some Finnish word
21:24:40<mauke>ENOSTU
21:25:03<byorgey>probably with two t's, ENOSTTU
21:28:29<Gracenotes>patpat???
21:30:10<benmachine>when I do let zwt = zipWith (*) in my ghci (to save on typing, mostly) it seems to decide that zwt is [Integer] -> [Integer] -> [Integer] instead of (Num n) => [n] -> [n] -> [n] as I'd expect, is there any way to force it to be the latter?
21:30:33<benmachine>I tried doing let zwt = zipWith (*) :: blah but it didn't seem to care
21:30:52<mauke>benmachine: three solutions
21:31:10<mauke>1) put a type annotation on zwt 2) add a parameter to zwt 3) disable the monomorphism restriction
21:32:41<benmachine>can I do those at the interactive prompt? ghci didn't seem to pay attention to my type annotations
21:32:41<FunctorSal>the dreaded monodwarfism constriction...
21:32:54<FunctorSal>:set -XNoMonomorphismRestriction
21:32:57<FunctorSal>( benmachine )
21:33:08<mauke>benmachine: you didn't annotate zwt
21:33:27<benmachine>mauke: I guess not, how do I?
21:33:31<mauke>let zwt :: (Num n) => [n] -> [n] -> [n]; zwt = zipWith (*)
21:33:50<benmachine>ah
21:33:57<mauke>but 'let zwt x = zipWith (*) x' is a lot easier to type
21:34:20<benmachine>why does that change things?
21:35:07<byorgey>benmachine: you probably don't want to know. see http://haskell.org/haskellwiki/Monomorphism_restriction
21:35:14<benmachine>hah, okay
21:35:16<benmachine>thanks everyone
21:46:40<TomMD>Will killThread kill the thread even if it's blocked?
21:47:03<monochrom>I think yes.
21:51:03<malouin>http://hackage.haskell.org/packages/archive/formlets/0.4.8/doc/html/src/Text-Formlets.html#input'
21:51:23<malouin>So I'm trying to make an input that displays its own errors.
21:51:34<malouin>which means the display code has to validate itself.
21:52:48<malouin>The "value"-generating part of the formlet that ordinarily does the validating does not ever send any of its intermediate result o the 'display' part.
21:53:44<malouin>But I figured, the output of the display code as returned by runFormState is in the form's monad, so I should be able to run my (monadic) validator twice.
21:53:48<malouin>Suboptimal, but ok.
21:54:07<hackagebot>url 2.1 - A library for working with URLs. (IavorDiatchki)
21:55:04<malouin>However, after getting into this for a while, I notice that the function that input' takes returns something *not* in the formlet monad, so I either have to write my own input' function, or what I'm trying to do is completely impossible.
21:55:44<malouin>and the mystery for me is, why is the output of runFormState in the monad if this functionality is not used?
22:00:22<gwern>so I've been wondering. is there any downside to make forkIO :: IO a -> IO ThreadId?
22:00:23<travisbrady_>anyone know how many packages Hackage is up to these days?
22:00:32<gwern>travisbrady_: >1k
22:00:52<opqdonut>:t forkIO
22:00:53<lambdabot>Not in scope: `forkIO'
22:00:57<opqdonut>gah
22:01:06<opqdonut>@hoogle forkIO
22:01:06<lambdabot>Control.Concurrent forkIO :: IO () -> IO ThreadId
22:01:07<mauke>IO () -> IO ThreadId, I think
22:01:12<opqdonut>thought so
22:01:23<opqdonut>gwern: no downside imo
22:01:32<gwern>opqdonut: I was reading a post by ndm
22:01:34<opqdonut>other than the current one makes you explicitly ignore the return value
22:01:38<conal>gwern: loss of type-checking.
22:01:47<gwern>where he complained about how people using mapM where they meant mapM_ lead to memory leaks
22:01:48<opqdonut>i'd like forever to have a different type too
22:01:51<conal>i have the same beef with the type of (>>)
22:01:51<opqdonut>:t forever
22:01:52<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> m b
22:02:01<gwern>and said that if statements had to be IO () instead of IO a, code would be better
22:02:14<conal>opqdonut: already got changed
22:02:16<opqdonut>conal: oh you'd want it to be m () -> m a -> m a?
22:02:17<gwern>since it forced you to do something with the results, and let you not slide
22:02:23<opqdonut>oh, it did
22:02:25<opqdonut>cool
22:02:42<conal>opqdonut: yeah. or Monoid o :: m o -> m o -> m o
22:02:49<opqdonut>mhmm
22:03:11<conal>tho the latter is liftM2 mappend
22:03:18<conal>or liftA2 mappend
22:08:37<eu-prleu-peupeu1>hello
22:09:01<gwern>I've noticed that everytime I ask about something involving monads, people wind up wanking with some obscure derivation involving either monoids or applicatives
22:09:07<gwern>I don't know whether to be bothered by this or not
22:09:20<byorgey>hi eu-prleu-peupeu
22:10:47<Saizan>gwern: ndm's point applies to forkIO as much as (>>)
22:10:56<conal>gwern: monoid is an inevitable idea here, because it gives a default way to combine two values. applicative fits because liftM2 is really an unnecessarily special case of liftA2.
22:11:17<gwern>Saizan: I thought it did, but I'm unsure whether it's a good point in the context of forkIO
22:11:57<gwern>conal: but where are we combining values? forkIO just returns a threadid, which might as well be a constant for all it matters
22:12:02<Saizan>gwern: what's the difference between (>>) and forkIO here?
22:12:19<gwern>yah.
22:12:23<conal>gwern: in >>
22:12:34<Saizan>they both discard the result of one action
22:13:22<conal>url for ndm's post?
22:13:46<gwern>conal: it's in the 'ignore' thread on libraries
22:14:09<Saizan>conal: having (>>) = liftA2 mappend makes little sense for parsers, for example
22:14:18<conal>gwern: thx.
22:14:59<Saizan>conal: it's common to parse a keyword or any other delimiter and ignore its value
22:15:51<conal>Saizan: sure. i prefer m () -> m a -> m a
22:16:33<Hunner>Is there a pragma to hide a package?
22:17:09<Hunner>or another way to hide a package without specifying it on the command line?
22:17:48<Taejo>read "sin x" :: Expr
22:17:50<Taejo>> read "sin x" :: Expr
22:17:52<lambdabot> No instance for (GHC.Read.Read SimpleReflect.Expr)
22:17:52<lambdabot> arising from a use of...
22:17:56<Taejo>:(
22:18:00<Saizan>maybe {-# OPTIONS_GHC -hide-package foo #-} ?
22:19:15<gwern>Taejo: the Expr stuff isn't an interpreter :)
22:19:30<mauke>> read "x" :: Expr
22:19:31<lambdabot> No instance for (GHC.Read.Read SimpleReflect.Expr)
22:19:31<lambdabot> arising from a use of...
22:19:35<gwern>> sin x
22:19:37<lambdabot> sin x
22:19:39<mauke>ACTION slaps his brain
22:19:41<FliPPeh>I see that Xmonad and LambdaBot both can parse Haskell, atleast for lambdabot I know for sure. Is that some kind of built-in, or would I have to do that myself if I want to add something simiar?
22:19:44<gwern>> map (sin) [1..10]
22:19:46<lambdabot> [0.8414709848078965,0.9092974268256817,0.1411200080598672,-0.75680249530792...
22:20:00<gwern>hm, that wasn't what I intneded
22:20:07<mauke>FliPPeh: XMonad simply calls ghc to compile files
22:20:12<gwern>FliPPeh: what do you mean, xmonad can parse haskell?
22:20:14<hackagebot>control-event 1.0.0.0 - Event scheduling system. (ThomasDuBuisson)
22:20:17<Saizan>FliPPeh: there's hint, mueval, the ghc-api, haskell-src-exts ...
22:20:20<gwern>FliPPeh: also, lambdabot just shells out to mueval
22:20:26<Taejo>gwern: but I was hoping it was a parser
22:20:27<FliPPeh>Okay
22:20:35<gwern>FliPPeh: which accomplishes its haskell-fu by linking in the GHC API
22:21:10<FliPPeh>Would have been a nice scripting language for my own IRCly
22:21:18<Taejo>gwern: I've written a program that draws fractals ... the UI for Mandelbrot and Julia fractals are easy, Newton fractals not so much (without an expression parser)
22:21:41<gwern>FliPPeh: well, there are just haskell parsers. haskell-src and haskell-src-exts
22:21:44<gwern>they work pretty well
22:21:53<FliPPeh>Oh no
22:22:01<FliPPeh>I've seen that "Write Yourself a Scheme" tutorial
22:22:08<FliPPeh>That would be my next action :)
22:22:11<gwern>mueval uses haskell-src-exts to do some static analysis of submitted code, incidentally
22:22:30<gwern>FliPPeh: no no! REUSE REUSE REUSE! we have a scheme interpreter on hackage already!
22:22:42<FliPPeh>meh
22:22:44<Nereid_>lol
22:22:53<FunctorSalad>FliPPeh: there's a simplified interface to the ghc api on hackage (iirc called "hint")
22:23:00<gwern>repeat after me: 'if there is an appropriate library on hackage, I will use it and not roll my own'
22:23:02<gwern>all together now!
22:23:03<FunctorSalad>might be the right thing for irc scripting
22:23:23<FunctorSalad>but I didn't try it myself
22:24:21<FunctorSalad>gwern: well... some packages have no haddock whatsoever :-(
22:24:32<FunctorSalad>(a few)
22:24:39<gwern>the source is the best haddock!
22:24:52<FunctorSalad>sometimes there aren't even normal comments
22:25:04<benmachine>ACTION writes abnormal comments
22:25:11<FunctorSalad>:)
22:25:42<gwern>'-- | Come, it is time to discuss ships, sealing wax, of beavers and kings. Arg must be a non-negative integer.'
22:25:45<RayNbow>@users
22:25:46<lambdabot>Maximum users seen in #haskell: 658, currently: 595 (90.4%), active: 22 (3.7%)
22:25:49<malouin>@src lookup
22:25:50<lambdabot>lookup _key [] = Nothing
22:25:50<lambdabot>lookup key ((x,y):xys) | key == x = Just y
22:25:50<lambdabot> | otherwise = lookup key xys
22:25:57<conal>benmachine: always normalize your comments before checking in code!
22:26:11<FunctorSalad>gwern: is that a quote?
22:26:26<gwern>FunctorSalad: of course it is
22:26:42<conal>lewis carrol rolls over in his grave
22:27:09<gwern>conal: if carroll were alive today, he'd be writing quines and winning the obfuscated c contests!
22:27:19<conal>:)
22:29:18<RayNbow>hmm, http://www.cse.unsw.edu.au/~dons/irc/nick-activity.png <-- isn't the extrapolated nick count for 2009 a bit too optimistic?
22:29:59<gwern>RayNbow: I think it's more humorous than serious
22:30:16<gwern>dons knows perfectly well that on small bases, exponential extrapolations are more voodoo than science
22:30:29<RayNbow>gwern: ah k :p
22:33:58<FunctorSal>> let a=1/1000 in [ (1+a)**n - (1+n*a+n^2*a/2) | n <- [0..] ]
22:34:00<lambdabot> [0.0,-4.999999999999449e-4,-1.999000000000306e-3,-4.4969990000001125e-3,-7....
22:34:13<FunctorSal>gwern: fair enough isn't it? ;)
22:34:13<Badger>> e
22:34:15<lambdabot> e
22:37:46<FunctorSal>I probably missed the context while I was offline..
22:42:24<BONUS>say we have data F = forall a. F a
22:42:40<BONUS>a function F -> (forall a. a -> b) -> b doesn't make sense right
22:43:00<Saizan>why not=
22:43:01<Saizan>?
22:43:03<BONUS>because the a contained in the type and the one that the funciton takes don't have to be the same
22:43:37<Saizan>the function given as second parameter promises to be able to accept any a
22:43:54<Saizan>so you can instance it to the type contained in F
22:44:00<BONUS>aha i see
22:44:11<Hunner>Is there a way to tell haskell to re-evaluate an expression?
22:44:18<BONUS>but that function can only be const something then?
22:44:54<Saizan>BONUS: or seq, or wrapping in another existential
22:45:05<Saizan>BONUS: nothing really interesting though
22:45:20<BONUS>ah, i see
22:46:27<hackagebot>gps 0.2.4 - For manipulating GPS coordinates and trails. (ThomasDuBuisson)
22:46:32<Botje>Hunner: why? it would just give the same result
22:49:11<Berengal>Type hackery is hard
22:49:56<Saizan>let's go shopping?
22:49:56<Nereid_>Hunner: why would you do that?
22:50:19<Berengal>Saizan: I'm tempted to, but it also feels like I'm on the verge of discovery, so I'll press on
22:50:20<Nereid_>benchmarking perhaps
22:51:20<Alpounet>Hi all.
22:51:23<Nereid_>Hi.
22:51:56<Hunner>Botje: not if it's IO
22:52:16<Nereid_>but that's not evaluating, that's executing
22:52:41<BONUS>another on existential. say with data F = forall a. C a => a - if we have forall b. F -> (forall a. C a => a -> b) -> b
22:52:42<Hunner>okay, then I was using the wrong terms, sorry
22:52:55<BONUS>why can't we move the forall a. to the forall b.
22:53:00<Nereid_>Hunner: what are you having trouble with, then?
22:53:00<Hunner>I'm using the ghc api to recompile code when it needs it from external files, but it only compiles it once per run of main
22:53:07<BONUS>so it's forall a b. C a => F -> (a -> b) -> b
22:53:35<Hunner>Nereid_: similar to http://www.bluishcoder.co.nz/2008/11/dynamic-compilation-and-loading-of.html
22:54:53<Saizan>BONUS: because with that type the caller can instantiate 'a' to what it wants
22:55:00<Hunner>I don't have to recompile the file with main in it, just re-run it to get it to re-execute the function that does the compiling
22:55:20<uzytkownik>Whats the standard place for tests? Test.hs, tests/?
22:55:31<Saizan>BONUS: while you need to keep that freedom for the body of the function
22:55:47<BONUS>aahh
22:55:50<BONUS>i get it
22:57:00<Saizan>IOW the second argument must be polymorphic
22:57:44<mmorrow>here are doxygen docs for the linux kernel, built with all the various graphviz graphs doxygen can do: http://moonpatio.com/docs/linux/
22:57:58<jix_>and again this would be a monad if the definition of (>>=) would be restricted to one type instead of two
22:58:08<habitue_>Hey I am trying to write a function with the signature (a -> a) -> a -> Int -> a where it applies the function to itself x times, what is the easiest way to write this?
22:58:35<mmorrow>struct index: http://moonpatio.com/docs/linux/classes.html
22:58:52<mmorrow>file: http://moonpatio.com/docs/linux/files.html
22:58:53<mmorrow>etc
22:59:10<Saizan>jix_: it's just a monoid then :)
22:59:53<conal>habitue_: maybe iterate & !!
22:59:57<BONUS>i think i get existentials now, awesome
23:00:07<Saizan>BONUS: yay!
23:00:15<jix_>Saizan: really? to me a monoid looks like something completely different
23:00:25<BONUS>:]
23:01:05<Hunner>Nereid_: okay, is there a way to make haskell re-execute a function?
23:01:05<habitue_>I tried something along the lines of :
23:01:07<FunctorSal>habitue_: foldr (.) id $ replicate theFun n
23:01:10<habitue_>repeatedly f k n -> foldl (\x y -> y x) k $ take n (repeat f)
23:01:19<Saizan>jix_: you can write (a -> M a) -> (a -> M a) -> (a -> M a), that's the mappend, and "return" is mempty
23:01:37<Nereid_>habitue_: repeatedly f k n = iterate f k !! n
23:01:57<jix_>Saizan: ah... but i get no nice do notation then... ;)
23:01:58<Nereid_>Hunner: I would think you'd need to load the module again or something
23:02:05<habitue_>ok! thank you very much!
23:02:28<Nereid_>but if the module is already loaded maybe reloading it again just returns something cached, so you'd need to find a way to clear that
23:02:33<FunctorSal>habitue_: you can get exponential speedup (in n) by square-and-multiply, though...
23:02:35<Hunner>Nereid_: It doesn't actually load the module. It uses ghc's api to compile it and load it into the context
23:02:41<Nereid_>that's what I meant
23:03:07<habitue_>FunctorSal: square and multiply?
23:03:26<FunctorSal>habitue_: or wait, nevermind. that only makes sense for numbers, since for functions the function will still have to be applied n times anyway ;)
23:03:31<Nereid_>FunctorSal: not really, you need to apply the function n times in any case
23:03:32<Nereid_>yeah
23:03:33<Nereid_>:-)
23:03:41<FunctorSal>silly me
23:03:54<Nereid_>habitue_: more explicitly you could do, repeatedly f k 0 = k; repeatedly f k n = f (repeatedly f k (n - 1))
23:04:18<Nereid_>(probably want to error if n < 0)
23:04:59<FunctorSal>I was thinking of function composition as a constant-cost operation... (which it is, but applying the thunk will be linear in n)
23:05:18<Nereid_>indeed
23:05:57<mmorrow>@type \n -> foldr (.) id . replicate n
23:05:58<lambdabot>forall a. Int -> (a -> a) -> a -> a
23:06:44<mmorrow>(my favorite way to do that)
23:07:04<mmorrow>and it's `id' if n < 1
23:08:02<conal>mmorrow: hm. id for n < 1 would break some nice identities. like saying x ^ n = 1 for all n <= 0.
23:08:37<conal>to bad the Endo monoid isn't more convenient to use in settings like this one
23:09:59<FunctorSal>yeah replicate with negative arg should make a formal inverse ;)
23:10:14<conal>yep
23:10:34<conal>or at least something *consistent* with inverse.
23:10:38<conal>if not equal to it.
23:11:23<jnwhiteh>Does anyone know of an implementation of the commstime network in Haskell?
23:11:45<monochrom>inverse is hard.
23:11:58<conal>monochrom: yeah. but consistency with inverse is easy.
23:12:11<FunctorSal>inverses of lists with respect to (++) aren't really much more imaginary than negative numbers ;)
23:12:20<jix_>i so want do notation for this :/
23:12:20<conal>i.e., if we can't agree, we can still agree not to disagree.
23:12:24<FunctorSal>but I don't know what the elements should be
23:12:46<monochrom>consistency with inverse is hard. that's what I meant.
23:12:47<SamB>FunctorSal: sure they are, negative numbers are easy
23:14:22<pedro-kun>hi.. sorry for asking such a question..
23:14:26<conal>i guess "easy" & "hard" is binary (relation) not unary (property)
23:14:27<pedro-kun>i have a [String]
23:14:34<pedro-kun>and i want to putStrLn every item
23:14:37<Nereid_>numbers with addition have a group structure
23:14:39<pedro-kun>how can i do this?
23:14:40<Nereid_>lists and concatenation don't
23:14:57<conal>@ty mapM_
23:14:57<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m ()
23:15:03<Nereid_>pedro-kun: sequence
23:15:07<conal>pedro-kun: ^^
23:15:12<Nereid_>or that
23:15:15<conal>@ty sequence
23:15:16<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m [a]
23:15:17<Taejo>what's a good library for writing "permissive" parsers (I want to parse something that isn't meant to be machine readable, but follows a fairly regular format)
23:15:17<monochrom>consistency with inverse is as hard as the halting problem.
23:15:22<Saizan>?ty mapM_ putStrLn
23:15:24<lambdabot>[String] -> IO ()
23:15:31<conal>@ty sequence_
23:15:32<lambdabot>forall (m :: * -> *) a. (Monad m) => [m a] -> m ()
23:16:08<Saizan>Taejo: maybe uu-parsinglib? it does autocorrection
23:16:21<Taejo>Saizan: I'll look into it
23:16:22<FunctorSal>Nereid_: naturals with additions have only a monoid structure, so you invent negatives to make a group. you can do that with lists too (but it is more complicated because (++) isn't commutative)
23:17:01<Berengal>How would negative-length lists work?
23:18:21<conal>Berengal: maybe with anti-values that cancel out values when juxtaposed
23:18:24<Nereid_>actually
23:18:24<Nereid_>yeah
23:18:40<conal>"annihilation, jim"
23:18:40<FunctorSal>Berengal: ListGroup a = [Either a a], with ordinary lists included via \xs -> map right xs
23:18:42<monochrom>"free groups" and "words". also "the word problem"
23:18:50<wy_>hey, anybody familar with the implementation of haskell?
23:18:58<Nereid_>asdf I was about to mention free groups. :(
23:19:00<FunctorSal>concatenation is defined such that lefts and rights cancel out
23:19:23<Nereid_>ACTION gets bored, and writes such a thing
23:19:26<FunctorSal>then inverse [Right "foo", Left "bar"] = [ Right "bar", Left "foo" ]
23:19:38<wy_>I was wondering how the currying is implemented. Does ghc create closures for every level of currying?
23:19:53<FunctorSal>Nereid_: it needs an Eq context though :(
23:19:54<Nereid_>how would we deal with infinite lists?
23:20:02<Nereid_>yeah probably
23:20:17<conal>FunctorSal: can these lists have negative length?
23:20:18<Nereid_>actually nevermind, infinite lists would be easy anyway
23:20:19<Berengal>Nereid_: [..Left 1] ish...
23:20:34<conal>FunctorSal: so that length is still a monoid homomorphism
23:20:55<Nereid_>well
23:20:57<Berengal>wy_: Conceptually it does
23:20:58<FunctorSal>conal: hmm if you define length as "number of rights - number of lefts" I think that's the case
23:21:05<Nereid_>indeed
23:21:09<wy_>Berengal: but in practice ..?
23:21:45<conal>FunctorSal: hm. what about [Right True] ++ [Left False] ?
23:21:54<Berengal>wy_: Don't know, and it probably depends on the phase of the moon and if you're wearing your lucky socks or not
23:21:56<conal>oh yeah. nm.
23:22:08<conal>just drop the old notion of length
23:22:10<FunctorSal>Nereid_: hmm with infinite lists it seems that either "inverse x ++ x" or "x ++ inverse x" will be undefined :(
23:22:18<Berengal>wy_: You could get ghc-core and try some experiments... if you know how to read core
23:22:22<Nereid_>FunctorSal: indeed
23:22:57<conal>FunctorSal: like infinity - infinity
23:23:12<wy_>Berengal: I looked at SPJ's book, but STG etc are still too far from the machine to make this point clear
23:23:31<Berengal>wy_: ghc-core shows the assembly as well
23:24:01<wy_>Berengal: oh, what is ghc-core? I thought it was the core language
23:24:01<SamB>wy_: when you apply several arguments in one go, it doesn't actually go through and make all those closures, no
23:24:28<SamB>wy_: hackage package
23:24:41<Berengal>wy_: No, ghc-core gets ghc to compile to core, then colours the ouput. It's on hackage, so cabal install ghc-core and you're golden
23:24:59<SamB>I would probably not have figured it out if he didn't mention that it shows the assembly as well
23:25:06<jix_>:r
23:25:09<jix_>whoops
23:25:25<jix_>this isn't ghci...
23:25:35<wy_>Thanks.
23:25:35<wy_>That's pretty clear now
23:25:38<SamB>heh
23:26:04<wy_>SamB: Is it considered an optimization?
23:26:14<SamB>wy_: sort of
23:26:31<wy_>That's nice.
23:26:57<SamB>I mean, I don't think you need -O to get it
23:27:04<Gracenotes>hm, I forget.. what's the problem with lambdabot and lefts/rights/partitionEithers?
23:27:25<wy_>SamB: yeah. It should be the case by default
23:27:30<Saizan>@versuion
23:27:30<lambdabot>lambdabot 4.2.2
23:27:30<lambdabot>darcs get http://code.haskell.org/lambdabot
23:28:01<Gracenotes>I *thought* it was on 6.10 GHC..
23:29:52<Cale>wy_: My mental model of how Haskell evaluation works (even when optimising code) is normally too high-level to include something like closures directly. :)
23:30:22<wy_>Cale: what do you think in? combinatory logic?
23:30:24<Cale>wy_: I normally think of the Haskell evaluator as repeatedly transforming a graph.
23:30:27<ray>closures? aren't they those things that are so obvious that i'm not sure what they're actually supposed to be?
23:31:06<Saizan>wy_: the recent paper "types are calling conventions" talk about that, afaik
23:31:34<Cale>ray: A closure consists of a pair, consisting of some code, possibly with some unbound variables left in it, together with an environment mapping which maps any unbound variables in the code to values.
23:31:54<Cale>ray: So that when the code gets run, it can look up the missing variables in the map.
23:32:22<Berengal>Argh! I have an idea, but I don't know how to express it in haskell :(
23:32:29<ray>in other words, it's "handle free variables in a way that makes sense"
23:33:00<wy_>Cale: how do you think in graphs also dealing with free vars?
23:33:07<Cale>ray: There are many ways to fill in the concrete details of how this works, but the important part is that what you have is a pair. If you can't take it apart anymore into separate code and environment parts, I wouldn't call it a closure anymore.
23:33:49<Cale>wy_: Well, the values of variables are captured by the fact that the body of a function will have an arc which points to them.
23:34:36<jix_>are there any tools that allow to trace haskell evaluation and generate graph reduction animations out of that?
23:35:00<wy_>Cale: maybe it's too low-level, but when these things are translated to assembly, you will have to package things up
23:35:20<ray>cale: i should write a compiler i guess
23:35:29<Cale>jix_: The closest thing I've seen is for a language which is not really Haskell, and where you write the code as graphs as well. Also, it's still not open source, though it's not for any good reason :)
23:35:41<Cale>http://www.cas.mcmaster.ca/~kahl/HOPS/ANIM/index.html
23:36:17<Taejo>:t flip id
23:36:18<lambdabot>forall b c. b -> (b -> c) -> c
23:36:48<Cale>ray: There's an annoying (from my perspective) tendency for people to call first class functions or procedures "closures", when what is really true is only that they *might* be implemented as such.
23:37:17<Cale>ray: A closure is an *implementation mechanism* for a first class function, procedure, or object.
23:37:46<ray>so writing a compiler is probably the way to go
23:37:57<Berengal>I think of a closure as a function and a list of (some of the) arguments. At the haskell-level, this is indistinguishable from any other function or value
23:38:25<Cale>Berengal: Well, yeah, if you're thinking of a pair, then that's fine.
23:38:33<Cale>Something like (a -> b -> c, a)
23:38:38<Berengal>You only really need them in languages that lack first-class functions and currying. They're easy enough to implement yourself
23:38:44<conal>Cale: thanks! i appreciate the distinction between implementation notions and semantic notions.
23:39:04<wy_>Cale: That's true if you think of lambda calculus. It doesn't have closures. The environment is just a "delayed substitution"
23:39:13<Cale>wy_: right.
23:39:44<Cale>wy_: Closures should not appear in language specifications. If they do, your spec is specifying too much about how the language is to be implemented.
23:40:10<wy_>Cale: It seems to be damn truth that first-class functions when implemented in assembly, still have to take another argument which is the closure
23:40:14<conal>Similarly, notions like graph reduction.
23:40:59<wy_>I wonder whether ghc has avoided that
23:41:00<conal>one can also implement first class functions via code generation.
23:41:24<SamB>wy_: that's the info pointer
23:41:35<SamB>er, I mean ...
23:41:41<Cale>wy_: But they might also be implemented as a code graph where arcs from the body of the function point at other values in memory, and so there's no closure to speak of.
23:42:28<wy_>Cale: yes. I mean, you may need to create a new processor to implement it nicely
23:42:47<Cale>wy_: and when you partially apply a function, it takes the lambda variable, and rewires everything that points at that to point at the value instead.
23:42:55<SamB>a GHC function object is not just a code address
23:43:05<Cale>Nah, you can do graph transformations on stock hardware.
23:43:19<Cale>You use pointers for arcs.
23:43:40<SamB>the first word is a pointer to some code with a table immediately before it ...
23:43:46<SamB>there rest, well, it depends
23:44:09<wy_>It will introduce multiple level of indirections I guess
23:44:51<wy_>It will introduce multiple level of indirections I guess.
23:44:54<SamB>wy_: of course, to implement the FFI, it really *does* need to generate machine code closures dynamically...
23:44:56<Cale>wy_: So despite working externally exactly like the closure implementation, there's never a separation between code and an environment of bindings.
23:45:05<wy_>sorry I thought I'm kicked off before send
23:46:10<wy_>It's a little strange that code is still not as flexible as data in the processors
23:46:14<Cale>wy_: So I think it's a potentially dangerous abuse of terminology to speak about languages "supporting closures", and such.
23:46:17<wy_>or is it?
23:46:23<Taejo>"We do not use the class Applicative from the module Control.Applicative" -- RAGE
23:46:37<Taejo>the standard libraries should be *standard*
23:47:10<SamB>Taejo: who said that?
23:47:20<wy_>Cale: well, that's a reasonable term if you think of languages that do not "support" it nicely, like javascript, python, ...
23:47:24<Taejo>SamB: uuparsinglib tutorial
23:47:29<Cale>wy_: Well... even at the processor level, code is data... but the implementation I'm talking about would represent the Haskell code as a non-machine-code graph, and have a piece of machine code which runs in some kind of recursive way to rewrite the graph over and over.
23:47:49<SamB>Taejo: that sounds a bit strange
23:47:57<SamB>what's the context?
23:48:00<Taejo>SamB: it's for efficiency reasons
23:48:13<SamB>for *what* now?
23:48:30<Cale>wy_: We should speak about languages supporting first class procedures and functions properly, not closures :)
23:48:32<SamB>and you said this was a tutorial
23:48:39<wy_>Cale: The abstraction of graph sounds not as neat to me. It feels "undirected"
23:48:40<uzytkownik>@pf \f g x -> do t <- f x; g x; return t
23:48:50<conal>Taejo: uuparsinglib preceded Applicative. i wonder if that's why.
23:48:52<lambdabot>Maybe you meant: bf pl
23:48:59<Cale>wy_: It is a digraph...
23:49:12<Cale>wy_: Instead of expression trees, you have expression graphs
23:49:23<uzytkownik>@pl \f g x -> do t <- f x; g x; return t
23:49:24<lambdabot>(line 1, column 22):
23:49:24<lambdabot>unexpected ";"
23:49:24<lambdabot>expecting variable, "(", "`", "!!", ".", operator or end of input
23:49:26<Taejo>conal: if that's the case, they should be honest... they claim it's for optimization
23:49:32<wy_>Cale: I mean... the graph doesn't contain semantic information itself
23:49:42<Cale>wy_: Eh?
23:49:52<conal>Taejo: oh! if you learn how not using Applicative helps them optimize, i'd love to hear about it.
23:49:52<Cale>wy_: It sort of does...
23:49:58<wy_>I mean, it's less syntax directed
23:50:00<Cale>wy_: Well, it has syntactic information.
23:50:04<Cale>It *is* syntax.
23:50:29<wy_>but it feels very far from logics
23:50:41<Cale>http://www.cas.mcmaster.ca/~kahl/HOPS/Screenshots/BoolList.filter.png
23:50:49<conal>Taejo: Applicative, like Arrow, allows static analysis that Monad thwarts. the UU parsing stuff was one of the first to notice, and partially motivated arrows.
23:50:54<Taejo>conal: I really don't see it, since their Applicative has <*>, <|>, <$>, pure and fail, all of which are class methods, so can be overridden in the standard libs (tho not all are Applicative)
23:50:58<Cale>That has some pictures which show what the filter function might look like
23:50:59<uzytkownik>@pl \x -> (x, x)
23:51:00<lambdabot>join (,)
23:51:01<dibblego>bos, ping
23:51:09<SamB>too bad malcolmw is missing :-(
23:51:13<Cale>The orange arrow shows the graph transformation to apply filter
23:51:20<uzytkownik>@hoogle join
23:51:21<lambdabot>Control.Monad join :: Monad m => m (m a) -> m a
23:51:21<lambdabot>System.FilePath.Posix joinDrive :: FilePath -> FilePath -> FilePath
23:51:21<lambdabot>System.FilePath.Windows joinDrive :: FilePath -> FilePath -> FilePath
23:51:35<Taejo>conal: yeah, but I'm not sure what their Applicative has that the standard one doesn't (except merging Applicative, ApplicativeChoice and Functor)
23:51:37<Cale>The @ nodes are function applications
23:52:14<Cale>The rule which is named filter_[] basically represents the Haskell code filter p [] = []
23:52:17<Taejo>s/ApplicativeChoice/Alternative/
23:52:21<conal>Taejo: i was telling you thing you already know, wasn't i?
23:52:21<wy_>Cale: It contains "side effects" in the graphs
23:52:42<conal>(things)
23:52:43<wy_>That would make it hard to reason about them
23:52:54<Cale>and filter_: represents the code filter p (x:xs) = if p x then x : filter p xs else filter p xs
23:53:00<Taejo>conal: sort of (I know the idea but not its history)
23:53:06<Cale>wy_: Well...
23:53:38<Saizan>Taejo: the last version of uu-parsinglib uses the standard Applicative, btw
23:54:10<Taejo>Saizan: oh, thanks. I guess one should never assume the documentation one is looking at is up-to-date
23:54:12<wy_>hehe. So we must use side effects to think about a pure language
23:54:12<Cale>wy_: It's still the same pure language at some level, it's just that this HOPS language makes the graph rewriting more explicit. You could place restrictions on the sorts of rewriting rules which are to be admitted in order to make it as pure as Haskell is
23:54:19<Taejo>now I can calm down
23:54:29<Cale>In some sense, it is lower-level than Haskell though.
23:54:49<Cale>But something like it is how I think of Haskell code when reasoning about its performance
23:55:19<Cale>This graph rewriting is actually a fairly close, if imperfect, representation of what GHC-compiled programs do in memory with pointers.
23:55:30<wy_>You mean you will think about performance when you write programs?
23:56:00<Cale>Well, usually not much more than asymptotics when I first write things.
23:56:16<Taejo>hmm... I like the idea that to parse online, one must do it breadth-first instead of depth-first
23:56:28<Cale>But if I have problems, I'll profile and then think about how the functions which are spending the largest amount of time are going to get reduced.
23:56:37<Taejo>I guess in a sense you're just making the parser predictive
23:57:18<monochrom>I think about performance when I write programs.
23:58:01<wy_>I mean, everybody should think about performance, but it seems to be a little too much if laziness makes it harder to think about that
23:58:28<SamB>ACTION realizes that a guy from york wouldn't maintain a package from UU
23:58:33<Cale>It's not really that much harder to think about
23:58:53<wy_>so that's good :)
23:59:00<Cale>It does change the way you need to reason about performance quite a lot, and it does mean that performance becomes more "global" of a property
23:59:04<monochrom>"does laziness make it harder" and "what should we do about it" are two big questions always on my mind.
23:59:24<jmcarthur_work>i also think about performance when i program. i have not found that laziness makes things difficult
23:59:40<Cale>So in some sense, that's a little harder. But usually you can think about some specific access pattern to the result of a function, and then reason about its performance from there.

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