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