Experimental IRC log haskell-2009-05-17

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:00<Saizan_>uh? @djinn lives in a total world, afaik
00:00:04<ehird>from another comment: "Do you seriously want me to believe that the order in which the statement are executed is non-deterministic? That they will effectively be executed in a random order?"
00:00:05<MyCatVerbs>Poor dons.
00:00:10<TomMD>MyCatVerbs: Exactly - if you removed every package with an unsafePerformIO then probably 80% of hackage would be gone.
00:00:12<ehird>MyCatVerbs: heck, I'm raging!
00:00:18<ehird>TomMD: 80%? no, that's excessive
00:00:24<ehird>i'd say like 10%
00:00:48<TomMD>ehird: Well, I'd include anything that depends on a package with unsafePerformIO - so anything with bytestring for example.
00:00:56<mmorrow>well, they'd all be broken due to their deps being gone :)
00:01:02<ehird>TomMD: bytestring does not HAVE to use unsafePerformIO
00:01:03<TomMD>ehird: So yes, 80% is probably high, but still it would be significant.
00:01:07<ehird>It is merely an implementation detail, I would say
00:01:09<TomMD>ehird: But it does.
00:01:14<mmorrow>ehird: every ByteString would be in IO then
00:01:18<ehird>TomMD: yes, but it is NOT part of the package's interface
00:01:24<ehird>therefore it doesn't infect dependencies
00:01:29<TomMD>ehird: A detail that gives it the performance it has, which is the reason the package is used.
00:01:32<ehird>mmorrow: no— an implementation could provide the infrastructure for it
00:01:35<ehird>without requiring unsafeness
00:01:35<mmorrow>newtype ByteString = ByteString [Word8]
00:01:43<mmorrow>there's nothing unsafe about it though
00:01:47<Cale>ACTION replied.
00:01:48<MyCatVerbs>Saizan_: yes. djinn lives in a total world, but the real world is not total. You cannot necessarily assume that djinn's (total-function world) output will work in the real (partial-functions everywhere) world.
00:01:54<ehird>I'm just saying
00:02:00<ehird>bytestring does not have to use IO internally
00:02:04<ehird>and unsafePerformIO
00:02:06<ehird>to give its benefits
00:02:11<ehird>it's just that way in current implementations
00:02:25<Lemmih>TomMD: The 'base' package uses unsafePerformIO. So I guess 100% would have to be removed.
00:02:32<hatds>can you make a fast bytestring without unsafePerformIO that lives in the IO monad?
00:02:35<roconnor>ACTION wants the partial function monad.
00:02:36<ehird>Lemmih: does it have to?
00:02:38<MyCatVerbs>Cale: good reply.
00:02:43<vixey>roconnor: I have one
00:02:46<TomMD>Lemmih: Where? I'm not overly surprised, but was unaware.
00:02:51<vixey>on moonpaste
00:02:52<ehird>Cale: ah, uh, don't bother... grauenwolf is just a troll
00:02:53<roconnor>vixey has one
00:03:30<obk>I am trying to configure a package to compile under both 6.8 and 6.10. In 6.10, it requires PostfixOperators. If I put this in the Cabal file, even if protected by impl(ghc >= 6.10.0), I get an error when configuring the package. Is there a workaround?
00:03:46<Cale>ehird: I'm aware, but I don't mind replying to trolls if they try to misinform people.
00:03:50<vixey>I can't find it :/
00:04:02<Lemmih>ehird: It uses unsafePerformIO to create global buffers for the various handles.
00:04:05<vixey>http://www.unsafecoerce.com/fastcgi/hpaste.fcgi/view?id=562
00:04:10<Saizan>obk: you need a later version of Cabal i think
00:04:16<vixey>roconnor it's mostly ripped out of some slides I found
00:04:27<ehird>Lemmih: Implementation detail, not part of interface.
00:04:45<Lemmih>ehird: Same with bytestrings, no?
00:04:55<ehird>exactly
00:05:09<ehird>If the implementation provided infrastructure to do things like that safely, we would not need unsafePerformIO
00:05:21<ehird>and since this unsafeness is not exposed via the interface, it does not infect across dependency barriers
00:05:39<TomMD>ehird: Certainly, but unsafePerformIO is so general it would be hard to find a good set of safe constructs to replace it (in my opinion)
00:05:46<obk>Saizan: Thanks, will try
00:05:51<ehird>TomMD: Yep— I'm being totally theoretical here.
00:06:02<ehird>I'm just arguing against "Everything is innately tied to unsafePerformIO, woe!"
00:06:59<hatds>how would a compiler implement a safe version of unsafePerformIO?
00:07:09<vixey>hatds there's no such thinga
00:07:49<hatds>or rather, safe infrastructure to do things we want that we currently use unsafePerformIO
00:07:58<hatds>(ehird's comment)
00:08:04<roconnor>hatds: dependent types!
00:08:10<ehird>hatds: by providing the stuff used primitively, pretty much
00:08:18<ehird>as in, a primitive version of bytestrings' operations is the most trivail way
00:08:24<sshc>wow. learnyouahaskell.com's a great site
00:08:24<roconnor>ACTION proposes that dependent types solve all problems.
00:08:26<Saizan>hatds: something like the ST monad for example
00:08:28<ehird>more work could be done into general ways of doing things that seem unsafe
00:08:29<ehird>roconnor++
00:08:31<roconnor>... except for stack overflows
00:08:32<ehird>Saizan: that too
00:08:34<vixey>roconnor didn't actually want a partiality monad..
00:08:58<ehird>vixey: why not?
00:09:01<ehird>partiality monads would rock
00:09:16<roconnor>vixey: I want one, but I already knew how to make one.
00:11:48<hatds>now I'm curious... would we think calling into C via IO to be "safe"? I mean, it's C!
00:12:23<hatds>*think of
00:12:43<roconnor>calling into C is not safe in general
00:13:24<MyCatVerbs>hatds: nothing in IO is guaranteed to be safe anyway. You have multithreading and Foreign.Storable, for starters.
00:13:46<roconnor>what's unsafe about multithreading?
00:14:31<vixey>roconnor: partiality monad is good for theory but in practice isn't it horribly inefficient (making these huge chains of data)?
00:14:44<vixey>(you can't erase them and retain the computational meaning)
00:15:12<vixey>runComputation (Now x) = x ; runComputation (Later c) = runComputation c -- works, but you can only do that at the end
00:15:13<hatds>vixey: can you give an example?
00:15:26<roconnor>vixey: presumably all you need is lazy evaluation.
00:15:29<vixey>hatds: my paste shows an example of a program that is more lazy than it would be if you wrote it in direct haskell
00:15:48<vixey>roconnor, I seem to write 'lazier than lazy' code using lfp of computation
00:15:56<roconnor>lfp?
00:16:05<vixey>least fixed point (by omega race)
00:16:43<MyCatVerbs>roconnor: the ordering of operations isn't well defined unless you use a correct locking scheme, and you get no automatic proof as to whether or not your locking scheme *is* correct.
00:18:09<SamB>MyCatVerbs: I think the linux kernel actually offers that ...
00:18:23<SamB>there's a Kconfig option for it, I think
00:18:40<MyCatVerbs>SamB: what? Deadlock resolution?
00:18:50<SamB>(obviously only helps if it's the Linux kernel you want to prove the locking scheme of correct ...)
00:18:53<roconnor>MyCatVerbs: so we are considering race conditions to be unsafe?
00:19:00<SamB>MyCatVerbs: proving your locking scheme correct!
00:19:24<SamB>where you == kernel hacker
00:19:31<roconnor>vixey: I don't get your lazier than lazy comment.
00:19:34<MyCatVerbs>SamB: huh? You can't prove arbitrary programs' locking schemes correct without solving the Halting Problem first?
00:19:50<SamB>MyCatVerbs: well, I expect it only works sometimes!
00:19:53<vixey>roconnor, I'm referring to the program in my paste
00:19:57<MyCatVerbs>roconnor: sure, and there are other even less safe things. For example, non-atomic reads and writes.
00:20:03<roconnor>vixey: I'm looking at it now.
00:20:06<vixey>if you write that not in the computation monad it will not be as lazy
00:20:11<vixey>you get _|_ more often
00:20:27<vixey>so to make Computation monad useful in practice.. I don't know what you do
00:20:36<SamB>but if it fails to prove your code correct, or fails to terminate in attemting to do so ... well, your code is probably too tricky to be allowed in the kernel, right?
00:20:43<vixey>currently it doesn't seem good enough
00:20:50<SamB>haven't tried that feature myself, though
00:21:07<roconnor>MyCatVerbs: can you use race conditions to read and write a complex data structure and totally screw it up by getting an impossible value?
00:21:11<marcusb>where can I find more info on the { foo :: TypeFoo, bar :: TypeBar } ... { foo = somefoo, bar = somebar } notation? I don't even know how it is called. I want to find out how I can write a modify function for a state monad with such a type
00:21:15<SamB>I only changed two lines, one of which was a comment ;-)
00:21:27<SamB>and the other one, I just replaced one way of writing "0" with another
00:21:36<MyCatVerbs>roconnor: yes, if you don't have atomic reads and writes on that data structure.
00:21:58<hatds>marcus: record notation
00:22:15<roconnor>MyCatVerbs: hmm, but isn't updating a simple pointer update, which usually is attomic?
00:22:17<marcusb>thanks
00:22:40<MyCatVerbs>roconnor: not on all architectures. On x86, yes, but x86 is weird in this respect.
00:23:14<roconnor>vixey: which function are you talking about?
00:23:20<MyCatVerbs>roconnor: plus you might concievably get inconsistent views. Imagine some data structure with multiple pointers in it, where it's significant whether two different pointers inside it alias the same location or not.
00:23:30<vixey>isAscending
00:23:40<stroan>Finally finished mandelbrot. That took more learning than in any other language I've ever started with.
00:24:27<roconnor>MyCatVerbs: what you ask me to imagine doesn't sound like haskell.
00:25:13<mae_>hFlush: resource vanished (Broken pipe), what the heck does this mean!
00:25:26<MyCatVerbs>roconnor: fine. data Foo = Foo { first :: (IORef Int), second :: (IORef Int) }.
00:25:35<TomMD>mae_: Your handle is probably closed, so flushing isn't possible.
00:25:43<roconnor>vixey: I see what you mean.
00:25:53<MyCatVerbs>roconnor: pretend there's some significance as to whether (first foo) and (second foo) have identical values or not.
00:26:00<PetRat>http://www.mibbit.com/pb/7Xd03D Looking at my example again, in the line marked (*), where does the definition of the "return" on the right come from?
00:26:32<MyCatVerbs>roconnor: it's a million miles away from idiomatic, but you can make more complicated examples that are perhaps less obviously broken.
00:27:01<roconnor>MyCatVerbs: I'm looking for an example where type soundness is broken, not data structure invarients.
00:27:11<PetRat>stroan: pardon my ignorance---what are you referring to? a book?
00:27:32<MyCatVerbs>roconnor: oh, right. Nah, you only break type soundness with non-atomic reads and writes.
00:27:56<stroan>PetRat: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2439 Implementing mandlebrot is one of the first programs I write in any language
00:28:22<mae_>stroan: rock on.
00:28:51<roconnor>MyCatVerbs: and on x86, thunk updates are always atomic? ... What about on whatever motorola chip that Macs use, or are they all x86 now?
00:29:00<MyCatVerbs>roconnor: if one thread is writing while another is reading on an arch where pointer reads and writes aren't always atomic, you can end up with the reader taking, say, the low bits of IORef's pointer's old value and the high bits of the new value.
00:29:04<stroan>mae_: :)
00:29:04<PetRat>stroan: I started learning Haskell a short time ago, and it is so different from any previous language I've learned. Feel like I was learning basic things for the first time.
00:29:25<MyCatVerbs>roconnor: PowerPC. Macs are all x86 now. I'm not sure, it varies from architecture to architecture.
00:29:43<stroan>PetRat: yeah. I know. Also used to there being the usual slew of C libraries available through trivial interfaces
00:29:54<PetRat>bump -- simple question here -- http://www.mibbit.com/pb/7Xd03D Looking at my example again, in the line marked (*), where does the definition of the "return" on the right come from?
00:30:11<MyCatVerbs>roconnor: the only two I know offhand are Alpha, where just about everything is non-atomic unless you put explicit barriers in, and x86, where just about everything is atomic provided it's no longer than the size of a general-purpose arithmetic register.
00:30:36<opqdonut>PetRat: the return of the list monad
00:30:46<opqdonut>:t return 1 :: [Integer]
00:30:47<lambdabot>[Integer]
00:30:52<opqdonut>> return 1 :: [Integer]
00:30:54<lambdabot> [1]
00:31:40<opqdonut>er, no
00:31:44<Asztal>kind of looks like it should be the State monad return
00:31:47<opqdonut>the return of the state monad actuallhy
00:31:49<opqdonut>-h
00:32:06<PetRat>opqdonut: yeah that make smore sense.
00:32:43<PetRat>PetRat's test
00:35:02<PetRat>Can someone tell me what the definition of the State monad's return is?
00:35:18<MyCatVerbs>@src State
00:35:18<lambdabot>Source not found. I feel much better now.
00:35:42<MyCatVerbs>PetRat: http://www.haskell.org/all_about_monads/html/statemonad.html
00:35:58<hatds>what's the simplest way to write f :: BinTree Int -> BinTree Int which changes each node to the sum of all its descendants, but where f is not recursive?
00:36:12<hatds>(BinaryTree)
00:36:14<MyCatVerbs>hatds: what's BinTree look like?
00:36:20<PetRat>Thanks.
00:36:31<adu>hi
00:36:35<adu>how do I "fixWith"?
00:36:44<augustss>hatds: Do you have a fold function for BinTree?
00:36:52<hatds>say Tree a = Node a | Branch a (Tree a) (Tree a)
00:37:11<hatds>yea, folds, traverse, etc.
00:37:15<adu>like a function like :: (a -> a) -> a -> a
00:37:20<adu>but like fix
00:38:49<augustss>hatds: well, then you should be able to do it :)
00:38:53<bwr>for some reason i thought you could derive Random when defining a datatype. is this not correct?
00:39:12<hatds>augustss: I'm not seeing it :(
00:39:41<augustss>bwr: it's not
00:40:12<bwr>i'm doing something like data Color = Red | Blue ...
00:40:13<augustss>hatds: one pass with a fold to add up all the numbers, one pass with a map to replace
00:40:19<MyCatVerbs>> let { fixWith f v = let x = f v in fixWith f x } in fixWith (\l -> head l : l) "a"
00:40:29<lambdabot> mueval: Prelude.read: no parse
00:40:30<bwr>is there someway i can generate a random value of type COlor
00:40:32<bwr>Color
00:40:33<MyCatVerbs>Blast.
00:41:00<augustss>bwr: use toEnum on an appropriate Int
00:41:10<adu>MyCatVerbs: thanks :)
00:41:19<MyCatVerbs>bwr: derive Enum and Bounded for Color. Generate Ints between (fromEnum minBound) and (fromEnum maxBound).
00:41:30<MyCatVerbs>adu: I'm not sure whether it's correct or not! x_x
00:41:51<MyCatVerbs>adu: no, it isn't. Hrmn.
00:41:53<augustss>QuickCheck has a number of utilities to generate random values.
00:42:00<bwr>thanks
00:42:01<adu>oh :(
00:42:07<opqdonut>:t foldr (.) id . repeat
00:42:10<lambdabot>forall a. (a -> a) -> a -> a
00:42:15<opqdonut>that should be correct
00:43:14<adu>opqdonut: no thats infinite
00:43:35<opqdonut>well stuff with fix tends to be
00:43:46<adu>I want something that keeps going only while the output reaches a fixedpoint
00:43:47<hatds>augustss: in the first pass though at each node you fold over all the descendents
00:44:03<adu>s/while/until/
00:44:03<hatds>augustss: right? I want to get away with just adding the two immediate children together
00:44:27<augustss>hatds: that's what fold will help you do
00:44:54<codolio>:t foldr ($) id . repeat
00:44:55<lambdabot>forall a. ((a -> a) -> a -> a) -> a -> a
00:45:20<Saizan>ACTION doesn't see how to divide this in two passes
00:45:38<adu>so if iterate f xs = [5, 7, 4, 8, 6, 2, 3, 1, 1, 1, 1, ...] then fixWith f xs = 1
00:45:40<dolio>:t foldr ($) undefined . repeat
00:45:42<lambdabot>forall b. (b -> b) -> b
00:46:06<PetRat>http://www.mibbit.com/pb/WxgZBa I have another question. I don't even know how to ask it. I'm stuck in trying to understand this example because I see [s] in one place and s in another and I don't know how to bring these together.
00:47:08<adu>PetRat: well, you can either remove some brackets of insert some brackets :P
00:47:41<Saizan>PetRat: those two 's' are not the same one
00:48:10<MyCatVerbs>adu: in order to keep going until you reach a fixpoint, you need more an (Eq a) constraint.
00:48:17<PetRat>Can you show me how to rewrite it to make it clearer?
00:48:33<Saizan>PetRat: instance Monad (State s) where .. <- here 's' is a variable so you can instantiate to any type you want
00:48:35<MyCatVerbs>adu: so that you'll be able to tell when you've hit the fixed point.
00:48:37<marcusb>this may be over my head, but anyway: I want to implement a very simple virtual machine, and have a state monad for the machine state, and an array of opcodes, the result of execution of the opcodes is a list of strings. I want to pattern match on one or more instructions (thus I don't want to use a fold or something similar simple). Would it be sensible to do
00:48:38<marcusb>execute :: [Opcode] -> State Machine ([String]) instr1:instr2:rest = do { do_instr1; do_instr2; strtail <- execute rest ; return "something":strtail }
00:48:38<marcusb>I think I am asking if this is or can be made tail-recursive(?).
00:48:48<adu>yes, I should have been clear :: Eq a => (a -> a) -> a -> a
00:49:05<EvilTerran>MyCatVerbs, what would be insufficient about Eq?
00:49:08<MyCatVerbs>adu: fixWith f v = let v' = f v in if (v == v') then v else fixWith v' -- easy peasy.
00:49:19<adu>oh ok
00:49:38<MyCatVerbs>EvilTerran: nothing. The word "more" shouldn't have been in that sentence, it was a typo. Brain-o. Whatever.
00:49:45<EvilTerran>ah
00:49:46<Saizan>PetRat: it's like when you define a function foo x = ..., when i call it with an argument say foo [x] it doesn't matter that 'x' was also the name of the formal parameter
00:50:03<PetRat>Okay let me fiddle a bit..
00:50:04<adu>MyCatVerbs: you forgot an 'f'
00:50:15<MyCatVerbs>adu: yes, yes I did.
00:50:21<MyCatVerbs>You didn't, though. :3
00:51:04<marcusb>maybe I should store the strings inside the state and only dump them at the end
00:51:18<mmorrow>@type \f -> fix (\k -> either k id . f)
00:51:20<lambdabot>forall b a. (a -> Either a b) -> a -> b
00:51:37<augustss>marcusb: yes, probably
00:52:02<mmorrow>> (\f -> fix (\k -> either k id . f)) (\a -> if 10 < a then Right a else Left (a+1)) 0
00:52:03<lambdabot> 11
00:52:44<Saizan>marcusb: why be tail recursive when you can be lazy? i'd use the WriterT monad transformer
00:53:13<marcusb>Saizan: basically everything I do in haskell can be explained by ignorance :)
00:53:29<adu>MyCatVerbs: it works!! thanks
00:53:54<MyCatVerbs>adu: No problem. Have fun. Don't use it irresponsibly. ;)
00:54:06<adu>lol
00:54:07<marcusb>Saizan: so the idea is to wrap the machine state in another monad that stores the output strings and write to that?
00:54:51<marcusb>I guess that's similar to storing the strings myself, except I don't need to implement it myself if I can understand monad transformations
00:55:09<Saizan>marcusb: Writer gives you a kind of logging facility, so you can e.g. tell ["something"] and it'll get appendend to what you tell'ed before
00:55:32<marcusb>yeah, I'm roughly aware of it. I guess I need to read section III in All About Monads
00:55:34<Saizan>the log can be any Monoid, but it's common to use a list
00:55:46<mmorrow>marcusb: i like the idea of this "Status" datatype in http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=772
00:56:41<vixey>mmorrow: looks a lot like the ordinal data type
00:57:12<Saizan>marcusb: if you just store the strings in the state you'd be less lazy, in that you can't look at the first strings before evaluating the last "put" in the computation
00:57:25<mmorrow>vixey: i'm not sure what that is, but it's similar to MonadPrompt (although i've never used that, but from what i understand that's the basic idea)
00:57:41<marcusb>Saizan: ah
00:57:42<mmorrow>, [$bf|.+[.+]|]
00:57:44<lunabot> luna: No instance for (GHC.Show.Show
00:57:46<mmorrow>, [$bf|.+[.+]|] ""
00:57:48<lunabot> "\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\b\t\n\v\f\r\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK...
00:57:55<mmorrow>output
00:59:44<mmorrow>so the idea of `Status' is that you just write a function :: Status -> o, then you can mutual with the eval function of type :: [Code] -> Status
01:00:23<sauf_>hi all, how can I write a polymorphic version of iterate
01:00:41<sauf_>which would work with powerSet :: [a] -> [[a]]
01:00:42<mmorrow>and if you want to output, eval (Out msg : rest) = W "something" (eval rest)
01:00:43<sauf_>and for which "take 2 $ polyIterate powerSet [1]" would give me
01:01:11<sauf_>[ [[],[1]], [ [], [[1]], [[]], [[],[1]] ] ]
01:01:11<sauf_>?
01:01:13<mmorrow>interp withStat code = withStat (eval code)
01:01:36<Saizan>sauf_: can you imagine a type for polyIterate?
01:01:45<mmorrow>eval (ReadChar : rest) = R (\c -> .. do something with c ... eval rest)
01:01:52<sauf_>no
01:02:25<sauf_>:(
01:03:15<Saizan>you can make a type for arbitrarily nested lists though
01:03:36<mmorrow>@type Node
01:03:38<lambdabot>forall a. a -> Forest a -> Tree a
01:04:15<Saizan>Node is not quite what we want here
01:04:22<sauf_>Saizan: yes but would it be executable ?
01:04:27<Saizan>the elements should be all at the "leafs"
01:04:28<mmorrow>but since we can't define datas in the interp..
01:05:03<Saizan>sauf_: yes, but you'd have to deal with its constructors
01:05:04<mmorrow>arg, it's painful with Tree
01:05:21<mmorrow>data T a = Tip [a] | T [T a]
01:05:55<sauf_>mmorrow: is it for me ?
01:06:42<Saizan>data T a = Nest (T [a]) | Tip a
01:06:48<mmorrow>ghci> [T[Tip[],Tip[1]],T[Tip[],T[Tip[1]],T[Tip[]],T[Tip[],Tip[1]]]]
01:06:48<mmorrow>[T [Tip [],Tip [1]],T [Tip [],T [Tip [1]],T [Tip []],T [Tip [],Tip [1]]]]
01:07:02<sauf_>mmorrow: Saizan thanks !
01:07:03<Saizan>so you enforce that you've the same level of nesting everywhere, i think
01:07:37<mmorrow>ghci> flat (T[T[Tip[],Tip[1]],T[Tip[],T[Tip[1]],T[Tip[]],T[Tip[],Tip[1]]]])
01:07:37<mmorrow>[1,1,1]
01:07:51<mmorrow>let flat (Tip xs) = xs; flat (T ts) = concatMap flat ts
01:15:19<mmorrow>flat (Tip a) = [a]; flat (Nest t) = (concat . flat . flat) t {- for Saizan's polymorphic recursive T -}
01:23:19<davidmccabe>This seems like sort of a hack; anyone have a better implementation handy?
01:23:21<davidmccabe>uniqueSorted l = Set.toAscList $ Set.fromList l
01:23:46<MyCatVerbs>davidmccabe: nah, that's a perfectly cromulent way of expressing it.
01:23:57<PetRat>@ runstate
01:24:03<PetRat>@runstate
01:24:04<lambdabot>Unknown command, try @list
01:24:27<MyCatVerbs>davidmccabe: the only other efficient thing you could do would be to use Data.List.sort and then scan the list dropping identical items.
01:24:35<PetRat>How do you ask lambdabot for a definition of runState?
01:25:39<MyCatVerbs>> let { identical (a:b:cs) = if a == b then identical (b:cs) else a : identical (b:cs); identical a = a; } in identical . sort $ [1,4,3,2,4,3,5,8,1,7]
01:25:40<lambdabot> [1,2,3,4,5,7,8]
01:26:39<Saizan>PetRat: there's @src in general, but runState is actually just a field accessor
01:27:06<PetRat>Oh, I see it now. A field accessor of State.
01:27:13<Saizan>yup
01:27:21<Saizan>it just unwraps the State constructor
01:27:44<Saizan>"data-constructor"
01:28:26<PetRat>Saizan: regarding this example, I'm trying to "play compiler" and work it through with concretes. Funny, because in RWH the example that makes all the types concrete doesn't come until the end of the chapter. So I'm working backwards from that, hoping to figure out how the compiler uses these type constructors.
01:28:50<PetRat>I have to go to dinner now, but should have a handle on this by later tonight.
01:29:52<mmorrow>struct con {int tag; char payload[];};
01:30:44<PetRat>For some reason I'm obsessed about getting through chapter 18 (Monad transformers) a.s.a.p., as though I were cramming for an exam. (I'm not in school---I'm a professional programmer but don't need Haskell for my work. It is for home projects.)
01:31:05<PetRat>I need to relax and do something non-Haskell for a while.
01:31:11<mmorrow>(oh, i think i misunderstood what you're after with that struct)
01:31:32<roconnor>ACTION needs to relax and write some Haskell for a while.
01:31:50<Saizan>ACTION needs to relax and get some sleep for a while
01:33:09<PetRat>What's the syntax for writing about yourself in the third person? Sorry about my newness to IRC
01:33:14<alexsuraci> /me
01:33:28<PetRat>ACTION is talking in the third person.
01:37:54<NickMib>SUCK IT FUCKERS
01:38:30<Hunner>> [floor(x/2) | x <- [0 .. maxBound]]
01:38:31<lambdabot> Add a type signature
01:39:02<Hunner>Where does it need a type signature for that?
01:39:20<roconnor>what is the type of x?
01:39:36<Hunner>> [floor(x/2) | x <- [0 .. maxBound::Int]]
01:39:38<lambdabot> No instance for (RealFrac Int)
01:39:38<lambdabot> arising from a use of `floor' at ...
01:40:01<roconnor>you cannot divide with Ints
01:40:04<roconnor>you can `div` though.
01:47:37<Axman6>ok, so. does R^2 have more numbers in it than R^1?
01:48:25<dolio>R is the reals?
01:48:32<Axman6>yeah
01:48:40<dolio>They have the same number of elements.
01:49:10<Axman6>ACTION does not like this
01:49:20<josephholsten>diagonalization proof, seems to imply otherwise
01:50:36<Axman6>so 2D space has as many elements as 1D (just making sure the question's clear)
01:51:02<dolio>Yes. As does any finite dimensional space.
01:51:11<wli>|R^k|=k|R|=|R| when k is finite.
01:51:45<Axman6>ACTION still does not like this
01:51:52<dolio>Maybe a countably infinite dimensional space, too. I'm not sure about that one.
01:53:11<dolio>I'm not sure what mapping from R^2 to R you use to demonstrate it, though.
01:54:07<josephholsten>countable infinite is aleph-0
01:54:45<dolio>Maybe interleaving the digits in some representation would do?
01:55:05<josephholsten>reals are cardinality aleph-1
01:55:06<Asztal>it would
01:56:14<josephholsten>oops, cardinality of continuum = 2^aleph-0
01:56:16<dolio>That's probably most convincing, too, if you take [0,1)^2, and show that it has the same cardinality as [0,1).
01:56:44<dolio>Then you show that R^2 has the same cardinality as [0,1)^2.
01:57:30<marcusb>Saizan: hey, WriterT [String] State Machine () works now, amazingly enough. Took me awhile to get lifting right and figure out how to run it, the best example was in Real World Haskell.
01:57:34<marcusb>thanks a lot
01:59:26<camio>Does anyone have a general idea for how often the google summer of code projects complete their objectives?
02:02:02<kyevan>Is it possible to construct an infinite list where the value of each entry relies on the previous one/few?
02:02:18<davidmccabe>First Haskell program, almost. Any comments or suggestions? http://dmccabe.org/tmp/quotient_rings.hs
02:02:49<SubStack>camio: #gsoc
02:02:56<roconnor>ACTION tries to construct a continous injection from R^2 to R
02:03:06<SubStack>I'm sure they'd know better than haskell folks
02:03:20<stroan>kyevan: f a b c = a+b+c : f b c (c+2) ?
02:03:26<camio>SubStack: thanks
02:03:37<stroan>that kind of thing?
02:04:04<kyevan>Oh. Right, recursive calls!
02:04:07<kyevan>Yeah :P
02:04:30<SubStack>davidmccabe: pretty ambitious for a first program
02:05:06<roconnor>davidmccabe: I don't see anything particularly wrong by glancing at the code.
02:05:15<SubStack>although it's not terribly clear what's going on, some sort of latex thing it seems
02:05:39<SubStack>more comments is a good suggestion
02:06:00<camio>davidmccabe: I would probably make another function for latexEnclose :: String -> String -> String, that handles the begin and end stuff.
02:07:01<mae_>what is the best way to handle a ctrl-c across windows and nix (sigterm)
02:07:05<SubStack>ACTION is playing with zippers and rose trees
02:07:11<roconnor>davidmccabe: I wouldn't indent your where section so much.
02:07:29<camio>davidmccabe: That would be bringing the latex part closer to a DSL (domain specific language). It makes code like this very readable.
02:08:05<alexsuraci>is there any sort of package for sending packets to/from a persistently connected client and server? (for example, implementing a mmorpg server)
02:08:20<camio>davidmccabe: Like roconner said. I usually indent 2 spaces myself.
02:08:39<SubStack>alexsuraci: Network is nice
02:08:42<roconnor>alexsuraci: I remember reading a blog post about a protocol library.
02:09:01<SubStack>Network.Socket not so much
02:09:07<alexsuraci>SubStack: Looking at it, but it looks like it's built for sending/receiving strings mostly
02:09:09<roconnor>or was it a Monad.Reader article?
02:09:15<camio>davidmccabe: By the way, thanks for sharing your code with us!
02:09:27<SubStack>raw packets?
02:09:39<alexsuraci>SubStack: yeah, as in hex data and such
02:10:11<camio>davidmccabe: Also, depending on how comfortable you are with higher level functions, uniqueSorted = Set.toAscList . Set.fromList.
02:10:12<davidmccabe>You're welcome, camio. Thanks everybody for the comments.
02:10:13<SubStack>there's a Raw thing in Network.Socket
02:10:18<SubStack>so however you'd do that in C I guess
02:10:31<davidmccabe>camio: I did that, but I had to add a type declaration and overall it was less clear because of the extra clutter introduced by it.
02:10:51<davidmccabe>:: (Eq a) => [a] -> [a] I think.
02:10:51<SubStack>type declarations are good
02:11:01<davidmccabe>Actually it had to be Ord.
02:12:04<camio>davidmccabe: keep up the work. There is sooo much to learn to improve ones coding in haskell if my experience is any indicator.
02:12:32<davidmccabe>camio: This is pretty much a direct translation from some Python I wrote the other day.
02:13:02<davidmccabe>I'm also trying to figure out exactly the right place to go from sets to lists, to get rid of the uniqueSorted everywhere.
02:13:18<camio>davidmccabe: How do you like programming in haskell in comparison so far?
02:25:22<wli>ACTION usually just deals with Set almost everywhere when uniqueness is a constraint.
02:25:39<davidmccabe>camio: It's a pain in the ass.
02:25:46<davidmccabe>:)
02:26:38<duaneb>so
02:26:41<duaneb>I have this function
02:26:43<camio>:) I feel you, bro. Get's better.
02:26:44<SubStack>once you pick up the idioms it gets better
02:26:50<duaneb>wait a minut
02:26:52<duaneb>minute*
02:27:24<duaneb>> let foo :: (Monad m) => Int -> m; foo 5 = return ()
02:27:25<lambdabot> <no location info>: parse error on input `;'
02:27:30<duaneb>what's up with that?
02:27:38<duaneb>not lambdabot's error
02:27:40<dibblego>m is a type constructor :: * -> *
02:27:50<duaneb>what does that mean?
02:27:58<dibblego>it means it takes another type variable
02:28:05<duaneb>dammit
02:28:18<dibblego>> let foo :: (Monad m) => Int -> m (); foo 5 = return () in 7
02:28:20<lambdabot> 7
02:28:50<roconnor>@kind Maybe
02:28:50<duaneb>yea, I just figured that out :P
02:28:51<lambdabot>* -> *
02:29:02<roconnor>@kind Maybe Int
02:29:03<lambdabot>*
02:29:15<roconnor>@type Just 7
02:29:16<lambdabot>forall t. (Num t) => Maybe t
02:29:24<roconnor>ah, close enough
02:29:40<roconnor>@type Just (fix bitsize)
02:29:41<lambdabot>Not in scope: `bitsize'
02:29:44<roconnor>@type Just (fix bitSize)
02:29:45<lambdabot>Maybe Int
02:37:10<duaneb>so, I have a function here
02:37:10<duaneb>putData ((r,g,b):dat') = putWord8 b >> putWord8 g >> putWord8 r >> putData dat'
02:37:14<duaneb>Is that tail recursive?
02:37:37<idnar>does it matter?
02:37:41<duaneb>idnar: yes
02:37:49<Berengal>It's not even a function
02:37:54<duaneb>Not in this case, especially, but I want to understand the language
02:37:58<duaneb>Berengal: ?
02:38:25<Berengal>Well, it is, but it produces an action
02:38:39<duaneb>that's true
02:38:46<duaneb>but is the call to putData a tail call?
02:38:48<Berengal>I like to think of such functions as actions with parameters...
02:39:02<duaneb>I mean, that's what I want to know
02:39:37<Berengal>No, the last call is to (>>)
02:39:37<ski>ACTION . o O ( forM_ )
02:39:53<duaneb>Berengal: dammit
02:39:56<Berengal>But I'm being pendantic
02:40:03<duaneb>any way to MAKE it a tail call?
02:40:04<Berengal>It'll run in constant stack though
02:40:09<duaneb>ok
02:40:10<duaneb>why is that?
02:40:14<duaneb>special case for monads?
02:40:17<Berengal>It's being lazy about it
02:40:25<duaneb>or is the compiler just smart in the order it applies the functions?
02:40:42<Berengal>Not as much smart as lazy
02:40:49<idnar>duaneb: lazy evaluation means things aren't evaluated until they're needed
02:41:06<duaneb>Is there a paper on this somewhere?
02:41:10<Berengal>duaneb: You need to stop thinking in terms of tail calls :P
02:41:17<duaneb>I understand lazy evaluation fine, just not in this case....
02:41:23<Cale>What that really means, for the most part is that functions are applied outermost first.
02:41:35<duaneb>I don't know what 'outermost' means
02:41:41<duaneb>right or left most? ::P
02:41:45<Cale>Think of expressions as trees
02:41:54<Berengal>duaneb: leftmost, assuming operators are written prefix
02:41:54<Cale>Start nearest the top of the tree.
02:42:05<Berengal>A function is evaluated before its arguments
02:42:09<Cale>right
02:42:16<duaneb>ok, that makes sense
02:42:18<Cale>I'll do my standard example.
02:42:23<duaneb>the laziness doesn't, though
02:42:23<Cale>Suppose we have double x = x + x
02:42:37<Cale>and we want to evaluate double (double 5)
02:42:46<duaneb>though, the function does absolutely nothing BUT return if putData returns
02:42:52<roconnor>The whole notion of tail-call makes no sense for haskell because "entering a function" does not push anything onto a stack.
02:43:11<duaneb>ACTION needs to learn the haskell internals
02:43:14<duaneb>is there a paper on THAT?
02:43:21<jmcarthur>duaneb: STG machine
02:44:04<stroan>roconnor: thanks for that. That's acutally cleared a lot up in my head
02:44:10<Cale>duaneb: It's not necessary to really understand the GHC implementation to have a good sense of things like performance though, in most cases.
02:44:13<duaneb>roconnor: how does it pass information, then?
02:44:17<duaneb>through registers and the heap?
02:44:28<roconnor>duaneb: I usually imagine it doing graph reduction
02:44:29<Cale>duaneb: There is a much higher-level approximation you can use.
02:44:29<duaneb>Cale: It will help me figure out the best way to write, though
02:44:34<roconnor>even though that isn't quite how GHC works.
02:44:40<duaneb>Clearly thinking of tail-calls doesn't help
02:44:58<duaneb>hmm
02:44:58<duaneb>ok
02:45:03<duaneb>I'll start digging through ghc
02:45:05<Berengal>Imagine evaluating the AST directly
02:45:07<Cale>Wait wait
02:45:16<Berengal>From the top
02:45:21<duaneb>I'm still reading :P
02:45:36<Cale>Come to haskell-overflow, and I'll go over some evaluation with you and it should start becoming more obvious how things work :)
02:53:08<alexsuraci>it occurs to me that I keep changing my language and it's getting closer and closer to haskell
02:53:19<alexsuraci>i predict that the final product will end up being haskell implemented in itself
02:55:32<halberd>if I'm looking for a minimalistic dependently typed language, should I look no further than LF (Logical Framework)?
02:56:42<dolio>Using what, twelf?
02:57:03<halberd>well I want to write my own
02:57:13<dolio>Oh, okay.
02:57:28<halberd>but based on some simple formalism
02:57:43<dolio>Well, calculus of constructions is pretty easy to implement.
02:57:54<dolio>I'm not very familiar with LF, but I doubt it's any easier.
02:58:12<dolio>If easiness is what you're going for.
02:58:20<halberd>it is
03:06:21<halberd>and CoC is as powerful as LF?
03:07:07<halberd>I mean, can every theorem that can be proved in LF also be proved in CoC?
03:09:53<dolio>Well, wikipedia doesn't give a whole lot of information on LF, but they sound pretty similar.
03:12:02<dolio>I guess, strictly speaking, I've implemented LF before, as well.
03:17:25<halberd>if you've implemented CoC, could I have a look at your source code?
03:17:29<mmorrow>roconnor: but evalutation pushes things on the stack
03:17:39<dolio>Anyhow, in the calculus of constructions, you have effectively a kind level, and then a single type above the kind level, and the hierarchy stops there.
03:17:46<roconnor>in GHC case analysis pushes things onto a stack.
03:18:01<roconnor>> fix tail
03:18:02<mmorrow>roconnor: case is the only thing that causes evaluation
03:18:02<lambdabot> * Exception: stack overflow
03:18:14<dolio>The wikipedia describes LF as "predicative" which might mean you have an infinite number of levels, but I'm not sure.
03:18:43<dolio>If that's not what they mean by that, then I don't know what the difference between CoC and LF would be, exactly.
03:18:52<mmorrow>roconnor: so if your entire result depends on more than just the next "tick", you're essentially in the same situation as you'd be in a strict language
03:19:01<mmorrow>e.g. sum
03:19:25<roconnor>mmorrow: entering a function is totally distinct from case analysis.
03:20:22<roconnor>mmorrow: I'm not really understanding what point you are trying to make.
03:20:31<mmorrow>roconnor: you need a result. so you evaluate, which entail jumping to functions, which begin executing their code, which may need to case on things, and jump to other functions, build closures, etc
03:20:49<duaneb>Cale: sorry, mibbit died
03:20:55<duaneb>and then I joined the wrong channel
03:20:56<dolio>And I would show you my code, but I messed it all up fooling around with unification stuff, so it doesn't work very well anymore.
03:21:03<mmorrow>the point i'm trying to make is that things need to be evaluated at some point
03:21:06<Cale>duaneb: ah, it's #haskell-overflow
03:21:13<halberd>ok
03:21:23<halberd>well in general how did you approach it then?
03:21:33<dolio>I can point you at an augustss blog post that shows how to do it, though.
03:21:43<dolio>I went a little beyond and made it into a pure type system.
03:22:08<roconnor>mmorrow: you don't jump to functions, you jump to thunks.
03:22:16<halberd>ok
03:22:27<roconnor>mmorrow: these thunks might be in the middle of a function body, and often are
03:22:32<mmorrow>so my point is that the part of the heap that you *are* going to evaluate, because you need it, you do so strictly
03:22:42<halberd>Cayenne a language with dependent types?
03:22:47<roconnor>mmorrow: and the body is only executed upto revealing the next constructor before execution is suspended.
03:23:02<mmorrow>but you need *all of it*
03:23:19<mmorrow>say i do "foldr (+) 0 [0..100000000000] == 4"
03:23:22<roconnor>mmorrow: what does any of what you are saying have to do with tail calls?
03:23:25<dolio>http://augustss.blogspot.com/2007/10/simpler-easier-in-recent-paper-simply.html there we go.
03:24:11<cads>hey I want to infer haskell types from clojure code, can I do this for limited but useful cases?
03:25:27<halberd>thanks dolio
03:25:47<mmorrow>int sum(int x, int *xs, int i, int n){ if(i < n){return xs[i] + sum(x,xs,i+1,n);} return x;}
03:25:58<mmorrow>imagine running that in C
03:26:23<mmorrow>that's exactly what you're doing when you do "foldr (+) 0 [...]" in haskell"
03:27:10<mmorrow>because the single Int result isn't complete until you hit the end of the list, /then return back through all the stack frames you've pushed onto the stack/
03:27:45<mmorrow>(so i'm just talking about when the entire result depends on traversing the entire structure here)
03:28:12<roconnor>In C, calling sum pushes a stack frame
03:28:23<roconnor>in Haskell calling (+) pushes the stack frame.
03:28:40<mmorrow>so does haskell when it comes time to actually evaluate "foldr (+) 0 [..]"
03:28:51<mmorrow>but you need the result of (+)
03:28:55<mmorrow>not just the thunk
03:29:12<mmorrow>so you need to evaluate (+) and both operands
03:29:17<roconnor>(+) is a effectively doing case analysis, even though it is a prim op
03:29:33<roconnor>and case analysis pushes stack frames in GHC
03:29:36<roconnor>not function calls.
03:29:51<mmorrow>1 + (2 + (3 + (4 + ( ............... (10000000000000 + 0
03:30:05<mmorrow>evaluate "1"...done
03:30:11<mmorrow>evalutate the rhs
03:30:23<mmorrow>goto => evaluate 2...done
03:30:28<mmorrow>evaluate the rhs
03:30:30<mmorrow>....
03:30:40<roconnor>mmorrow: I still don't get what you are disagreeing about.
03:31:12<mmorrow>i'm saying that you can use either the heap or the stack in haskell just like you can in strict langs
03:31:41<roconnor>no you don't
03:31:44<roconnor>In C, calling sum pushes a stack frame
03:31:53<roconnor>in Haskell calling (+) pushes the stack frame.
03:32:56<mmorrow>i don't see your point
03:33:16<mmorrow>:)
03:33:40<roconnor>[23:26] <mmorrow> that's exactly what you're doing when you do "foldr (+) 0 [...]" in haskell"
03:33:44<roconnor>I'm saying they are not exactly the same
03:33:59<mmorrow>you're pushing 100000000 stack frames to eval the Int!
03:34:18<mmorrow>just like you're pushing 100000000 stack frames to eval sum to completion
03:34:50<mmorrow>(for that particular `sum')
03:34:56<roconnor>mmorrow: firstly I don't think the number of stack frames is the same. I think they will probably differ by one. Secondly, even if the number of stack frames is the same, it is entirely coincidental.
03:35:14<mmorrow>heh
03:35:19<roconnor>I stand by my claim that the notion of tail-call make no sense in haskell.
03:35:46<Baughn>Makes perfect sense for strict evaluation, doesn't it?
03:35:54<Baughn>It's just a bit rare to run into that
03:36:56<roconnor>the purpose of tail-call optimization is to clear the stack before exiting a function at a tail call.
03:37:23<roconnor>but since entering a function in haskell doesn't allocate stack space, the whole idea of clearing it before a tail call makes no sense.
03:37:43<Baughn>Evaluating a thunk does allocate stack space, though
03:37:51<roconnor>yes
03:38:10<Baughn>And when you have to evaluate multiple thunks at once, you can do tail-call optimization
03:38:23<mmorrow>my claim is that the considerations change, but laziness doesn't save you from blowing your stack in the situation where you go to evaluate some massive thunk you've built, because if you need to eval /all/ of that thing to get any result at all, it's very similar to strict eval
03:38:40<dolio>Stack space is needed to evaluate subexpressions. Tail-call optimization is the realization that in "return g(...)", g(...) is not a subexpression of anything. :)
03:38:47<roconnor>mmorrow: I don't contest that.
03:38:54<mmorrow>that's all i'm saying :)
03:39:07<roconnor>I never said you couldn't blow a stack.
03:39:36<dolio>But in haskell, function application doesn't correspond to evaluating subexpressions anyway. :)
03:40:15<roconnor>Baughn: plz explain your multiple thunk thing
03:40:32<roconnor>Baughn: cause it makes no sense to me.
03:41:17<Baughn>roconnor: Um. Say, 1+(2+3), where the runtime doesn't hit any constructors while evaluating the first + before evaluating both parameters
03:41:25<mmorrow>dolio: yeah, it's like inverted strict evaluation (or something) ((haz now, pay later (if you actually try to)))
03:42:27<roconnor>Baughn: okay, where does the tail call come in?
03:43:06<Baughn>roconnor: In realizing that, to sum a large chain of numbers, you can live with constant stack space
03:45:27<roconnor>How do you realize that?
03:51:34<Lemmih>Draconx|Laptop: Please return to MC3018.
03:53:18<mmorrow>ok, so i think i've figure out how to say what i'm thinking.. i think saying that "tailcalls don't make sense in haskell" is misleading, because it implies that the eval model is such that it's even be a consideration (i.e. every function returns to caller, must optimize away tailcalls), *but* the bad results you can get if you try to do something in a non-tailcall-optimized language with recursion are still possible in haskell, under ce
03:53:18<mmorrow>rtain conditions (which are avoidable)
03:56:02<roconnor>I claim these bad results are only superficially similar, and in fact the cause behinds these similar bad results are totally different.
03:56:35<mmorrow>but they're just the other side of the same coin
03:56:47<dolio>Yes, but the way you avoid them isn't solely by using tail calls, it's by forcing things earlier than absolutely necessary.
03:57:18<roconnor>I think they are totally different coins
03:57:31<mmorrow>dolio: exactly, or by turning your recursion inside-out
03:58:00<dolio>Of course, sometimes you need to rewrite things to be more tail callish. But that's not sufficient.
03:59:04<mmorrow>> let foo x [] = x; foo x (y:xs) = let !z = foo x xs in y + z in foo 0 [0..1000000000] {- bad -}
03:59:06<lambdabot> * Exception: stack overflow
03:59:41<mmorrow>> let foo x [] = x; foo x (y:xs) = let !z = x + y in foo z xs in foo 0 [0..1000000000]
03:59:56<lambdabot> thread killed
04:00:34<mmorrow>dolio: yessss, that's really exactly what i'm trying to say
04:01:06<mmorrow>i just don't know how exactly to phrase my thoughts, because they're not really precise
04:02:03<vixey>mmorrow interpretive dance
04:02:37<Elly>an interpretive dance in six lambdas
04:04:36<vixey>mmorrow have you read my blog posts about TCO in haskell :D
04:04:46<vixey>they're controversal according to 'reddit'
04:04:48<mmorrow>no, link?
04:04:51<mmorrow>heh
04:05:21<Elly>vixey: you're just a controversial person
04:05:31<dolio>Well, if it's on reddit it must be true.
04:06:18<mmorrow>i thought that was the internet
04:07:32<jekor>Hey guys. How would I go about applying a function to arguments contained in a list? I presume that I need to use Template Haskell, but I'm not sure how. I'd like to be able to say "alright, apply this function to this list of arguments, but if the number of arguments don't match the size of the list, return Nothing".
04:08:21<jmcarthur>jekor: so you are wanting the first element to be the first argument, the second element to be the second argument, etc.?
04:08:29<vixey>jekor which function?
04:08:37<jekor>jmcarthur: Yes.
04:08:55<jekor>vixey: Depends. Usually data constructors.
04:09:05<jekor>It's to try and cut down on some boilerplate for working with SQL.
04:09:06<vixey>jekor so a whole bunch of different functions, with different types
04:09:08<vixey>?
04:09:31<jekor>vixey: I was thinking along the lines of: fromValues someFunc 5 someList
04:09:41<vixey>?
04:09:51<mmorrow>vixey: i can't find it, is your code blog the right place to look?
04:10:06<vixey>mmorrow: I just realized my post is irrelevant nonsense :/
04:10:11<vixey>probably best to avoid it
04:10:13<mmorrow>:(
04:10:17<Baughn>> foldr ($) (printf "%d %d") [1,2] :: String
04:10:18<lambdabot> No instance for (Num (String -> String))
04:10:18<lambdabot> arising from the litera...
04:10:35<Baughn>ah.. no, not quite right. How was it...
04:10:46<jekor>Baughn: I knew I should have looked at the example for printf more closely...
04:11:07<vixey>ACTION says to jekor: Are you talking about a bunch of different functions with _different types_ or just one type?
04:11:10<Baughn>jekor: Just so you know, this is something you almost never actually want.
04:11:48<Baughn>jekor: The printf hack is so it can use a format string; in general it's better to use combinators
04:11:54<jekor>Hmm...
04:12:03<jekor>Any pointers on how to go about doing that?
04:12:13<vixey>ACTION says to jekor: ok suit yourself
04:12:18<jekor>vixey: :P
04:12:23<Baughn>jekor: Start by looking at how parsec works, I guess. That's nice and practical. :)
04:12:26<vixey>I'm just not gonna let it bother me
04:12:50<vixey>you'd probably not understand what I said if I did answer your q anyway
04:13:09<jekor>vixey: I'm confused by what you're asking.
04:13:11<vixey>increasingly seems to happen where I tell someone something and they just go "what"
04:13:22<vixey>ooh I wonder if telling me that instead of ignoring me would have been quicker progres
04:13:31<jekor>vixey: The idea was to generate a bunch of functions with different types at compile time, yes.
04:13:42<vixey>sounds bad but I'm not gonna stop you
04:13:43<jekor>vixey: Not if I wanted to get information from Baughn first.
04:15:24<Baughn>jekor: Anyway, what you're asking is a staple of dynamic languages, which haskell is not
04:16:03<Baughn>jekor: There are no doubt other ways to do what you'd be using it /for/, but it's hard to suggest at this level. You're saying "how do I drive across the atlantic", when you should just be asking "how do I get to europe in the fastest way"
04:16:17<jekor>Baughn: Aye. Ideally I'd be able to use something like MetaHDBC, but it doesn't seem to compile with the latest HDBC.
04:16:59<Baughn>jekor: Oh, HDBC? Yeah, queries are kind of akin to printf format strings..
04:17:14<Baughn>jekor: You /could/ do the same trick with those, but it'd probably be better to invent a combinator language instead
04:18:14<jekor>Wouldn't I have just reimplemented HaskellDB by that point? What am I missing here?
04:19:24<roconnor>mmorrow: the fact that your good version of foo works has nothing to do with foo being in a tail call position.
04:19:31<Baughn>jekor: Nothiing much. Yes, that's exactly what you'd be doing. :P
04:19:34<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap (foo z xs) in foo 0 [0..10000000]
04:19:43<jekor>Baughn: OK. Just checking. Thanks for the tips ;)
04:19:48<roconnor>observe, no tail call, yet no stack overflow
04:19:49<lambdabot> thread killed
04:19:55<Baughn>jekor: I'm telling you how it /should/ work. Nobody says the system is perfect. :/
04:20:17<Baughn>jekor: As it is, well, you'll kind of have to learn to love toSql
04:20:18<jekor>Gotcha. I'd love to get there at some point.
04:20:32<roconnor>I did @let swap x = let (a,b) = x in (b,a) in a pm with lambdabot
04:20:32<mmorrow>roconnor: the reason that the bad one doesn't is because it's not
04:20:55<roconnor>mmorrow: but my codes doesn't have foo in the tail position either.
04:21:15<vixey>mmorrow: my point was TCO doesn't exist in Haskell btw
04:21:24<dolio>@type swap
04:21:44<roconnor> swap x = let (a,b) = x in (b,a)
04:21:52<mmorrow>wut, ok we're not even talking about the same thing when we say "tail recursion"
04:22:00<lambdabot>thread killed
04:22:12<roconnor>mmorrow: was that directed at me?
04:22:15<mmorrow>yes
04:22:45<roconnor>what the heck are do you think tail call means?
04:22:50<roconnor>s/are//
04:23:12<vixey>ACTION says TCO and means http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-6.html#%_idx_80
04:23:14<vixey>not that anyone ased me
04:23:20<mmorrow>in `bad', the ! makes it so that eval will have to return to that point, then proceed to contruct the resulting closure of which the `z' in !z will be a part
04:23:26<vixey>but yeah -- there's a formal def, it's completely syntactic
04:23:32<jekor>One difference I see with printf is that it generates a function that accepts n arguments. But I was hoping to accept a function that accepts n arguments and then apply it to a list. The list extraction seems to be the key. And I won't have the list until runtime.
04:23:41<mmorrow>in your and my `good', it doesn't
04:23:52<jekor>Nevermind, I think I know how I can do it.
04:23:58<Baughn>@type printf
04:24:01<Baughn>@type foldr
04:24:01<lambdabot>forall r. (PrintfType r) => String -> r
04:24:02<lambdabot>forall a b. (a -> b -> b) -> b -> [a] -> b
04:24:09<mmorrow>once you construct the result closure, you never have to return to that function again
04:24:11<roconnor>> let foo x [] = x; foo x (y:xs) = let !z = x + y in 2*(foo z xs) in foo 0 [0..10000000]
04:24:16<lambdabot> * Exception: stack overflow
04:24:18<jekor>Baughn: Ah...the foldr. Thank you.
04:24:20<roconnor>that stack overflows
04:24:23<roconnor>and it has a !z
04:24:54<Baughn>> (foldr ($) (printf "%d %d %s") [1,2]) "foo" :: String
04:24:55<lambdabot> No instance for (Num (([Char] -> String) -> [Char] -> String))
04:24:55<lambdabot> a...
04:25:00<Baughn>ACTION sighs
04:25:30<vixey>mmorrow: what is it exactly you're figuring out
04:25:34<vixey>or discussing or whatever
04:25:40<vixey>something to do with 'TCO' but what?
04:25:46<vixey>or maybe it's to do with stack overflows.. ?
04:26:02<roconnor>mmorrow: I agree you need the !z for efficency; however the !z has nothing to do with a tail call
04:26:10<mmorrow>roconnor: that's no different in essence than 'bad'
04:26:19<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap (foo z xs) in foo 0 [0..10000000]
04:26:25<roconnor>no tail call, yet it is good.
04:26:35<lambdabot> thread killed
04:26:36<mmorrow>roconnor: i'm was only using the !z there to order evaluation
04:26:56<roconnor>why are you describing your "good" foo as having a tail call
04:27:02<mmorrow>a closure is built for this ===> "swap (foo z xs)"
04:27:35<mmorrow>ok ok, i have to take a break
04:27:40<roconnor>@undefine
04:27:41<vixey>:(
04:27:53<roconnor>@let swap (a,b) = (b,a)
04:27:55<mmorrow>vixey: i'm not even certain anymore
04:27:57<lambdabot> Defined.
04:28:00<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap (foo z xs) in foo 0 [0..10000000]
04:28:06<vixey>ok
04:28:06<lambdabot> * Exception: stack overflow
04:28:12<roconnor>now it does overflow!
04:28:43<roconnor>bah!
04:28:45<roconnor>ACTION gives up
04:28:51<mmorrow>@let swap' ~(a,b) = (b,a)
04:28:52<lambdabot> Defined.
04:28:59<mmorrow>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap' (foo z xs) in foo 0 [0..10000000]
04:29:15<lambdabot> thread killed
04:29:31<roconnor>see, it has everything to do with where case analysis are, and nothing to do with whether foo is making a tail call.
04:30:08<dolio>It has to do with tail calls involving strict functions.
04:30:21<mmorrow>i think we need to stop calling it "tailcall" because i'm not even talking about that really
04:30:45<roconnor>mmorrow: Well that's pretty much what I said at the beginning.
04:30:46<jmcarthur>@quote endofunctor
04:30:54<mmorrow>i'm talking about exactly what you just said.... it has to do with the path of execution during evaluation of the graph of thunks you've created
04:31:00<jmcarthur>uh...
04:31:00<roconnor>the notion of "tail-call" isn't applicable to haskell.
04:31:07<vixey>roconnor I agree!
04:31:14<jmcarthur>@quote monads
04:31:19<mmorrow>and the position of things determines that path
04:31:23<mmorrow>(obviously)
04:31:24<lambdabot>psykotic says: [monads aren't hard] they're just monoids on the category of endofunctors over some category, what's the big deal?
04:31:24<lambdabot>samc says: monads are hard. let's go shopping!
04:31:26<vixey>I'm so happy now there's 2 people in the world that think that :p
04:31:31<jmcarthur>finally...
04:33:06<roconnor>so instead of telling people, oh to sum lists you should use strictness and a tail call, we instead should be saying, you need to use strictness and arrange things in the right order.
04:33:40<roconnor>because, as you can see from the swap' example, it foo doesn't even have to be put into tail-call position to fix the stack-overflow.
04:33:41<dolio>A tail call is the right order.
04:34:00<mmorrow>which i think is the flip side of the coin of what you consider when writing strict code that uses tail calls
04:34:19<mmorrow>yes
04:34:32<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap' (foo z xs) in foo 0 [0..10000000]
04:34:48<lambdabot> thread killed
04:34:48<roconnor>dolio: the above doesn't have a tail call, and there is no stack problem.
04:35:07<roconnor>dolio: so you are wrong when you say that tail call is the right order.
04:35:17<mmorrow>tail calls are applicable, but in a reverse, inverted, backwards, and opposite in time, space, and direction!
04:35:28<roconnor>ugh!
04:35:34<dolio>No, it is the right order. Just not the only right order. :)
04:37:18<dolio>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap' (foo z xs) in foo 0 [0..1000000]
04:37:27<lambdabot> (0,500000500000)
04:40:00<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in swap' (foo z xs) in foo 0 [0..1000001]
04:40:30<lambdabot> thread killed
04:40:55<roconnor>;(
04:40:59<dolio>I think we might be destroying the machine lambdabot's on.
04:41:28<mmorrow>@pl (\x -> x x) (\x -> x x)
04:41:31<lambdabot>ap id id (ap id id)
04:41:31<lambdabot>optimization suspended, use @pl-resume to continue.
04:41:39<mmorrow>fingers slipped
04:42:17<roconnor><dolio> No, it is the right order. Just not the only right order. :)
04:42:31<roconnor>Do you seriously think that is a defense of using the term tail call?
04:42:34<roconnor>or are you just joking?
04:43:27<mmorrow>@bot
04:43:27<lunabot> :)
04:45:13<dolio>If you're telling a newbie how to write 'sum', telling them to use a tail call and strictness on an accumulator tells them the correct way to implement it.
04:46:06<Baughn>> foldl (printf "%d %d") [] [1,2] :: String
04:46:17<lambdabot> "* Exception: Printf.printf: bad argument
04:46:21<dolio>In general, the rule is (approximately) tail calls possibly guarded with non-strict functions.
04:46:53<dolio>If you're inclined to think in terms of tail and non-tail calls.
04:46:55<Baughn>> foldl1 (printf "%d %d") [1,2] :: String
04:46:56<lambdabot> No instance for (Num String)
04:46:56<lambdabot> arising from the literal `1' at <in...
04:46:59<copumpkin>moo
04:47:15<copumpkin>I got a legit copy of the ARMv7 documents!
04:47:19<Baughn>> foldl1 (printf "%s %s") ["1","2"] :: String
04:47:20<lambdabot> "1 2"
04:47:37<Baughn>..oh, that's just great
04:49:16<david_>Hm. I'm a bit lost here. I've done a small (hello world-style) web app with fastcgi and everything works fine there. However, how can I access things such as GET and POST variables?
04:49:21<dolio>Well, I see that ghci-haskelline didn't improve my ^C handling any.
04:52:44<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in id (foo z xs) in foo 0 [0..1000001]
04:52:46<lambdabot> (500001500001,0)
04:53:00<copumpkin>it's kind of awkward when someone says "especially for a woman" on -cafe
04:53:01<roconnor>dolio: id is a strict function, and it works fine in place of swap'
04:53:10<roconnor>> let foo x [] = (x,0); foo x (y:xs) = let !z = x + y in id (foo z xs) in foo 0 [0..100000000]
04:53:25<lambdabot> thread killed
04:53:35<dolio>Yes, but id is one of a few special cases.
04:53:36<copumpkin>> fst (5, id 6)
04:53:38<lambdabot> 5
04:53:41<copumpkin>> fst (5, id undefined)
04:53:43<lambdabot> 5
04:53:52<MyCatVerbs>copumpkin: who what where? Drama?
04:54:19<roconnor>dolio: I think your rule is pretty misleading.
04:54:24<jdrake>Is anyone aware of this 'haskell to objective c binding' ( http://code.google.com/p/hoc/ )
04:55:10<copumpkin>jdrake: I think it's a little bitrotted
04:55:34<dolio>I don't think it's necessarily a good way to teach neophytes, but if someone's coming from scheme or something, it explains the differences.
04:55:35<jdrake>A lot of stuff seems to have been done
04:56:05<jdrake>I am doing commercial development with cocoa and noticing certain things would lend themselves to haskell :p
04:56:33<roconnor>dolio: here's how you explain it to people coming from scheme:
04:56:51<roconnor>The whole notion of tail-call makes no sense for haskell because "entering a function" does not push anything onto a stack.
04:57:08<copumpkin>isn't it just pushing the notion to thunk evaluation instead of function call though?
04:57:10<roconnor>well, something like that.
04:57:23<dolio>Yes, and I already wrote out an explanation like that earlier.
04:57:35<copumpkin>ah
04:58:15<roconnor>copumpkin: I haven't really understood what a tail-call for thunk evaluation would be, but I think that is what mmorrow was trying to get at.
04:58:18<vixey>I don't think it's schemers getting confused though :)
04:58:32<dolio>OCamlers, then.
04:58:56<roconnor>copumpkin: but the point is that the form of a recursive function has little to do with it's stack properties.
04:59:15<roconnor>it is all about how the case analysis statements are arranged.
04:59:29<BMeph>copumpkin: If the original topic concerns peeing with no hands, I guess that could apply. ;p
04:59:41<roconnor>which is why, id wasn't a problem in my code. Because id does no case analysis.
05:01:46<dolio>Yes, but it's only one of two (I believe) strict functions that don't.
05:01:55<dolio>Technically 3 in Haskell.
05:02:23<copumpkin>how is id strict?
05:02:31<dolio>id _|_ = _|_
05:03:56<dolio>Although I suppose it's hard to imagine it being a problem anyway.
05:04:35<dolio>Does doing something like (define foo () (id (foo))) blow the stack in scheme?
05:05:11<roconnor>(define foo () (id (foo ()))) ?
05:05:14<dolio>I suppose you'd have to ensure that it doesn't just eliminate id.
05:05:17<copumpkin>oh, is that how strict is defined?
05:05:28<copumpkin>I guess that makes sense
05:05:52<dolio>(foo) is how you call a function of no arguments in scheme, isn't it?
05:05:55<vixey>dolio it crashes sisc
05:05:56<dolio>It's been a while.
05:06:13<vixey>which is fine, I expect that (id (foo)) to explode
05:07:50<dolio>Technically seq doesn't do case analysis, either, it does magic. :)
05:08:44<roconnor>I consider seq case analysis since I don't ever recall applying it to functions.
05:08:58<roconnor>If we had our Seq class, it would actually be case analysis I think.
05:09:47<dolio>I'm not sure if I have or not. I wonder if one can construct a stack overflow on a function...
05:10:31<dolio>Aside from, like, 'let y f = f (y f) in y id :: a -> a'.
05:10:41<dolio>Which is clearly cheating.
05:10:42<MyCatVerbs>dolio: (foo) is indeed how you call a zero-arity function in Scheme.
05:11:14<copumpkin>MyCatVerbs: I meant Bulat's response to Belka
05:11:57<dolio>Interestingly enough, I went back and read some of the old reports with the Seq class, and despite it being in a class, it still worked on functions, and was magic.
05:12:04<dolio>You weren't allowed to define instances yourself.
05:12:23<MyCatVerbs>copumpkin: thanks. I haven't been up to date on -cafe for several months now. >>
05:12:52<MyCatVerbs>To the tune of... four thousand unread posts? By Thor's left nut, that is a lot of email. x_x
05:13:21<roconnor>dolio: oh?
05:13:21<copumpkin>:P
05:13:36<roconnor>dolio: interesting
05:13:44<roconnor>and hard to believe.
05:14:09<roconnor>I thought the whole complaint about removing the Seq class was about that seq would apply to functions.
05:14:33<dolio>Maybe that's why polymorphic seq got the pass, since it wasn't adding new eta-breaking to the language, just moving the eta-breaking out of a class. :)
05:16:35<david_>hmm.. Isn't there a built in function for splitting strings with given delimiter?
05:16:57<vixey>I don't think so
05:17:31<dibblego>Data.List.Split
05:18:06<dolio>From the 1.4 report: "Class Eval is a special class for which no instances may be explicitly defined. An Eval instance is implicitly derived for every datatype. Functions as well as all other built-in types are in Eval. (As a consequence, _|_ is not the same as \x -> _|_ since seq can be used to distinguish them.)
05:18:29<dolio>I didn't go all the way back to 1.0, though, so maybe there was a time when it wasn't that way.
05:18:45<vixey>it's stupid making it a class if it's defined for everything
05:19:12<dolio>Well, Typeable is, in principle, defined for everything.
05:19:26<dolio>Everything monomorphic, at least.
05:19:31<david_>hmm.. Isn't there a built in function for splitting strings with given delimiter?
05:19:34<david_>oops
05:20:08<david_>it complains on "Couldn't fine module Data.List.Split".. :(
05:20:11<jmcarthur>@src words
05:20:11<lambdabot>words s = case dropWhile isSpace s of
05:20:11<lambdabot> "" -> []
05:20:11<lambdabot> s' -> w : words s'' where (w, s'') = break isSpace s'
05:20:24<jmcarthur>david_: it's a package on hackage
05:20:32<david_>ah okay
05:21:08<roconnor>dolio: wow
05:22:02<dolio>Yeah, I was surprised, too.
05:22:41<roconnor>interseting
05:22:53<roconnor>> let foo x [] = fix (In . ((,)())); foo x (y:xs) = let !z = x + y in (\x -> let In (_,y) = x in y) (foo z xs) in fst . out $ foo 0 [0..1000000]
05:22:55<lambdabot> * Exception: stack overflow
05:23:08<dolio>Evidently 1.4 was not perfect. :)
05:23:09<roconnor>I wanted to show this as an example of a non-id strict function that doesn't overflow
05:23:15<roconnor>but it does overflow
05:23:35<roconnor>> let foo x [] = fix (In . ((,)())); foo x (y:xs) = let !z = x + y in (\x -> let In ~(_,y) = x in y) (foo z xs) in fst . out $ foo 0 [0..1000000]
05:23:37<lambdabot> * Exception: stack overflow
05:30:47<roconnor>I guess my let expression doesn't delay case analysis long enough.
05:35:36<Gracenotes>let in :(
05:35:52<bombshelter13_>Can a value ever be extracted and coerced into a value of it's original type after being put into a type like 'data F = forall a. Show a => F a'?
05:36:15<bombshelter13_>or can I only extract it and retype it as another type with identical constraints?
05:37:01<roconnor>bombshelter13_: I *think* if you know the original type you can safely unsafeCoerce it back.
05:37:07<Gracenotes>ouch
05:37:58<bombshelter13_>hm... *looks up unsafe coerce*
05:38:07<Gracenotes>bombshelter13_: probably not a good idea, though.
05:38:18<roconnor>bombshelter13_: you have to be sure to drop the constructor containing it.
05:38:27<Gracenotes>are you trying to have a heterogeneous list?
05:38:39<roconnor>of course
05:38:54<bombshelter13_>Yeah, pretty much.
05:39:22<roconnor>> let foo x [] = repeat 0; foo x (y:xs) = let !z = x + y in 1 : drop 1 (foo z xs) in foo 0 [0..100000000] -- does not stack overflow
05:39:38<lambdabot> thread killed
05:39:45<roconnor>> let foo x [] = repeat 0; foo x (y:xs) = let !z = x + y in 1 : drop 2 (foo z xs) in foo 0 [0..100000000] -- does stack overflow
05:39:49<lambdabot> [1* Exception: stack overflow
05:40:02<BMeph>roconnor: Liar. ;)
05:40:12<roconnor>BMeph: how so?
05:40:31<copumpkin>a smaller value might actually not get killed in the first case
05:40:54<roconnor>copumpkin:smaller value?
05:41:13<copumpkin>> let foo x [] = repeat 0; foo x (y:xs) = let !z = x + y in 1 : drop 1 (foo z xs) in foo 0 [0..1000000] -- does not stack overflow
05:41:22<lambdabot> [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...
05:41:28<copumpkin>> let foo x [] = repeat 0; foo x (y:xs) = let !z = x + y in 1 : drop 2 (foo z xs) in foo 0 [0..1000000] -- does stack overflow
05:41:36<lambdabot> [1* Exception: stack overflow
05:41:43<roconnor>when something does or does not stack overflow is unrelated to the tail call position.
05:41:44<copumpkin>just that :)
05:41:59<roconnor>copumpkin: um, where is my lie?
05:42:05<copumpkin>I never said you lied
05:42:15<roconnor>oh oops
05:42:28<copumpkin>I just said that in your first case, it got killed, so it wasn't very clear that it wasn't stack overflowing (with a different error)
05:42:32<copumpkin>*meant :)
05:42:37<Gracenotes>> error "stack overflow"
05:42:37<roconnor>good
05:42:40<lambdabot> * Exception: stack overflow
05:42:43<copumpkin>zomg
05:42:44<roconnor>:D
05:42:47<BMeph>I said he lied., though. :)
05:42:50<copumpkin>mmorrow: had a good one though
05:43:11<copumpkin>> error "stack overflsegmentation fault"
05:43:15<lambdabot> * Exception: stack overflsegmentation fault
05:43:21<Gracenotes>overflegmentation
05:43:22<copumpkin>something like that :P
05:43:27<roconnor>talking about tail calls is such a bad way of understanding stack overflows.
05:44:22<roconnor>and how to fix them
05:44:28<Gracenotes>in a lazy language, it's to do more with how man levels of thunk-i-ness there are
05:44:33<Gracenotes>as far as I understand
05:44:37<Gracenotes>y
05:44:51<roconnor>ya, talking about thunks is a fairly good way.
05:45:18<povman>Hi all.
05:45:25<roconnor>I didn't even know what caused stack allocations in GHC until a few weeks ago.
05:45:30<roconnor>I thought it was just prim ops
05:47:08<bombshelter13_>copumpkin: that's an awesome error, how'd you cause it?
05:47:21<copumpkin>bombshelter13_: I didn't :P it was just humor on mmorrow's part :)
05:48:23<bombshelter13_>damn, i'd have enjoyed seeing code that could cause that.
05:48:35<roconnor>error ("stack overfl"++unsafeCoerce 7)
05:48:47<roconnor>hmm
05:48:51<roconnor>error ("stack overfl"++unsafeCoerce id)
05:48:54<bombshelter13_>heh, without faking part of the string
05:48:55<roconnor>better
05:49:07<copumpkin>I don't think that would crash would it?
05:49:37<copumpkin>error (unsafeCoerce 5 "stack overfl") maybe?
05:50:10<Gracenotes>if you have a Num (a -> b) instance, not so bad :)
05:50:28<copumpkin>why not?
05:50:41<Gracenotes>but, actually, roconnor's code just causes unsafeCoerce id to be ""
05:50:45<Gracenotes>it seems
05:50:45<mmorrow>> help
05:50:51<lambdabot> <<loop>***Excep
05:50:51<lambdabot> Segmentaion fault
05:50:55<copumpkin>:P
05:50:57<Gracenotes>maybe it's converted it to the nullary constructor []?
05:51:01<mmorrow>heh
05:51:16<Gracenotes>mmorrow: I know text when I see it!
05:51:21<Gracenotes>o_O
05:59:36<povman>How likely are we to use template haskell when we discover something that (gasp) haskell can't do
05:59:37<povman>?
05:59:53<roconnor>povman: 30% chance
06:00:43<MyCatVerbs>povman: pretty likely. If you watch Haskell-cafe, you see places where people have used TH to fake optimisations in order to benchmark potential gains.
06:01:29<MyCatVerbs>povman: e.g. dons hacking together a loop unroller in TH in order to estimate how profitable it might be to add loop unrolling to GHC.
06:01:40<povman>hey cool
06:02:02<povman>Hm. Could you replace GHC with a template haskell expander?
06:02:34<MyCatVerbs>Probably, in as much as TH is Turing-complete after all.
06:02:58<povman>I am obviously procrastinating.
06:03:00<MyCatVerbs>You'd just need to tack on a phase at the end that ran the output through Hugs or something in order to dump the output binary.
06:03:37<MyCatVerbs>That'd be more "write a Haskell compiler in Template Haskell" than anything sensible though.
06:19:26<MyCatVerbs>Coinductive functions are just those that tail call on data constructors, right?
06:26:33<psygnisfive>http://news.ycombinator.com/item?id=612999
06:26:40<psygnisfive>guys should totally read the series e.e
06:30:02<centrinia>Is it possible to have a chain of metaprograms that has no minimum length?
06:30:43<povman>centrinia: what's a 'chain of metaprograms'?
06:31:37<centrinia>You start with some program, and a subsequent metaprogram outputs the previous program's source code.
06:32:25<copumpkin>in scripting languages, the trivial one should work
06:32:39<Nafai>Something like a higher-order quine?
06:32:41<copumpkin>or how do you mean?
06:32:53<copumpkin>I remember seeing a circular quine once, with 4 steps I think
06:33:06<copumpkin>maybe in an IOCCC submission
06:33:09<centrinia>Wait, will all chains contain a quine?
06:34:01<povman>centrinia: That sounds false.
06:34:22<p_l>copumpkin: the one with 4 ASCII arts?
06:34:32<copumpkin>that sounds right
06:34:38<copumpkin>I think they were manga style or something?
06:34:43<p_l>Saito -> Aku -> Soku -> Zan -> Saito
06:34:56<copumpkin>what's that from?
06:35:01<copumpkin>it was a cool entry, I thought :P
06:35:21<p_l>the first image was from a manga (but the character was based on real guy), the other three were the motto of his unit during Meiji Revolution
06:35:28<copumpkin>ah
06:35:59<p_l>"Aku Soku Zan" roughly translates as "Kill evil swiftly"
06:37:26<centrinia>Why isn't it possible for a chain of metaprograms to not contain a cycle?
06:37:51<povman>centrinia: Why do they have to contain a cycle?
06:37:53<p_l>copumpkin: the guy was "Saitō Hajime"
06:38:04<centrinia>povman, I don't know.
06:38:16<povman>centrinia: I could spend my whole life writing programs that printed the previous program and never have a loop
06:38:33<centrinia>Do they always contain a cycle?
06:38:38<povman>They'd keep getting bigger though.
06:38:49<povman>centrinia: Is this a homework question?
06:39:01<centrinia>I don't have homework.
06:39:20<copumpkin>o.O
06:39:36<centrinia>I only have workwork. ;)
06:39:50<povman>centrinia: Why don't you write a program, then write another that prints it, and so on
06:39:52<MyCatVerbs>It *is* possible for a chain of metaprograms to not contain a cycle. povman gave a fairly easy way to construct one: a modified quine that makes itself a little longer on each iteration.
06:40:27<centrinia>povman, I guess I was too drunk to have thought about that. :p
06:40:30<MyCatVerbs>No program in that chain will ever be identical to any other program in that chain.
06:41:09<povman>centrinia: Do you believe in Ballmer's peak?
06:41:11<p_l>copumpkin: funny, wikipedia claims the motto was fictional, while from some other sources I recall it being "unofficial motto" of the whole Shinsengumi. No time to chase the tails :D
06:41:18<copumpkin>:P
06:41:27<copumpkin>it was rather unfamiliar japanese, so I looked it up
06:41:44<centrinia>povman, No.
06:42:45<povman>This website says I have (1) message. I wonder who it's from?
06:42:54<MyCatVerbs>povman: it's my mum.
06:43:00<MyCatVerbs>She emails everybody.
06:43:03<copumpkin>:o
06:43:09<MyCatVerbs>Mostly about nitrogen generators.
06:43:37<MyCatVerbs>She's had it up to here with buying dozens of bottles of ammonia.
06:44:05<povman>I actually have a spare one if she needs it. Is she trying to kill some fish?
06:44:37<MyCatVerbs>No, harden titanium.
06:44:44<MyCatVerbs>Just the outside.
06:47:37<centrinia>Is liquid nitrogen soluble in liquid oxygen?
06:47:52<lw0x15>lol
06:48:00<bombshelter13_>if I had a function, mapfilter, where 'mapfilter f g l' returns an identical value to 'map f $ filter g l', but only iterates over the list once, instead of iterating over it once to filter and once to map the way 'map f $ filter g l' would, would it be any quicker, or is the difference optomized away? (assuming ghc)
06:48:50<Lemmih>bombshelter13_: The difference is optimized away.
06:49:10<bombshelter13_>handy to know
06:49:11<Gracenotes>laziness takes care of that for you
06:49:21<Gracenotes>laziness is responsible for lots of performance gains
06:49:31<MyCatVerbs>Gracenotes: (!)
06:49:39<Gracenotes>(?)
06:49:47<bombshelter13_>ahh, i see how that would help now that you point it out :0
06:50:05<MyCatVerbs>Gracenotes: laziness doesn't mean that the optimisation must happen, rather pure semantics mean that it's possible.
06:50:40<Gracenotes>yes. but most of the time it's best to think about code as though laziness is predictable -- because most of the time it is :) in common use
06:50:47<bombshelter13_>MyCatVerbs: er, while that might be true for certain particular optimizations it doesn't make gracenotes statement untrue
06:50:53<Gracenotes>it can be subtle though... eh.
06:50:56<sjanssen>MyCatVerbs: lazy evaluation actually does guarantee that
06:51:12<sjanssen>MyCatVerbs: I think you mean "non-strict"
06:51:47<Gracenotes>bombshelter13_: so even though the calculation is in memory, nothing happens (in theory) until the first element of the list is retrieved
06:52:10<Gracenotes>it finds the first value for which the filter condition is true, and then maps it, and gives you that
06:52:15<MyCatVerbs>sjanssen: what? Lazy evaluation does *not* guarantee that (map f . filter g) are merged into one pass!
06:52:18<Gracenotes>and the same for the next element, and so on, until you reach the end of the list
06:52:26<Gracenotes>again, in theory.
06:52:29<Gracenotes>:)
06:52:44<sjanssen>MyCatVerbs: it does
06:52:46<povman>I have a feeling there's a GHC rewrite rule which handles that
06:52:55<Twey>Yep
06:52:56<Gracenotes>the entire list may be deforested away, after all, and yes, rewrite rules
06:52:58<sjanssen>there is, but that's even more specific than one pass
06:53:10<MyCatVerbs>sjanssen: no it doesn't. You get no guarantee whatsoever that you don't get an intermediate list consed up in between the filter and map.
06:53:31<Cale>MyCatVerbs: But you do get a guarantee that the elements of that list are immediate garbage.
06:53:35<bombshelter13_>yeah, I'm aware that that's the general behaviour I just for some reason figured that, once the value of the filter call was needed by map, the entire filter would be evaluated. but that doesn't make sense now that i think about it... after all, to map f on to the first element of the result of filtering l by g, you only really need to filter enough of l to get one element :)
06:54:02<sjanssen>MyCatVerbs: there will be an intermediate cons cell between the map and filter, but only one will ever be in memory at a time
06:54:05<Cale>MyCatVerbs: That is, at no point in time will any more than one element of that list be held.
06:54:20<MyCatVerbs>Cale: yes. Hence the deforestation is possible. Not by any stretch of the imagination required, though.
06:54:40<Cale>MyCatVerbs: But that's already much better than strict evaluation!
06:55:06<MyCatVerbs>Cale: only asymptotically. ;)
06:55:07<sjanssen>MyCatVerbs: deforestation is a step beyond achieving this in a single pass
06:55:20<Cale>Sure, you can go that extra step and remove even the one cons cell.
06:57:16<MyCatVerbs>sjanssen: right, yes. Serves me right for thinking like it was ML.
06:57:53<jekor>Is there a way to force import of a function from a module when the function is not exported by the module?
06:58:00<MyCatVerbs>No.
06:58:34<jekor>*sigh* Another library to modify...
07:01:14<bombshelter13_>Most of the info on the 'interfacing other languages' page on the wiki is about accessing other languages from a haskell program... where can I learn about the reverse?
07:01:53<sjanssen>bombshelter13_: the FFI addendum?
07:02:02<bombshelter13_>ACTION seeks that out.
07:03:22<Pingray>This? http://www.haskell.org/haskellwiki/FFI
07:07:25<Gracenotes>hm. how would on go about adding support for another language?
07:07:33<Gracenotes>hypothetically
07:07:38<Gracenotes>what needs to be done at a basic level?
07:09:04<povman>Gracenotes: What do you mean by another language?
07:09:19<sjanssen>the most practical thing would be to give that language an interface to C, and use the C FFI
07:09:41<wli>e.g. Mercury <-> C <-> Haskell
07:09:51<Gracenotes>essentially -- would it be possible to link into another language in the same way one could link into C?
07:10:16<Gracenotes>ACTION is aware of the blah-to-C-to-Haskell approach
07:10:26<Hunner>What is the difference between Int and Integer?
07:10:30<wli>No, you end up being stuck with C as an intermediate step to link, at least in Haskell. It's clearly possible in principle.
07:10:32<Gracenotes>like Smalltalk. or (for masochists) C++
07:10:43<povman>Hunner: Integer is unbounded
07:10:50<Gracenotes>we can link to assembly, right?
07:10:53<cinimod>Is there a cabal irc channel?
07:10:55<povman>Hunner: Int is a system integer
07:11:17<zakwilson>After manually upgrading GHC, how do I tell cabal to recompile the libraries I had installed on the previous version?
07:11:17<sjanssen>Gracenotes: given a C-like calling convention, sure
07:11:32<sjanssen>that's really the important issue
07:12:30<Gracenotes>hm. C is particularly convenient in this respect?
07:13:14<zakwilson>C is particularly common, therefore most FFIs are C FFIs.
07:13:23<sjanssen>it's the lingua franca
07:14:15<wli>If you're implementing the FFI yourself you can obviosly make a direct interface to other languages.
07:16:30<PetRat>http://www.mibbit.com/pb/OL3RJQ I'm getting this error in running example code from chapter 15 of RWH. Can someone tell me what GHC.Prim.Any refers to?
07:17:31<sjanssen>PetRat: can you paste the code?
07:19:05<mmorrow>mauke: ping
07:19:11<PetRat>http://www.mibbit.com/pb/HwFXX6 Okay pasted.
07:20:46<sjanssen>PetRat: do you get an error with "runSupply next [1 :: Int,2,3]"?
07:21:09<bombshelter13_>Hahah. Nice work PetRat, our devious plan is now complete! Now we can sick the copyright police on him for reproducing part of copyrighted work. Eeexcellent...
07:22:22<Gracenotes>-k
07:22:39<bombshelter13_>true
07:22:56<bombshelter13_>and i should have congratulated sjanssen for luring him into the trap.
07:23:10<bombshelter13_>it's late though, and i'm half asleep.
07:25:09<PetRat>ACTION should probably not expect a detailed answer at this time.
07:27:03<PetRat>sjannssen: here is similar error with that line: http://www.mibbit.com/pb/ywHVOG
07:28:37<sjanssen>hmm
07:29:26<sjanssen>PetRat: what does ghci tell you the types of next and runSupply are?
07:29:30<PetRat>In the online RWH, the comments for this section include someone having the same error. Maybe we are using a different version of ghc than the book's?
07:30:18<PetRat>sjanssen: http://www.mibbit.com/pb/tGsTpv
07:30:19<sjanssen>possibly, I'll try running it
07:31:39<sjanssen>I get wrong results for both GHC 6.8.2 and GHC 6.10.1
07:32:44<PetRat>I pasted info about GHC.Prim.Any from the docs: http://www.mibbit.com/pb/8Rih1F
07:32:55<sjanssen>PetRat: give next an explicit type signature: next :: Supply a (Maybe a)
07:33:02<PetRat>I think I'm running GHC 6.8.2
07:33:16<sjanssen>PetRat: yeah, it's a GHC internal that shouldn't be popping up here. Some sort of funky GHC bug presumably
07:34:01<PetRat>Giving type signature for next fixed it. Thanks!
07:34:54<PetRat>By the way, don't know if you are familiar with this chapter of RWH (chapter 15) but I am having a hard time understanding. It seems to introduce confusing code with very little explanation. I know the book is already large, but this topic needs more said about it for beginners, I think.
07:35:46<sjanssen>PetRat: what's the topic?
07:35:56<acieroid>hi
07:37:01<acieroid>I can't understand the state monad, and I don't find many documentation about it
07:37:12<PetRat>Chapter 15 "Programming with Monads". Here is an outline of chapter 15: http://www.mibbit.com/pb/6OuZZP
07:37:41<PetRat>http://www.mibbit.com/pb/CxIzgR
07:38:49<Twey>PetRat: The chapter is designed to be compiled
07:39:09<Twey>If you don't want to compile it, you'll have to provide an explicit type signature to prevent GHCi from defaulting
07:40:01<PetRat>Sorry the format in the paste bin is screwed up. Anyway, chapter 15 introduces a few examples of programming with monads, including: using the Maybe monad to short-circuit a computation or provide default answer, MonadPlus, a monad that supplies random numbers, "adventures in hiding the plumbing" (encapsulation)
07:40:27<PetRat>Twey: I think my brain has to be a compiler to understand it.
07:42:36<sjanssen>ooh, it works when compiled
07:42:39<sjanssen>mysteries abound!
07:43:26<Twey>sjanssen: It's because GHCi defaults a to GHC.Prim.Any
07:44:01<sjanssen>Twey: not in general
07:44:10<sjanssen>and actually, it doesn't seem to be a ghci thing
07:44:17<voker57_>how to get size of a file?
07:44:36<MyCatVerbs>acieroid: hit up All About Monads.
07:45:00<Twey>voker57_: hFileSize
07:45:10<sjanssen>when "main = print . runSupply next $ [1, 2, 3]" is present in the file the type of next is correct, when that decl is not in the file a type involving Any is inferred
07:45:17<MyCatVerbs>acieroid: http://www.haskell.org/all_about_monads/html/statemonad.html <- fairly terse explanation of State.
07:45:39<solrize>it's worth trying to figure out how to write the state monad on your own
07:45:46<solrize>it really helped my understanding of monads when i did that
07:45:59<sjanssen>oh, the type isn't correct, it's filled in with Integer
07:46:11<sjanssen>I get it now, not a GHC bug
07:48:16<Saizan>it's the MR restriction
07:48:30<Saizan>s/restriction//
07:49:06<sjanssen>Saizan: I don't think it is, there are no class contraints
07:49:19<Saizan>MonadState
07:49:48<Saizan>though the instance is polymorphic in 's' so you don't get an "ambiguous type variable" error
07:49:55<sjanssen>then why does Any come in?
07:50:27<Saizan>because 's' is not generalized, but there's nothing constraining it, so it "defaults" to Any
07:50:37<acieroid>thanks MyCatVerbs
07:50:51<sjanssen>hmm, what would Haskell '98 do with this?
07:50:54<Saizan>s/constraining/unified with/
07:50:59<acieroid>I'm beginning to understand the thing
07:51:48<Saizan>good question
07:53:39<voker57_>@type hFileSize
07:53:40<lambdabot>Not in scope: `hFileSize'
07:55:35<wli>@type System.IO.hFileSize
07:55:36<lambdabot>GHC.IOBase.Handle -> IO Integer
07:58:33<voker57_>@type System.IO.fileSize
07:58:34<lambdabot>Not in scope: `System.IO.fileSize'
08:22:59<blueonyx>http://downforeveryoneorjustme.com/haskell.org :(
08:30:45<mm_freak>with the ByteString parser of parsec i'm often doing something like 'fmap B.pack . many1 $ satisfy …'
08:31:04<mm_freak>is there a special case many1, which returns a ByteString right away?
08:33:04<Twey>:t satisfy
08:33:05<lambdabot>Not in scope: `satisfy'
08:33:30<Twey>mm_freak: bs = (fmap B.pack .)?
08:33:37<mm_freak>satisfy takes a predicate and succeeds with a character, if it fulfills that predicate
08:33:53<mm_freak>hmm, good idea
08:34:45<mm_freak>but conciseness in notation is not my main concern
08:34:48<mm_freak>it's performance
08:35:39<neoswish>if i have some overlapping instances and more polymorphic type to return, is there some hack to define what instance to use by default, e.i. without explicit type signature? =)
08:35:45<Twey>Does Parsec return a string there?
08:36:04<mm_freak>in that case, yeah
08:36:13<Twey>Weird
08:36:21<mm_freak>nope, totally reasonable
08:36:48<Twey>Well you'd think it would return a generic Stream Char
08:36:57<mm_freak>'satisfy' returns a Char (with ByteString.Char8) and many1 applies a parser at least once, as often as it succeeds
08:37:13<mm_freak>it returns a list of all those results, i.e. a String
08:37:27<Twey>So it should be a Stream Char8
08:37:40<mm_freak>uhm, wait
08:37:59<mm_freak>nope
08:38:00<Saizan>i don't think Stream has methods for construction
08:38:01<mm_freak>many1 :: Stream s m t => ParsecT s u m a -> ParsecT s u m [a]
08:38:07<mm_freak>it doesn't
08:38:10<Saizan>attoparsec has this: takeWhile :: (Word8 -> Bool) -> Parser ByteString
08:38:20<mm_freak>Stream has only an uncons operation
08:38:44<mm_freak>Saizan: would you recommend attoparsec over parsec?
08:38:45<Saizan>consing for ByteString won't be efficient anyway
08:39:05<Twey>You're right, it seems to be monomorphic Char/[]
08:39:17<Saizan>mm_freak: if you want performance, then yes
08:39:20<Twey>Hmn
08:39:43<mm_freak>Saizan: yeah, i want just that
08:39:45<mm_freak>thanks =)
08:40:06<mm_freak>hmm
08:40:13<mm_freak>no haddock docs
08:40:21<mm_freak>no homepage
08:40:40<Saizan>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/attoparsec-0.5.1 <- there are for this version
08:41:06<Saizan>but it's best to build the latest locally
08:41:31<mm_freak>i wonder why nobody makes a decent arrow-based parser library
08:42:20<Saizan>"decent" is a bit vague :)
08:42:44<mm_freak>something that is useful in practical code and maintained
08:42:50<ivanm>mm_freak: because those who want it can't be bothered, the rest of us either don't want it or have NFI what an "arrow-based parser" is/looks like or why it would be useful
08:44:11<mm_freak>ivanm: i don't know how exactly arrows improve it, but as far as i know it improves performance in that it allows parsers to fail much earlier using less backtracking
08:44:26<ivanm>*nod*
08:44:31<mm_freak>so far i've used arrows only for fancy function encoding
08:44:37<ivanm>so you mean using arrows under the hood, rather than an arrows based interface?
08:44:38<ivanm>or both?
08:44:49<Saizan>interface
08:44:50<mm_freak>dunno
08:45:23<ivanm>since I've only ever used Arrows to apply functions to pairs... ;-)
08:45:32<mm_freak>the PArrows library uses arrows as interface
08:45:49<mm_freak>ditto
08:45:51<Saizan>the idea is basically to calculate the set of first characters each parser expects
08:45:54<Gracenotes>⋘_⋘
08:45:55<Gracenotes>⋙_⋙
08:46:21<Saizan>which can actually be done with monads too, with some difficulty
08:46:45<mm_freak>well, so far i haven't found a case, where that would improve anything, because i wouldn't ever match against multiple words in a parser
08:47:31<Saizan>no disjunction?
08:47:47<mm_freak>there are disjunctions, but they fail early
08:48:30<mm_freak>consider IRC… most disjunctions deal with leading ':'
08:48:39<mm_freak>like: if there is a leading ':', then…
08:49:32<Saizan>so you don't actually need it :)
08:50:08<mm_freak>i like the idea of explicit input types =)
08:51:25<mm_freak>though PArrows doesn't seem to expose a lot of this to the user
08:51:42<blueonyx>hi, does anyone know how to use Target from the GHC API like this "A target may be supplied with the actual text of the module."? i provide the text but GHC still searches for a file :/
08:53:08<mm_freak>it looks like PArrows doesn't use the input type at all
08:53:16<mm_freak>it just uses the arrow interface
08:54:02<Saizan>uh?
08:54:17<Saizan>it's the user that's supposed to use the input type
08:54:47<mm_freak>nope, the user uses 'runParser', where the input type is fully polymorphic
08:54:57<mm_freak>the user passes a String to runParser
08:55:28<Saizan>i meant in building its expressions
08:55:44<mm_freak>ditto… the input type is fully polymorphic everywhere
08:55:56<Saizan>yeah, but you need to use it to combine the arrows
08:56:01<Saizan>and build your result
08:56:23<mm_freak>but what would you pass as input?
08:56:42<mm_freak>the actual 'input' comes with runParser as a String already
08:57:37<Saizan>i mean, like in "digit &&& digit >>> arr (uncurry (*))"
08:58:24<Saizan>you wont' pass anything to digit, true, but you need to instantiate the input type for "arr (uncurry (*))"
08:59:27<mm_freak>oh, indeed
08:59:28<Saizan>it'll feel very much like using an Applicative in most cases
08:59:39<Saizan>but you've a little more expressivity
09:01:03<Saizan>uhm, actually
09:03:10<Saizan>maybe if no combinator makes use of the input type you could just stick to applicative and not lose anything
09:05:35<mm_freak>yeah
09:06:06<mm_freak>i just forgot custom parsers
09:06:14<mm_freak>like your arr (uncurry (*))
09:07:02<Saizan>yeah, but those built with arr can just be converted in equivalent fmap
09:07:28<acieroid>is there a specific way to remove a value from an alist ?
09:07:37<acieroid>or do I have to write it ?
09:08:22<Saizan>maybe filter applies?
09:09:36<acieroid>oh right
09:11:57<mm_freak>if not filter, there is delete
09:12:03<mm_freak>but usually filter is better
09:13:04<Saizan>oh, i always forget about delete
09:14:04<Twey>delete = filter . not?
09:14:07<Twey>@src delete
09:14:08<lambdabot>delete = deleteBy (==)
09:14:11<Twey>@src deleteBy
09:14:12<lambdabot>deleteBy eq x [] = []
09:14:12<lambdabot>deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys
09:14:42<Gracenotes>delete is delete-once
09:14:43<Twey>Why isn't delete = filter $ not (==)?
09:14:50<Twey>Oh, right
09:14:52<Gracenotes>not delete-every-single-instance
09:14:52<Twey>It only takes one
09:15:21<Gracenotes>at least this way, though, it won't make a bottom cons cell unless one already exists in the list
09:15:32<raptornv25>hi guys how to get "hello world" in haskell?
09:15:47<kaol>main = putStrLn "hello world"
09:18:36<njbartlett>Can anybody tell me where haddock docs end up after doing "cabal haddock" then "cabal install"
09:20:23<mm_freak>njbartlett: look in 'dist'
09:20:31<mm_freak>oh, after installing
09:21:15<njbartlett>mm_freak: Yeah, after installing. Looks like neither "cabal install" nor "runhaskell Setup.hs install" actually install the docs anywhere
09:21:27<njbartlett>So they can't be found when generating docs for dependent packages
09:21:28<mm_freak>seems like they end up in /usr/share/doc/ or similar
09:21:33<mm_freak>just like every other documentation
09:23:19<njbartlett>mm_freak: Well you get a directory under /usr/local/share, but it just contains licence.txt
09:23:31<Saizan>is there a way to exclude a certain value and/or type from heap profiling?
09:24:21<mm_freak>njbartlett: well, specify it: cabal configure --haddockdir=/foo/bar
09:24:26<Saizan>njbartlett: ghc-pkg field $pkg haddock-html
09:24:41<mm_freak>or --htmldir
09:27:16<njbartlett>Saizan: returns nothing
09:28:14<Saizan>njbartlett: even when using the name of your package in place of $pkg?
09:28:36<njbartlett>Saizan: Yes
09:29:13<Saizan>weird, i get a directory even for packages that don't have the haddocks installed
09:29:25<Saizan>which version of Cabal/ghc are you using?
09:29:49<njbartlett>Cabal 1.6.01, ghc 6.10.3
09:35:49<njbartlett_>Saizan: Sorry, I'm on an unreliable internet connection... will ask again later if I still can't sort it out
09:38:46<Saizan>njbartlett_: k, i've no idea what's wrong anyway
09:46:12<romildo>Hello.
09:46:43<romildo>I am going to implement a Tiger compiler in Haskell.
09:47:37<mm_freak>isn't there some nicer syntax for qualified importing?
09:48:43<mm_freak>i usually have some nicely sorted imports, but as soon as a qualified import gets in, it either makes everything ugly or i have to place it, e.g. at the top/bottom of the list
09:48:55<QtPlaty[HireMe]>romildo: Tiger?
09:50:37<ivanm>mm_freak: nicer? in what way?
09:50:54<ivanm>QtPlaty[HireMe]: if you make a mistake, it eats you
09:50:55<ivanm>;-)
09:52:27<trofi>[:
09:52:36<romildo>What would be a good representation of symbols? Appel, in his "Modern Compiler Implementation in SML" uses an imperative hash table to map strings to symbols, where a symbol is something like an "interned" string. It resembles the symbols from Lisp and Scheme. Appel represents them as a pair (name,key)::(String,Int), where key is a unique integer that can be used to quickly determine if two symbols are the same.
09:52:49<mm_freak>ivanm: it would suffice to be able to write 'qualified' _after_ the module name
09:53:13<ivanm>mm_freak: oh, you mean "as" implies "qualified"?
09:53:20<ivanm>that would make sense to me as well...
09:53:30<mm_freak>no, not really
09:53:30<ivanm>how many times do you import as an alias but don't qualify it?
09:53:35<ivanm>hmmm...
09:53:38<romildo>QtPlaty[HireMe], Tiger is a didatic programming language used in the series "Modern Compiler Implenation in [ML,Java,C]" by Andrew Appel.
09:53:43<mm_freak>just that i could write something like: import Control.Category qualified as C
09:54:07<mm_freak>sometimes i don't qualify
09:54:08<trofi>very high qualification
09:54:39<mm_freak>well, apparently there is no alternative =/
09:55:06<Saizan>romildo: i'd use a Map String Int
09:55:29<Saizan>or IntMap String, depending on which indexing you want..
09:57:24<Saizan>or maybe not, since this things will be runtime values for the generated programs, right?
09:57:39<Saizan>so, what are you compiling into?
09:57:44<roderyk>MissingPy has a (FromPyObject CDouble) ... how do I go about casting a haskell CDouble to Double?
09:58:02<Saizan>roderyk: fromIntegral
09:58:23<romildo>Saizan, the key should be the symbol name. When a symbol name is retrieved from the input program, it is looked in the map. If it is not found, a new symbol is created (with a new integer id) and inserted into the map. Otherwise the symbol found in the table is used.
09:58:44<roderyk>Saizan: hmm, ok.. thanks. I kind of assumed that was for Int, Integer...
10:01:17<romildo>Saizan, I am concentrating into the analisys phases now. I am not sure what will be the target. Most of the time there is not enough classes to cover the whole compiler, just the lexical, syntatic and semantic analisers.
10:01:37<romildo>Saizan, but I am thinking about using llvm as the backend.
10:03:05<joeally>hello
10:04:13<joeally>I am just learning haskell and thought trying to program the bubble sort algorithm
10:04:18<roderyk>Saizan: no instance (Integral CDouble)
10:04:31<joeally>but haskell being different i am stuck
10:04:41<Saizan>roderyk: oh, sorry, braino, realToFrac
10:04:51<Saizan>Double is not an Integral type
10:04:52<roderyk>Saizan: ok, that makes more sense :)
10:04:59<roderyk>Saizan: yea... ;)
10:05:04<roderyk>thanks :)
10:05:15<joeally>the best that i could come up with was "bubble (x:y:ys) = min x y:bubble (max x y:ys)"
10:05:30<joeally>but this only does the first pass of bubble sort
10:05:37<romildo>The Data.HashTable.HashTable type is implemented in the IO monad. Is there any non-monadiic implementation of hash tables in the Haskell standard library that would be more efficient than using a Data.Map.Map ?
10:05:45<joeally>is there anyway to apply a function to itself
10:06:34<joeally>anyone know how to apply a function to itself a specific amount of times
10:06:34<Lemmih>romildo: Data.Map is very fast.
10:06:35<Saizan>joeally: there's iterate
10:06:40<joeally>okay
10:06:53<joeally>i'll search it on google thankyou very much
10:07:07<Saizan>> iterate (*2) 0 !! 4
10:07:08<lambdabot> 0
10:07:11<Saizan>> iterate (*2) 1 !! 4
10:07:12<lambdabot> 16
10:07:20<romildo>So I think I will go with Data.Map to store the known symbols of my compiler.
10:07:37<monadic_kid>joeally: what you should try to do is break down you're specific cases and the most general one, then you can write this out as an equation in haskell with pattern matching function arguments
10:07:59<monadic_kid>joeally: like one of you're specific cases which is the empty list
10:08:00<joeally>i have tried
10:08:24<joeally>this is what i got
10:08:27<joeally>"bubbleI [] = []
10:08:27<joeally>bubbleI [x] = [x]
10:08:27<joeally>bubbleI (x:y:ys) = min x y:bubble (max x y:ys)"
10:08:38<joeally>but this is only one pas
10:09:10<joeally>i need to repeat this x times depending on length of list
10:09:28<joeally>thanks sazian
10:09:49<monadic_kid>joeally: make a recursive call to bubbleI, is bubble a different function from bubbleI?
10:09:51<joeally>Sazian: thnaks
10:11:39<joeally>yes
10:11:50<joeally>monadic_kid:
10:11:54<joeally>monadic_kid:yes
10:12:05<joeally>but i dont know what to put bubble as
10:15:45<mm_freak>i'm trying to implement a state arrow, but i'm running into a major problem: first a >>> second b wouldn't be equal to second b >>> first a
10:15:49<mm_freak>is this a problem?
10:16:00<Saizan>no, that's expected
10:16:10<mm_freak>ok, thanks
10:17:32<mm_freak>is a state arrow useful actually?
10:17:54<opqdonut>you mean the kleisli arrow of State?
10:18:06<mm_freak>dunno
10:18:24<mm_freak>i mean this: data AState s a b = AState { runState :: a -> s -> (b, s) }
10:18:39<opqdonut>?src Kleisli
10:18:40<lambdabot>Source not found. And you call yourself a Rocket Scientist!
10:18:55<mm_freak>i have no experience with kleisli arrows
10:19:06<mm_freak>i've read about them once, but never found a use for them
10:19:17<opqdonut>newtype Kleisli m a b = Kleisli (a -> m b)
10:19:18<opqdonut>basically
10:19:35<opqdonut>that's an arrow for any monad m
10:20:09<mm_freak>in fact, Kleisli (State s) a b seems equivalent to my AState
10:20:14<opqdonut>indeed.
10:20:38<mm_freak>well, is such an arrow useful?
10:21:03<opqdonut>well it's as useful as State
10:21:27<mm_freak>sure, i guess it could improve notation sometimes using proc/do
10:21:45<mm_freak>but i'm failing to find a concrete example
10:25:11<mm_freak>hmm
10:25:18<mm_freak>i guess it may be useful sometimes
10:25:48<mm_freak>like applying stateful computations to tuples
10:26:01<mm_freak>but notation is very tiring
10:26:10<mm_freak>> flip runState 3 . flip runKleisli (10,20) . first $ Kleisli (\x -> modify (+x))
10:26:11<lambdabot> (((),20),13)
10:26:52<Saizan>the wrapping/unwrapping is quite bad, yeah
10:27:17<mm_freak>yep… i guess, proc/do may improve it
10:28:59<Saizan>i never liked proc
10:31:46<mm_freak>i've never used it
10:31:55<mux>anyone running openbsd or netbsd and willing to provide me with a shell account so that I can have a haskell module work there?
10:33:08<cnwdup>Is it possible to create a function which takes a string and produces an n-ary result depending on the string? For instance foo "%%" should yield a binaryary function, foo "%a" should yield an unary function, and so on. Or does this violate Haskell's type system?
10:33:32<mm_freak>cnwdup: you need some magic for that
10:33:36<mm_freak>see Text.Printf
10:34:07<mm_freak>it's a type-safe haskell equivalent of the C printf function
10:34:21<mux>it's not type-safe
10:34:34<mm_freak>no? not statically i guess
10:34:36<cnwdup>And it's unflexible.
10:34:39<mux>it should be called unsafePrintf
10:35:11<mm_freak>cnwdup: it implements the idea nevertheless
10:36:07<cnwdup>Does it? It seems to be different to me. printf kind of creates the arity from the number of arguments and I'd like to create it from the first argument only.
10:36:21<mm_freak>it does
10:36:23<cnwdup>Where printf uses the type system to create a function I'd like to create a function whilst not violating the type system.
10:36:28<mm_freak>> printf "%i" 3
10:36:30<lambdabot> Add a type signature
10:36:34<mm_freak>> printf "%i-" 3 :: String
10:36:36<lambdabot> "3-"
10:36:39<mm_freak>> printf "%i-%i" 3 4 :: String
10:36:41<lambdabot> "3-4"
10:37:16<opqdonut>cnwdup: a type-safe printf is easy if the format is read from some sort of ADT and not a string
10:37:26<mux>yeah
10:37:28<mm_freak>yeah
10:37:36<Cale>Where the ADT is probably a GADT.
10:37:51<Cale>(but possibly not...)
10:37:53<mux>the "fun with type functions" implements it this way
10:37:53<cnwdup>Yeah, printf "fmt" creates a function of type PrintfType and then it matches printf type against the arguments. As 3 follows, PrintfType is PrintfArg -> PrintfType. As 4 follows, the resulting function is PrintfArg -> PrintfArg -> PrintfType. Then no argument follows and the type system infers PrintfArg -> PrintfArg -> String since String is an instance of PrintfType.
10:37:59<mux>*paper
10:38:34<cnwdup>I'd rather have this way: myPrint "fmt" should create a function of variable arity depending on the format argument no matter what the remaining arguments passed to the functions are.
10:39:27<cnwdup>(myPrint "fmt") and ((((myPrint "fmt") 1) 2) 3) should evaluate to the same function when evaluating only (myPrint "fmt").
10:40:08<Saizan>cnwdup: you can't if you use a String
10:40:10<cnwdup>opqdonut, I thought so, too. But I do not quite know how to realize that.
10:40:31<cnwdup>Saizan, what can I use?
10:40:33<monadic_kid>the way cnwdup is describing is exactly how format type works in ocaml and F#
10:41:27<joeally>Is this an efficient bubble sort algorithm:
10:41:30<joeally>bubbleI [] = []
10:41:30<joeally>bubbleI [x] = [x]
10:41:30<joeally>bubbleI (x:y:ys) = (min x y:bubbleI (max x y:ys))
10:41:30<joeally>bubble x = iterate bubbleI x !!(length x-1)
10:42:06<Saizan>cnwdup: a gadt, and there's an example in the paper here: http://haskell.org/haskellwiki/Simonpj/Talk:FunWithTypeFuns
10:42:17<Saizan>it's also possibile with delimited continuations
10:42:18<monadic_kid>in F# and Ocaml there is a special type constructor called format/Format where one of the type parameters is substituted by the compiler from the format string at compile-time
10:42:27<cnwdup>Saizan, thank you. (:
10:42:56<Saizan>as described here (and the linked code) http://www.mail-archive.com/haskell@haskell.org/msg20758.html
10:43:29<Saizan>monadic_kid: ah, yeah, i guess we'd do that with TH here
10:43:55<Saizan>to generate the gadt from the string
10:44:03<Tristan1>hello everyone
10:44:09<joeally>hello
10:44:40<Saizan>joeally: as efficient as bubblesort is :)
10:44:47<joeally>yaya
10:44:52<monadic_kid>as long as you can analyze strings at compile-time then it's all cool
10:44:58<Tristan1>if someone has a litte time, i need some help installing the base-4.1.0.0 package
10:45:02<joeally>thanks for pointing me to iterate
10:45:10<Saizan>joeally: though a common optimization is to stop if the last pass didn't swap any elements
10:45:32<joeally>okay thanks i may try and add that
10:45:54<Saizan>Tristan1: you can't upgrade the base package
10:45:58<joeally>I think implementing algorithms is the best way to learn a language
10:46:10<Saizan>Tristan1: if you need base-4.1 you must upgrade ghc
10:46:15<Tristan1>i did this
10:46:40<Tristan1>now cabal says: config.status: error: cannot find input file: include/HsBaseConfig.h.in
10:46:53<monadic_kid>this "fun with type funs" paper sounds awfully familiar (hint boost mpl)
10:46:53<Tristan1>and i don't know where to get this file
10:47:06<Tristan1>my ghc version is 6.10.1
10:47:48<Tristan1>(installed as user, $PATH is set correctly - ghc --version says 6.10.1)
10:48:04<Saizan>Tristan1: ghc-6.10.1 comes with base-4, you need at least ghc-6.10.2 if you want base-4.1
10:48:11<Tristan1>ok
10:48:17<Tristan1>this explains a lot
10:48:38<Tristan1>then i'm going to install 6.10.2
10:48:40<Tristan1>thx
10:48:47<mux>or 6.10.3 maybe?
10:48:55<mux>while you're at it :-)
10:49:06<Tristan1>what is the latest version ?
10:49:10<koeien>6.10.3 is
10:49:13<Tristan1>ok
10:49:22<Tristan1>thx again
10:49:28<koeien>although i haven't installed it yet, the difference appears to be minor
10:49:34<twb>How do I sort (then group) a list of tuples by the snd of each element?
10:49:42<koeien>:t sortBy
10:49:44<lambdabot>forall a. (a -> a -> Ordering) -> [a] -> [a]
10:49:45<monadic_kid>omg it's boost mpl all over again
10:49:46<twb>sortBy wants me to define the comparator, which sucks
10:49:52<koeien>:t on
10:49:53<lambdabot>forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
10:49:56<twb>Ah.
10:50:00<twb>I knew there was a trick to it
10:50:02<mux>6.10.3 just makes line editing work out of the box all the time because it doesn't depend on libedit/libreadline anymore
10:50:55<twb> ((<) `on` snd) ?
10:51:03<Saizan>compare on snd
10:51:06<koeien>> sortBy (compare `on` snd) [(0,1),(1,0)]
10:51:07<lambdabot> [(1,0),(0,1)]
10:51:09<mux>comparing snd
10:51:19<twb>mux: aha!
10:52:29<joeally>What is quicker the function min or checking using "<"
10:52:32<monadic_kid>fun with types funs is very similliar to type computations with C++ templates and mixing it up with other techniques like expression templates
10:52:41<koeien>joeally: min probably uses <
10:52:46<joeally>okay
10:52:49<joeally>so no difference
10:53:01<twb>Is there a better way to say: group $ sort xs ?
10:53:01<koeien>not a difference you'd notice
10:53:08<mux>joeally: except that your code calls min and max one time each
10:53:17<joeally>yes
10:53:35<joeally>so im thinking of checking if its smaller before calling min
10:53:38<joeally>or max
10:53:48<koeien>twb: not 100% sure, but i don't think so
10:54:31<monadic_kid>can you apply a type function to an unbounded sequence of types?
10:55:19<Saizan>you can represent sequences of types with tuples, like in HList
10:55:48<Saizan>(A,(B,(C,()))) <- cons cells at the type level
10:55:50<monadic_kid>okay so i guess you can define a fold type function then
10:56:26<Saizan>can you pass a type function as parameter to another?
10:57:38<monadic_kid>Saizan: you can with templates, boost mpl defines a how framework for STL style type functions, they have method of lazy template instantion and parital application and sort of lambda functions
10:59:40<monadic_kid>boost::is_pod<> , is_pod is a type traits or you can view this as a type function predicate, with boost mpl if you do boost::is_pod<_1> becomes lambda function that takes one arg, you can pass this to higher-order type functions
11:00:45<monadic_kid>fold< type_seq, add<_1,_2>, size_t<0> >
11:00:54<roderyk>in gtk2hs, Model.TreeView: I can set a model via (treeViewSetModel view (treeStoreNew forest)) where forest is Data.Tree; but I need to later update this tree. When I call treeViewGetModel, I cannot get the old (treeStore Data.Tree) back. Instead, it wants to return the generic TreeModelClass
11:01:15<roderyk>TreeStore is an instance of TreeModelClass, but I can't seem to get it to cast back... any suggestions/ideas?
11:01:35<roderyk>(the gtk interface for TreeModel seems really over-engineered)
11:02:01<twb>@pl ((==) `on` snd)
11:02:01<lambdabot>(==) `on` snd
11:02:57<monadic_kid>i guess you would be able to do this with depedant types in haskell and type-classes fun deps, fold< list_c<1,2,3,4,5> , add<_1,_2>, size_t<0> >
11:03:50<joeally>is this bubbleI (x:y:ys)
11:03:50<joeally> | x <= y = x:bubbleI (y:ys)
11:03:50<joeally> | x > y = y:bubbleI (x:ys)
11:04:25<joeally>quicker than this : bubbleI (x:y:ys) = min x y:bubbleI (max x y:ys)
11:05:30<mux>joeally: you want this:
11:05:37<mux>bubbleI (x:y:ys)
11:05:47<mux> | x <= x = x:bubbleI (y:ys)
11:05:58<mux> | otherwise = y:bubbleI (x:ys)
11:06:03<joeally>okay
11:06:06<mux>this way you really do only one comparison
11:06:13<mux>otherwise is just an alias for True
11:06:17<joeally>fair enough
11:06:28<joeally>so that is the quickest way
11:06:45<mux>x <= x should x <= y of course, that was a typo
11:06:54<mux>joeally: well it is a way that only does one comparison :-)
11:07:11<joeally>thank you mux
11:07:17<mux>you're welcome
11:07:28<joeally>i have just learned something new
11:08:24<Twey>mux: Apparently otherwise has optimisation magic in GHC
11:08:43<joeally>ooh
11:08:44<koeien>i hope that 'True' has the same optimization magic
11:08:49<joeally>that makes it even bugger
11:08:50<mux>I really hope that too.
11:08:58<joeally>beter*
11:09:01<mux>if GHC ends up comparing True with True, that would suck :-)
11:09:15<koeien>GHC may do that compiletime :)
11:09:24<koeien>but runtime that should be optimized away
11:09:45<joeally>Fast bubble sort in 6 lines...better than python
11:10:10<joeally>i get the feeling haskell is better than python for mathmatical things
11:10:33<koeien>joeally: i confess that i use haskell mostly for math things, but i think it is also better for larger projects
11:10:41<koeien>because of static typing
11:10:50<joeally>yeah I suppose
11:11:15<joeally>Its just that python and ruby seem easier for things like web services and gui
11:11:16<koeien>but i also use haskell for scripting stuff ;)
11:12:17<joeally>saying that bubble sort in python is also 6 lines
11:12:36<joeally>but it is slower
11:12:42<koeien>python is slower
11:13:02<koeien>if you really need performance, it's not the best choice
11:13:25<joeally>yeah its syntax is really easy though
11:13:35<koeien>true.
11:13:36<joeally>and its very good for when your in linux
11:13:42<joeally>but i like haskell also
11:13:48<twb>What am I doing wrong here?
11:13:50<twb>> foldl1 ((+) `on` fst) $ zip [1..3] ['a'..'c']
11:13:51<lambdabot> Occurs check: cannot construct the infinite type: a = (a, b)
11:13:51<lambdabot> Exp...
11:13:54<joeally>its syntax seems more efficient
11:14:00<Berengal>> let bubble (x:y:ys) = if x <= y then x:bubble(y:ys) else y:bubble(x:ys); bubble l = l in bubble [1,5,3,4,6,8,3,4]
11:14:01<lambdabot> [1,3,4,5,6,3,4,8]
11:14:11<Berengal>> let bubble (x:y:ys) = if x <= y then x:bubble (bubble(y:ys)) else y:bubble (bubble(x:ys)); bubble l = l in bubble [1,5,3,4,6,8,3,4]
11:14:11<lambdabot> [1,3,3,4,4,5,6,8]
11:15:01<joeally>thanks berengal but i prefer pattern matching to control expressions in this case
11:15:02<koeien>:t ((+) `on` fst)
11:15:03<lambdabot>forall a b. (Num a) => (a, b) -> (a, b) -> a
11:15:06<koeien>:t foldl1
11:15:07<lambdabot>forall a. (a -> a -> a) -> [a] -> a
11:15:15<Berengal>joeally: I was just checking to see if it worked
11:15:20<joeally>oh
11:15:21<koeien>twb: you see that this is not a valid argument to foldl1
11:15:48<twb>koeien: I don't understand why.
11:16:03<koeien>the first argument should be of type c -> c -> c
11:16:09<twb>Is this just one of those annoying foibles of HM inference?
11:16:16<twb>Ah
11:16:24<koeien>while (a, b) -> (a, b) -> a cannot be unified with that
11:16:34<koeien>it complains that c = a = (a,b) cannot be unified
11:16:45<Jedai>twb: No, it's a genuine type error
11:17:52<twb>Is there a straightforward way to express what I want?
11:17:58<Jedai>twb: You want something like "foldl1 (+) . map fst"
11:18:02<mux>> foldl (\x y -> x + fst y) 0 $ zip [1..3] ['a'..'c']
11:18:03<lambdabot> 6
11:18:06<koeien>twb: foldl1 (+) $ map fst [...]
11:18:08<twb>Jedai: ew, since I'm using &&&
11:18:10<mux>if you really want a fold
11:18:19<mux>but sum . map fst is shorted :)
11:18:22<mux>shorter, rather
11:19:04<Jedai>twb: ??
11:19:10<twb>I have a list [(Int,a)] and I want to return a tuple (sum of ints, first a).
11:19:44<Berengal>(sum &&& head) . unzip?
11:19:52<koeien>> ((sum . map fst) &&& head) [(0,"Hello"), (1,"Why")]
11:19:53<twb>Hmm, unzip...
11:19:54<lambdabot> (1,(0,"Hello"))
11:19:59<Berengal>@type unzip
11:20:00<lambdabot>forall a b. [(a, b)] -> ([a], [b])
11:20:11<mux>twb: if the function you pass to foldl1 takes two pairs and returns an integer, what does foldl1 do after having fed your function with the first two pairs in your list?
11:20:18<koeien>unzip, far better
11:20:32<twb>(sum &&& head) . unzip, I think
11:20:44<mux>twb: it ends up with the rest of the list, and the sum of the integers of the two first pairs, and there's nothing it can do to go on
11:20:56<mux>twb: this is why your code can't possibly type check
11:21:34<Berengal>Sorry, should be sum *** head
11:21:48<koeien>i always mix those up.
11:21:57<Berengal>Yeah, me too...
11:22:08<koeien>although i should use them more
11:22:20<koeien>better than writing anon function for them
11:23:04<mux>> foldl1 (\(x,c) (y,_) -> (x+y,c)) $ zip [1..3] ['a'..'c']
11:23:06<lambdabot> (6,'a')
11:23:06<twb>Berengal: hlint can tell you when you should use them :-)
11:23:14<twb>Whee, it compiles again
11:23:18<mux>twb: see?
11:23:52<koeien>hlint! nice suggestion
11:24:06<mux>twb: this works because I still return a pair in the function passed to foldl1
11:25:17<mux>@pl \(x,c) (y,_) -> (x+y,c)
11:25:18<lambdabot>uncurry (flip flip snd . (ap .) . flip flip fst . (((.) . (const .)) .) . flip . ((,) .) . (+))
11:25:23<mux>heh.
11:26:46<koeien>i love lambdabot's pointless feature
11:28:54<Twey>It's terrifying
11:29:37<koeien>there should be a program that converts a haskell source code text, to a pointless one
11:30:01<Twey>Please gods no
11:30:05<ziman>@pl \a b c d -> a (b (c d))
11:30:06<lambdabot>(. (.)) . (.) . (.)
11:30:14<beelsebob>@pl \a b c d e f g h i j k l m n o p q r s t u v w x y z -> (a b a c z) (k q (r z) i (j 2 x) (p x q ((r z) (e x y)) z e f))
11:30:17<lambdabot>((const .) .) . ((((const .) .) .) .) . ((((const .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .)
11:30:17<lambdabot> .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .)
11:30:17<lambdabot>. ((((((((((const .) .) .) .) .) .) .) .) .) .) . flip flip ((flip (flip . (flip .) . (((.) .) .) . ((ap .) .) . (((ap .) .) .) . ((((ap .) .) .) .) . ((((((.) .) .) .) .) .) . (((((ap .) .) .) .) .)
11:30:17<lambdabot> . (. ($ 2)) . flip . (flip .) . ((flip .) .) . ((((.) .) .) .) . (((flip .) .) .) . flip (flip . (flip .) . ((flip .) .) . ((.) .))) .) . flip . (flip .) . ((flip .) .) . (((flip .) .) .) . ((((
11:30:20<lambdabot>flip .) .) .) .) . (((((flip .) .) .) .) .) . ap (flip . (flip .) . ((flip .) .) . (((flip .) .) .) . ((((flip .) .) .) .) . (((((flip .) .) .) .) .) . flip (flip . (flip .) . ((flip .) .) . (((flip
11:30:20<beelsebob>>.>
11:30:23<lambdabot>.) .) .) . ((((flip .) .) .) .) . (((((ap .) .) .) .) .) . flip (flip . ((.) .) . (ap .) . (((.) .) .) . (((.) .) .) . flip) . flip ((.) . (.) . flip)) id) id) . (flip .) . (((.) .) .) . (((.) .) .)
11:30:26<lambdabot>. (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . ((ap .) .) . ap flip id
11:30:29<lambdabot>optimization suspended, use @pl-resume to continue.
11:30:30<Twey>Hoooly crap
11:30:34<Twey>Lambda-spam
11:30:40<Twey>Someone fix that?
11:31:20<Twey>You see?
11:31:23<Twey>Terrifying.
11:33:43<Japsu>Yeah, you scared the whole channel to STFU.
11:36:39<beelsebob>lol
11:38:42<trofi>looks like lisp
11:43:18<voker57_>@pl-resume
11:43:24<lambdabot>((const .) .) . ((((const .) .) .) .) . ((((const .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .) .) .) . (((((((const .) .) .) .) .)
11:43:24<lambdabot> .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .) . ((((((((((const .) .) .) .) .) .) .) .) .) .)
11:43:24<lambdabot>. ((((((((((const .) .) .) .) .) .) .) .) .) .) . flip flip ((flip (flip . (flip .) . (((.) .) .) . ((ap .) .) . (((ap .) .) .) . ((((ap .) .) .) .) . ((((((.) .) .) .) .) .) . (((((ap .) .) .) .) .)
11:43:24<lambdabot> . (. ($ 2)) . flip . (flip .) . ((flip .) .) . ((((.) .) .) .) . (((flip .) .) .) . flip (flip . (flip .) . ((flip .) .) . ((.) .))) .) . flip . (flip .) . ((flip .) .) . (((flip .) .) .) . ((((
11:43:26<lambdabot>flip .) .) .) .) . (((((flip .) .) .) .) .) . join (flip . (flip .) . ((flip .) .) . (((flip .) .) .) . ((((flip .) .) .) .) . (((((flip .) .) .) .) .) . flip flip id . (flip .) . ((flip .) .) . (((
11:43:29<lambdabot>flip .) .) .) . ((((flip .) .) .) .) . (((((ap .) .) .) .) .) . flip (flip . ((.) .) . (ap .) . (((.) .) .) . (((.) .) .) . flip) . flip ((.) . (.) . flip))) . (flip .) . (((.) .) .) . (((.) .) .) .
11:43:32<lambdabot>(((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . (((.) .) .) . ((ap .) .) . ap flip id
11:43:35<lambdabot>optimization suspended, use @pl-resume to continue.
11:43:39<voker57_>cool
11:49:03<EvilTerran>voker57_, if you want to do that sort of thing, you can talk to lambdabot via private message
11:52:14<voker57_>EvilTerran: ok
11:52:22<burp_>lol
12:05:13<Stim_Jim>be my pupil. http://invaderjim.mybrute.com its a fun litle flash game.
12:07:43<Botje>hmm
12:07:52<Botje>i wonder if there is an abuse@mybrute.com
12:12:19<Natashaaaa>Enter text here...
12:12:46<Natashaaaa>hiii
12:12:49<Natashaaaa>:)
12:35:49<brian6>ghci in 6.10.3 is acting weird for me. like :t seq<enter> doesn't actually put a newline before the signature it prints.
12:36:28<brian6>so it ends up looking like :t seqseq :: ...
12:37:40<Botje>are you sure that's not a problem with your libeditline?
12:37:44<Raevel>i installed parsec 3, now everything is broken :-(
12:39:19<Botje>what kind of errors are you getting?
12:39:26<brian6>Botje: dunno for sure, but i got rid of my .editrc.
12:45:37<stulli>> foldl (\a b -> if b==',' then (a ++ [[]]) else (init a) ++ [(last a) ++ [b]]) [[]] "foo,bar,baz"
12:45:38<lambdabot> ["foo","bar","baz"]
12:45:47<stulli>is there a standard funcion for this?
12:46:46<juhp_>6.10.3 should be using haskline, no?
12:47:00<ivanm>juhp_: it does
12:47:02<juhp_>ACTION wonders if yhc would not benefit from cabal
12:47:04<stulli>like pythons split function
12:47:13<ivanm>stulli: see Data.Split IIRC
12:47:21<ivanm>juhp_: I think it does...
12:47:30<ivanm>cabal is meant to be compiler-agnostic IIRC
12:47:33<juhp_>oh?
12:47:43<juhp_>ivanm: I mean rather than scons :)
12:48:13<ivanm>juhp_: never heard of scons (except for appending an element on to the end of a "list")
12:48:16<ivanm>wait, that's snoc
12:48:25<juhp_>ivanm: :)
12:48:34<ivanm>@where scons
12:48:34<lambdabot>I know nothing about scons.
12:48:36<byorgey>stulli: see the 'split' package on Hackage, which provides Data.List.Split
12:48:42<juhp_>scons is a buildsystem (written in python)
12:48:42<ivanm>*shrug* mustn't be important then ;-)
12:48:50<ivanm>byorgey: ahhh, Data.List.Split, not Data.Split
12:48:54<juhp_>ivanm: nod
12:48:58<byorgey>yeah =)
12:49:00<juhp_>try google :)
12:49:11<ivanm>juhp_: you mean yhc using cabal to build yhc?
12:49:15<ivanm>that would probably be bad...
12:49:19<juhp_>ivanm: indeed
12:49:24<ivanm>you have bootstrapping issues then
12:49:36<juhp_>hmm maybe yeah
12:49:41<ivanm>with needing cabal installed to install the compiler to build cabal
12:49:45<stulli>byorgey: thanks, thats exactly what i was looking for
12:49:47<juhp_>on the other hand ghc uses cabal too
12:49:47<ivanm>even worse then ghc requiring ghc
12:49:52<ivanm>juhp_: does it?
12:49:56<juhp_>yes
12:50:03<juhp_>for most of it
12:50:04<ivanm>it _comes_ with cabal, but does it actually use cabal to build?
12:50:15<juhp_>not all of course
12:50:15<ivanm>*shrug* didn't know that, thought it was all Make-based
12:50:21<juhp_>it is
12:50:28<guinea>newb question: how do I get cabal to install base-4. Apparently my installed version is base-3
12:50:39<ivanm>guinea: you need ghc-6.10.*
12:50:48<ivanm>so cabal-install can't install it for you ;-)
12:51:06<juhp_>which comes with base-4
12:51:07<ivanm>which lib/app do you want that needs base-4?
12:51:21<guinea>ivanm: aha! Is there a ubuntu package for that, or do I install it from a tgz?
12:51:26<guinea>ivanm: yi
12:51:30<ivanm>guinea: no idea
12:51:37<ivanm>check ubuntu ;-)
12:51:42<Berengal>guinea: No ubuntu package yet I'm afraid
12:51:48<juhp_>yeah I think yi require ghc-6.10.x
12:51:52<ivanm>Berengal: really? what's taking so long?
12:51:56<ivanm>even fedora has it! :p
12:52:02<juhp_>hehe
12:52:07<Berengal>ivanm: I know, right!
12:52:12<koeien>debian sid has it, i believe
12:52:12<juhp_>what's that supposed to mean ;P
12:52:15<ivanm>ACTION uses fedora at work, though no official haskell stuff is involved...
12:52:19<koeien>so ubuntu will probably have it in the next release
12:52:53<Berengal>By the next releast 6.12 will have/soon have come out anyway
12:52:54<guinea>Is there an apt-source I can add to my ubuntu?
12:53:14<koeien>Berengal: ETA for 6.12 ?
12:53:18<Berengal>guinea: No, you'll have to download the binaries from haskell.org and install it yourself
12:53:21<ivanm>Berengal: august, isn't it?
12:53:27<koeien>guinea: i would not recommend adding debian sid's repos
12:53:30<ivanm>koeien: august IIRC
12:53:33<koeien>ok
12:53:37<Berengal>koeien: Sometime after summer
12:53:38<koeien>ivanm: can't wait =)
12:53:43<ivanm>heh
12:53:52<ivanm>Berengal: but that's not until next year then! :(
12:53:53<Berengal>koeien: That's too bad, because you'll have to :P
12:54:01<koeien>guinea: download the binaries and installing it is easy.
12:54:02<ivanm>(hint: southern hemisphere)
12:54:03<juhp_>anyways yhc is not linking for me :-/
12:54:11<koeien>Berengal: :( :P
12:54:14<Berengal>ivanm: I didn't say which summer, did I?
12:54:18<ivanm>Berengal: heh
12:54:21<Berengal>Could be last year's...
12:54:30<ivanm>@slap Berengal
12:54:31<lambdabot>ACTION clobbers Berengal with an untyped language
12:55:16<juhp_>is there a schedule for 6.12?
12:55:48<juhp_>src/compiler/Front.o: In function `s1Vl_info':
12:55:48<juhp_>(.text+0x1ed4): undefined reference to `cpphszm1zi6_LanguageziPreprocessorziUnlit_unlit_closure'
12:55:50<juhp_>....
12:55:53<pejo>juhp, they roughly release major releases around ICFP
12:56:25<juhp_>aha
12:56:38<Berengal>pejo: Any reason why?
12:57:38<pejo>Berengal, don't know, but it's past submission deadlines for both ICFP and POPL.
12:57:52<ivanm>Berengal: why not?
12:58:29<Berengal>ivanm: That's not a reason why. That just means it's completely unreasonable ;)
12:58:46<ivanm>Berengal: as in, they have to have an annual date to base releases around
12:58:55<ivanm>so why not ICFP, which is at least remotely relevant/related
12:59:34<Berengal>ivanm: Yeah, but choosing an arbitrary date doesn't give that date a reason
12:59:41<Berengal>for being chosen, that is
12:59:54<Berengal>Or it wouldn't be arbitrary
12:59:57<ivanm>Berengal: I think pejo has hit it
13:00:11<ivanm>they can't do it before, because they're busy writing papers/talks/etc. for ICFP
13:01:14<Berengal>ivanm: Yeah, I was just arguing semantics with you. Sorry :
13:01:28<ivanm>heh
13:02:00<Berengal>ivanm: To be fair, "why not" was an open invitation to do so :P
13:02:28<ivanm>true
13:02:30<ivanm>;-)
13:02:56<kacper_>can yout tell me what is the diference by proving for example map( f.g ) = map f . map g for infinite and finite lists?
13:03:19<Berengal>kacper_: There is no difference
13:03:26<Berengal>Least not semantically
13:03:41<ivanm>kacper_: my guess is that you can "fully" prove it for finite lists
13:03:50<juhp_>ACTION wonders if anyone has had any luck building yhc recently
13:03:50<ivanm>whereas infinite lists require induction or something...
13:04:02<ivanm>juhp_: any particular reason for wanting to use yhc?
13:04:04<ivanm>@seen ndm
13:04:04<lambdabot>I haven't seen ndm.
13:04:13<QtPlaty[HireMe]>IIRC deforestation in part depends on your ability to do that.
13:04:20<ivanm>@uptime
13:04:21<lambdabot>uptime: 8h 21m 1s, longest uptime: 1m 10d 23h 44m 29s
13:04:24<juhp_>ivanm: well I was interested in playing the the js stuff
13:04:28<juhp_>with
13:04:40<ivanm>which probably hasn't been touched since it came out? :p
13:04:46<guinea>I was about to upgrade ubuntu, but I'm wondering if I should switch to another distro? I use xmonad anyway.
13:04:47<juhp_>hmm
13:04:48<pejo>QtPlaty, do what?
13:05:03<Berengal>guinea: If you feel up to it, try arch.
13:05:07<juhp_>guinea: fedora has xmonad now :)
13:05:07<EvilTerran>as i learnt it, in order to prove it for finite lists, you'd consider "map (f.g) [] =? (map f . map g) []" and "map (f.g) (x:xs) =? (map f . map g) (x:xs)"
13:05:16<ivanm>guinea: fedora seems to have fairly decent haskell support, if you want a hand-holdy distro
13:05:22<EvilTerran>and, for infinite lists, you'd consider "map (f.g) _|_ =? (map f . map g) _|_" as well
13:05:22<ivanm>or else there's gentoo and arch
13:05:41<dsouza>is xmod worthwhile? I'm currently a [happy] openbox user
13:05:47<kacper_>I have a exercise to provo some facts for infinite lists and prove that some of them are correct only for finite lists
13:05:48<dsouza>xmonad
13:05:49<koeien>debian/ubuntu is not the best for haskell support i guess. but otherwise i like debian better than other distros
13:05:54<Berengal>EvilTerran: finite lists can't be _|_?
13:06:08<RayNbow>hmm, is it possible to use cabal to install packages for all users on a system?
13:06:10<EvilTerran>because you can consider the infinite list [x0,x1 ..] to be the least upper bound of _|_, x0:_|_, x0:x1:_|_, ...
13:06:13<koeien>RayNbow: yes.
13:06:16<koeien>RayNbow: --global
13:06:26<RayNbow>ah, thx
13:06:34<koeien>(you must be root, of course)
13:06:41<pejo>kacper_, to prove that something is incorrect for infinite lists you can probably just look at the case for the infinite list.
13:06:54<juhp_>oh I see last yhc checkin is about a year ago... hmm
13:07:12<EvilTerran>Berengal, IIRC, considering _|_ covered the fact that you can't fully evaluate the tail of an infinite list
13:07:28<RayNbow>koeien: is it also possible to move packages installed for the root user only to the global configuration?
13:07:41<RayNbow>(or should I just take the delete/reinstall approach)
13:07:52<kacper_>yes I know that reverse( reverse xs ) is only correct for finite lists, but can I prove it from definition of reverse?
13:07:53<guinea>ivanm: I like hand holdy distros, because by default I'm lazy, and only want cutting edge for the things I care about, e.g. haskell, emacs, R, which I can install myself, and which have their own package managers
13:08:10<ivanm>emacs has its own package manager? :o
13:08:38<dv_>emacs is an OS
13:08:42<dv_>everybody knows this
13:08:55<koeien>RayNbow: not sure. the only reliable thing i know of is reinstalling
13:08:58<ivanm>dv_: not quite, it doesn't have a kernel yet
13:09:03<ivanm>I'm sure they're working on it though...
13:09:12<ivanm>(and no, I don't think it's Hurd)
13:09:13<dv_>I heard they are gonna call it "hurd"
13:09:13<koeien>it lacks a decent text editor...
13:09:14<dv_>:P
13:09:15<koeien>ACTION runs
13:09:25<guinea>ivanm: not quite, because they're not really packages
13:09:31<EvilTerran>kacper_, well, if you take "reverse = go [] where go xs (y:ys) = go (y:xs) ys; go xs [] = xs", for instance
13:10:22<ivanm>guinea: there are unofficial pkg managers though
13:10:32<EvilTerran>kacper_, then reverse [1..] = go [] [1..]; because [1..] is infinite, this will always go down the recursive branch of the definition of "go"
13:13:54<guinea>ivanm: yeah, and apparently it's in xemacs. I knew I remember seeing it. I didn't notice that gnuemacs lacked it until now, since I've been on ubuntu for a while and relied on apt for a lot of things.
13:14:25<kacper_>what is definition of go?
13:14:40<ivanm>guinea: I was referring to things like ELPA (if that's the right name)
13:14:46<Twey>14:09:31 < EvilTerran> kacper_, well, if you take "reverse = go [] where go xs (y:ys) = go (y:xs) ys; go xs [] = xs", for instance
13:15:02<ivanm>but yes, for small one-or-two-file .el things, I just do it by hand
13:16:59<juhp_>aha maybe I should play with HJScript instead
13:17:34<michael_>Hello. When I try this program with hugs > mydivide x y = div x y > mymult z = z + 3 and I type the command mydivide((mymult (3)), (mymult (4))) I get an "Cannot infer instance" error. Why is this?
13:17:36<guinea>ivanm: heh, I didn't even know about elpa, but somehow it doesn't surprise me.
13:17:43<ivanm>heh
13:17:54<kacper_>ok, I get it, just one question more, if I prove something for finite list by normal structural induction, what shoul I do to prove it for infinite lists
13:18:12<Twey>michael_: mydivide(x, y) means mydivide (x, y)
13:18:18<Twey>(x, y) is a tuple
13:18:24<Twey>div cannot be used on tuples
13:18:38<EvilTerran>michael_, "mydivide (mymult 3) (mymult 4)"
13:18:55<EvilTerran>michael_, although i'm not sure why you're calling "mymult" that
13:19:22<michael_>EvilTerran, yeh that was silly
13:19:33<michael_>Thanks Evil. That got it
13:20:01<EvilTerran>kacper_, take "map f . map g = map (f.g)", for instance; you can prove that holds regardless of whether the parameter is [], (x:xs), or _|_
13:20:34<EvilTerran>kacper_, because of the _|_ case and the (:) case, you know it works for x0:_|_, x0:x1:_|_, x0:x1:x2:_|_, ...
13:20:51<EvilTerran>kacper_, and hence it works for the limit of that series, the infinite list [x0, x1, x2, ...]
13:21:35<blueonyx>hi, how to use a GHC API Target "supplied with the actual text of the module."? i put the text into the targetContents but GHC panics because he cant find the module or file
13:22:40<kacper_>so what is denotation of map f _|_ ? is it _|_ ?
13:23:34<EvilTerran>kacper_, well, from looking at the definition of map
13:23:34<EvilTerran>?src map
13:23:34<lambdabot>map _ [] = []
13:23:34<lambdabot>map f (x:xs) = f x : map f xs
13:24:48<EvilTerran>kacper_, you can see it pattern-matches its second parameter, so, if that parameter is _|_, the whole expression's _|_
13:24:50<EvilTerran>ie, yes.
13:27:16<kacper_>x:xs pattern-matches _|_ ? so map f _|_ = f _|_ : map f _|_ or what?
13:27:27<yakov>hey
13:28:13<EvilTerran>kacper_, in order to see if the pattern "x:xs" matches an expression, the runtime has to evaluate the expression far enough to see what its outermost constructor is ([] or (:))
13:28:50<EvilTerran>kacper_, so, if the expression never evaluates that far (from either nontermination or throwing an error), the pattern never matches
13:29:22<EvilTerran>kacper_, so map f _|_ = _|_ directly
13:30:05<kacper_>and what with reverse [1..] ?
13:30:22<michael_>Why doesn't > mydivide :: (Double, Double) -> Double for function mydivide x y = x/y give a "Type error in explicitly typed binding"?
13:30:58<FunctorSalad>meh. I have multirec generating some enormous functor, and ghc eats my ram (4gb) and dies. How could I find the problem?
13:31:14<EvilTerran>kacper_, what property are you trying to prove or disprove about reverse?
13:31:18<michael_>* why does...
13:31:38<EvilTerran>michael_, because that should be "mydivide :: Double -> Double -> Double"
13:31:44<yakov>how can one put package on hackage if .cabal file is generated by configure script?
13:31:59<FunctorSalad>(btw multirec is pretty neat. it generates the functor describing your initial algebra, but it does this for a family of mutually recursive types...)
13:32:12<EvilTerran>michael_, "(Double, Double) -> Double" means "takes a tuple of two doubles and returns a double"
13:32:15<kacper_>i must show when inductions prove of reverse( reverse "infinite list" ) fails
13:32:21<FunctorSalad>*the functor for which your types are initial algebras
13:32:27<michael_>EvilTerran, but isn't that type for the curryfied version of mydivide?
13:32:37<EvilTerran>michael_, no, that's the uncurried version's type
13:32:45<EvilTerran>?type let f (x,y) = x/y in f
13:32:47<lambdabot>forall t. (Fractional t) => (t, t) -> t
13:32:49<EvilTerran>?type let f x y = x/y in f
13:32:51<lambdabot>forall a. (Fractional a) => a -> a -> a
13:33:11<EvilTerran>kacper_, so you're trying to disprove "reverse . reverse = id", then?
13:34:13<kacper_>induction base of [] is correct
13:34:39<EvilTerran>kacper_, that'd be easiest to do by counterexample; (reverse . reverse) (0 : _|_) = _|_
13:34:48<EvilTerran>(you can work that through to prove it)
13:35:25<EvilTerran>(and, of course, id (0 : _|_) = (0 : _|_) /= _|_)
13:35:59<kacper_>so the diference by prooving for finite and infinite is the _|_ ?
13:36:28<EvilTerran>reasoning about _|_ is one way of getting results for infinite lists, yes
13:36:40<FunctorSalad>(I guess I might be running into some high-complexity algorithm that doesn't matter for usual programs but does matter for the multirec-generated monster?)
13:37:26<EvilTerran>kacper_, Richard Bird's writings on equational reasoning in haskell may be relevant to you
13:37:49<kacper_>have you link for it?
13:39:15<FunctorSalad>hmm I turned -v4 on with ghc and now it doesn't run out of memory :) (but still working)
13:39:36<lars9>what kind of projects do you use haskell for?
13:39:58<koeien>FunctorSalad: all the messages will probably take some time :)
13:40:25<pejo>lars9, compilers!
13:40:27<EvilTerran>kacper_, well, there's a list of his work on http://www.comlab.ox.ac.uk/people/publications/date/Richard.Bird.html , although it doesn't seem to have (many, if any) actual papers
13:40:39<pejo>lars9, and pretty much everything else.
13:41:17<FunctorSalad>koeien: fortunately konsole deals well with huge outputs...
13:41:43<koeien>FunctorSalad: my money is on running out of memory eventually :)
13:41:44<FunctorSalad>(I don't think it acts on every putStrLn call)
13:41:50<EvilTerran>kacper_, you may be able to google up some of them; "The Algebra of Programming", "Mathematics of Program Construction", etc seem likely to go into this sort of thing in more detail
13:41:53<michael_>Isn't a text editor written in Haskell?
13:41:57<koeien>michael_: yi is
13:42:17<FunctorSalad>koeien: hmm I thought that the verbosity forces flushing of sume buffers that previously grew too fast ;)
13:42:23<michael_>lars9, then GUI projects!
13:42:28<FunctorSalad>(wild speculation)
13:42:34<koeien>FunctorSalad: can be ;) we'll see
13:42:38<kacper_>thanks a lot ;)
13:42:49<lars9>GUI projects?
13:43:03<michael_>lars9, look GUI up
13:43:09<michael_>lars9, look GUI up
13:43:30<michael_>lars9, and wxWidgets which i think has bindings for Haskell
13:43:46<koeien>wxWidgets has, yes, although Gtk2Hs is more popular i believe
13:43:50<FunctorSalad>koeien: well, stack overflow. previously it was "out of memory, requested x bytes"
13:43:54<lars9>oh, i'm using Xmonad which is in haskell
13:43:57<EvilTerran>we've got wxWidgets and GTK bindings
13:44:12<EvilTerran>(and cairo and opengl, for other graphicy stuff)
13:44:15<olsner>FunctorSalad: hmm, I don't think the line buffering is done by the rts though
13:44:39<FunctorSalad>olsner: I'm pretty sure konsole does this
13:44:41<koeien>FunctorSalad: you could try to increase stack space
13:44:45<koeien>+RTS ...
13:45:36<FunctorSalad>yeah, but somehow I doubt it will ever finish...
13:45:56<olsner>FunctorSalad: what are you doing btw?
13:46:20<olsner>and are you sure it actually terminates? :P
13:46:24<FunctorSalad>olsner: trying to run multirec on the types of haskell-src-exts o_O
13:47:34<FunctorSalad>thought it would be neat to navigate haskell source with a zipper :)
13:51:47<FunctorSalad>ok, now it did something...
13:53:47<olsner>now reading "Generic programming with fixed points for mutually recursive datatypes" :)
13:54:16<olsner>I should write a haskell paper title generator some day
13:56:19<cypher->olsner: there is a whole paper generator somewhere on the web
13:56:28<cypher->it even generates stuff that sounds vaguely sensible
13:56:36<cypher->(at first sight)
13:58:16<kyevan>I had a weird dream.
13:58:33<kyevan>Dr. Seuss wrote haskell handbooks.
13:58:45<kyevan>Also, lots of cakes were involved >_:>
13:59:46<olsner>@faq can haskell make you dream of cake?
13:59:47<lambdabot>The answer is: Yes! Haskell can do that.
14:00:13<EvilTerran>return :: Monad hat => cat -> hat cat
14:03:34<olsner>this is cool, fixed points for types... reminds me of that other paper that involved the derivatives of types - it used something similar for describing recursive types
14:04:09<EvilTerran>newtype Mu f = In { out :: f (Mu f) } kinda thing?
14:04:25<olsner>exactly
14:04:44<EvilTerran>ACTION is occasionally amused by Mu Endo
14:05:03<cypher->why is it mu?
14:05:45<kyevan>I read that as occasionally aroused.
14:06:00<kyevan>I need to get some coffee or something >_<
14:06:09<cypher->ah, as in u-recursive?
14:06:14<thomastc>kyevan: some *hot* coffee? :)
14:06:20<kyevan>*groan*
14:06:20<olsner>kyevan: unless amused is just a euphemism :P
14:06:43<cypher->ACTION was indoctrinated to call functions partial recursive rather than mu-recursive
14:06:58<olsner>in which case that would've been a freudian co-slip
14:07:52<thomastc>it's 16:07 in the morning here, I need some coffee too
14:09:37<DRMacIver>Stupid cabal question. I'm trying to use bang patterns in Slicer.hs, but am getting "illegal bang pattern, use -XBangPattern", but as far as I can tell my Cabal file is set up to use bang patterns.
14:09:42<DRMacIver>Cabal file is here: http://github.com/DRMacIver/slicer/blob/8fa061184c11c867cde603a4c7432236181a1903/slicer.cabal
14:10:23<Saizan>DRMacIver: you need it in the executable stanza too
14:10:33<EvilTerran>cypher-, as in the convention in a few situations of writing "mu x. f x" to mean "fixed point of f"; i guess that's related
14:10:46<DRMacIver>Ah, of course. Thanks
14:10:57<Saizan>mu = least fixed point, in many notations
14:11:31<EvilTerran>ACTION forgot the "least" bit, there <.< >.>
14:14:36<DRMacIver>Next stupid question: What's the best way to debug stack space overflows.
14:15:10<cypher->can someone recommend some good crash course on prolog?
14:15:22<olsner>run in debugger, break on error, look at the stack trace?
14:15:50<Twey>cypher-: http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/contents.html
14:16:08<cypher->Twey: thanks
14:16:17<DRMacIver>Hm. I've never actually used the Haskell debugger. Is there really not a simpler way to get a trace from a stack overflow?
14:16:47<Saizan>DRMacIver: compile with profiling support and run with -hc -xc
14:16:55<dsouza>\set
14:17:00<DRMacIver>Saizan: Thanks
14:17:17<dsouza>whoops, sorry
14:21:38<EvilTerran>ACTION hunts for an algorithm for syntactic unification of terms with quantifiers
14:24:20<EvilTerran>seeing as i can't quite even work out what the result of such a unification would be, i'm kinda stuck =/
14:24:55<EvilTerran>a most general unifier would be the obvious choice, but i'm not sure what happens with the bound variables
14:29:00<mmorrow>EvilTerran: look up the W algorithm
14:29:21<EvilTerran>ACTION does so
14:30:52<EvilTerran>mmorrow, ... am i right in thinking it's related to hindley-milner in some way?
14:30:55<mmorrow>("milner's W algorithm" mi
14:30:56<mmorrow>yes
14:31:08<mmorrow>..ght be a better search phrase)
14:32:09<Saizan>HM and W don't really unify terms with quantifies in them
14:32:23<mmorrow>W does sigma types
14:32:33<mmorrow>forall a1...an. t
14:32:52<Saizan>yes, but you don't apply unification to such a thing, afaik
14:33:02<mmorrow>oh, /unification/
14:33:17<mmorrow>well, W computes the mgt
14:33:35<cypher->me used to do unification on FOL but first skolemized the formulas
14:33:52<Saizan>right, but generalization and instantation gets dealt with externally
14:33:52<cypher->I'm not sure if that helps though
14:34:00<mmorrow>this looks like a nice quicky run-through http://www.google.com/url?sa=t&source=web&ct=res&cd=9&url=http%3A%2F%2Fuser.cs.tu-berlin.de%2F~magr%2Fpub%2FAlgorithmW.pdf&ei=jh8QSoTEC5GMNZG_4VI&rct=j&q=milner%27s+W+algorithm&usg=AFQjCNHtj1ObrsQnUTE5mHc3vuZ1hsbVDg
14:34:03<mmorrow>oops gah
14:34:22<mmorrow>user.cs.tu-berlin.de/~magr/pub/AlgorithmW.pdf
14:34:26<Saizan>you can see forall a. t as Forall (\a -> t), but then you've to deal with higher order unification
14:34:39<mmorrow>yeah, W is the vanilla of the vanilla
14:36:09<mmorrow>err, sorry i mean W compute the most general unifier
14:36:21<mmorrow>of type defined as:
14:36:24<EvilTerran>Saizan, well, if you stick to syntactic unification, you wouldn't have to worry about the equational properties of Forall, so it wouldn't be higher-order, surely?
14:36:43<mmorrow>data T = Prim | Var Int | Forall [Int] T
14:36:45<EvilTerran>pretend Forall is just another constant
14:36:51<Philippa>yeah, you basically don't need that at all for H-M
14:37:01<vixey>Int ?
14:37:02<Philippa>polytypes are just there to tell you whether it's been instantiated or not
14:37:15<mmorrow>vixey: "Name", "String", "Walrus", ...
14:37:16<mmorrow>:)
14:37:30<EvilTerran>so, for the purposes of unification, you'd only need to think about a single binding syntactic construct
14:38:14<Philippa>what's the actual problem?
14:38:39<mmorrow>the punchline of W (that i took away) was that you only deal with closed (w.r.t no free tyvars) types
14:38:59<mmorrow>close t = let vs = fvs t in Forall vs t
14:39:28<EvilTerran>Philippa, well, the problem i'm currently trying to solve is syntactic unification of terms in lambda-calculus + constants
14:40:00<EvilTerran>think "data Expr = VarE Var | ConstE Const | AppE Expr Expr | LambdaE Var Expr"
14:40:03<vixey>what's "forall" got to do with that?
14:40:08<Philippa>*nod*. No free tyvars, only free metavars which if you wrote out the constraint system explicitly would be existentially quantified
14:40:28<Philippa>EvilTerran: requires higher-order unification, can't quite be done
14:40:32<mmorrow>Philippa: exactly
14:40:43<Philippa>it's known to be undecidable
14:40:48<EvilTerran>vixey, nothing at all; hence, in this context, anything called Forall would be "just another constant"
14:40:53<EvilTerran>blah
14:41:03<thomastc>anyone here ever experienced lockups with darcs? mine hangs even after "darcs help" eating 100% cpu
14:41:03<vixey>Girard Heut encodes post problem in HOU
14:41:13<thomastc>I asked in #darcs but it's pretty quiet there
14:41:22<EvilTerran>even just syntactic unification's undecidable? that's unexpected =/
14:41:32<augustss>Gerard Huet?
14:42:08<EvilTerran>ACTION expected unification modulo the \-calc equational theory to be undecidable, but not syntactic unification
14:42:11<augustss>s/?/!/
14:42:11<Philippa>EvilTerran: syntactic has to respect bindings still
14:42:26<Philippa>so you have some of the theory tagging along for the ride
14:42:28<vixey>EvilTerran: wrt. beta reduction or not ?
14:42:58<mmorrow>EvilTerran: all it is is zipping two trees
14:43:07<Philippa>if you don't mind breaking bindings then it's just another algebraic type and it's decidable of course
14:43:25<EvilTerran>vixey, ignoring reduction and suchlike equivalences completely. lambdas just introduce a variable.
14:43:47<Philippa>EvilTerran: yep, without beta equivalence
14:43:58<EvilTerran>as in, i'd want to be able to unify (\x.x) with (\y.y), but not with (\x.(\y.y)x) or (\x.x)(\y.y)
14:43:59<Philippa>oh, wait... no, fair enough, that's a different problem
14:44:08<vixey>that's fine then, you can represent it in Prolog like \x -> x x as lam(X,app(X,X))
14:44:29<vixey>if you throw beta reduction in the mix this lam(X,...) rep. screws up though
14:44:38<Philippa>EvilTerran: just up to variable renaming?
14:44:57<Philippa>if so, name each variable uniquely and then just do dumb unification
14:45:03<vixey>lam(X,X) = lam(Y,Y) ~~> X = Y
14:45:40<EvilTerran>ACTION realises he doesn't really know what he's trying to do
14:46:01<vixey>yeah like Philippa says, \x -> x (\x -> x) should be lam(X,app(X,lam(Y,Y)))
14:46:51<augustss>So then it's not really higher order unification
14:47:02<EvilTerran>thanks for the insight, guys. now to think for a bit longer about what i actually want. :S
14:47:11<vixey>what is the application of this ?
14:47:36<EvilTerran>well, in theory, it was to be for use in a proof assistant
14:47:51<vixey>some kind of a type theory based on?
14:47:55<vixey>one*
14:48:14<vixey>btw I think HOU isn't undecidable
14:49:03<EvilTerran>i figured, given variable binding, application, and constants, you could define arbitrary theories to reason in by adding appropriate constants and refinement rules
14:49:27<vixey>it sounds like you're iventing LF :p
14:49:28<Philippa>vixey: it is. HTH HAND. Same problem as inference for System F. Adding annotations makes it different
14:49:42<vixey>Philippa: pretty sure there's a semi-decision algorithm actually
14:49:47<EvilTerran>LF?
14:49:48<vixey>always suceeds if there is a unifier
14:49:50<Philippa>which isn't decision
14:50:12<vixey>logical framwork, like Twelf and stuff
14:50:29<Philippa>I mean, if you can check is-unifier, then there's a semi-decision algorithm: enumerate all terms...
14:50:41<vixey>in practice semi-decidable is a lot different to undecidable
14:51:09<DRMacIver>Hm. No, I can't figure out how to get useful information about stack overflows from either of the debugger orC[C[C[C[C +RTS -xc. The only noticable difference with -xc is that I get a pretty <><><> before the stack space overflow error.
14:52:02<EvilTerran>vixey, it looks like that might be closely related to what i was trying to do. ah well.
14:52:53<EvilTerran>i'm an undergrad, it's going to be at least a couple of years before i'm well-enough read in the field to come up with things that haven't already been invented
14:53:32<DRMacIver>And the debugger output is http://pastebin.com/m5ddf183b which I can't seem to make sense of
14:57:11<Saizan>DRMacIver: you should run the expression under :trace
14:57:16<Saizan>to get any history
14:57:18<DRMacIver>Oh, right.
14:57:19<DRMacIver>Thanks
14:57:46<Saizan>and, when compiling for profiling you should add -auto-all -caf-all
15:18:22<DRMacIver>I don't suppose anyone wants to take pity on me and help me find this error? :) I'm drawing a total blank here, probably mostly through unfamiliarity with the tools (it's been a while since I've written Haskell, and most of my debugging attempts previously were fortunately quite easy to pin point)
15:18:52<DRMacIver>Code is at http://github.com/DRMacIver/slicer/tree/master . It stack overflows on either feeding it a large input file or calling "slice defaults [1..1000000]"
15:19:00<DRMacIver>I can't figure out where the stack overflow is coming from though
15:20:55<olsner>> minimum [1..1000000]
15:20:57<lambdabot> * Exception: stack overflow
15:21:41<DRMacIver>the list I'm calling minimum on should only have four elements
15:22:03<DRMacIver>Oh. But the list I'm calling sum on isn't.
15:22:21<MyCatVerbs>sum is defined as foldl (+) for some insane reason.
15:22:38<MyCatVerbs>You want to import Data.List, and use foldl' (+).
15:23:52<DRMacIver>Yeah. I knew that, it just failed to occur to me when I wrote that and I hadn't spotted it in the code.
15:24:03<Saizan>for Int/Integer there are rules to rewrite it to foldl'
15:24:17<Axman6>> minimum [minBound .. maxBound] :: Int32
15:24:34<DRMacIver>Saizan: Oh. Hm. Then I guess that isn't it.
15:24:44<DRMacIver>And indeed specialising it manually didn't fix the problem
15:24:44<MyCatVerbs>Also, (sum x) / (length x) is not a fantastic way to calculate a mean.mmm
15:24:54<byorgey_>DRMacIver: are you compiling with -O2?
15:25:07<DRMacIver>byorgey_: At the moment, no, but the problem doesn't go away when I do.
15:25:10<lambdabot> thread killed
15:25:53<DRMacIver>MyCatVerbs: Not fantastic in which way? Numeric stability or GCing the head of the list issues?
15:25:54<Axman6>> minimum [minBound .. maxBound] :: Int16
15:25:58<lambdabot> -32768
15:26:51<pejo>MyCatVerbs, what you see in @src is not what GHC necessarily uses.
15:26:53<DRMacIver>For the latter it needs the whole list in memory anyway, for the former... well, consider me lazy. I didn't think it was that big a deal and there wasn't a correct implementation readily to hand. :)
15:27:15<MyCatVerbs>DRMacIver: the latter. Maybe the former too if the elements are floating point numbers but it's really difficult to observe that. ;p
15:27:54<DRMacIver>MyCatVerbs: That's not such a big deal here. I basically have to hold the whole list in memory anyway (this isn't technically true, but I have to hold equivalently large things in memory)
15:28:57<DRMacIver>ok. So this doesn't seem to be minimum or sum. I replaced sum with a strict tail recursive version and it blows up in exactly the same way, and the minimum is definitely only being called on a list of 4 elements
15:31:11<MyCatVerbs>DRMacIver: sample input data?
15:33:09<DRMacIver>MyCatVerbs: Almost any big line separated list of integers will work. Hold on though, I'll commit the data I'm running on.
15:33:33<EvilTerran>ACTION 's brain shorts out and shuts down
15:35:29<DRMacIver>Hm. I won't commit it actually, as it's 5M and I don't really want it in source. Will upload it to my webserver. One second
15:35:48<DRMacIver>(And it doesn't seem to stack overflow on anything much smaller than that)
15:36:16<MyCatVerbs>DRMacIver: er, hang on, I can do it with a big old randomR output anyway, no?
15:36:22<DRMacIver>MyCatVerbs: Yeah
15:36:36<DRMacIver>MyCatVerbs: http://www.drmaciver.com/sampledata for what it's worth, but random data should work just as well
15:37:44<olsner>slice defaults [1..10000000] also reproduces the stack overflow pretty quickly
15:37:49<DRMacIver>Yeah
15:38:18<duaneb>@src defauls
15:38:18<lambdabot>Source not found. Have you considered trying to match wits with a rutabaga?
15:38:19<duaneb>@src defaults
15:38:19<lambdabot>Source not found.
15:38:54<duaneb>@src slice
15:38:54<lambdabot>Source not found. You speak an infinite deal of nothing
15:38:55<duaneb> :/
15:39:12<DRMacIver>duaneb: defaults and slice are from the code I posted. :)
15:39:31<DRMacIver>I don't think lambdabot indexes github
15:40:10<EvilTerran>ACTION thinks it'd be cool if hpastes generated modules visible to lambdabot
15:40:37<duaneb>ahh
15:40:38<duaneb>heh
15:40:41<duaneb>it should, I think
15:41:17<EvilTerran>"?type HPaste4920.done" kinda thing
15:41:54<Berengal>That would be nifty...
15:43:19<EvilTerran>that way, you could hpaste a relatively long function definition, and then demo it realtime via lambdabot
15:43:22<MyCatVerbs>DRMacIver: I just ran it over ~8k random integers and got an answer in four seconds' CPU time. :|
15:43:39<olsner>DRMacIver: I got a stack overflow in sum', but changing that to foldl' seems to move the stack overflow somewhere else
15:45:31<DRMacIver>olsner: Oh, hm. Embarrassing that I screwed up sum'.
15:46:26<DRMacIver>olsner: sum' was added in in the course of debugging, so assuming ghc does the right thing for sums of lists of ints (someone mentioned it did) it's not surprising there are still stack overflows
15:46:35<EvilTerran>ACTION ponders some way of structuring a recursive function so the strictness could be specified after the fact
15:47:17<DRMacIver>Out of curiousity, why is the sum' I wrote not tail recursive?
15:48:21<DRMacIver>Oh, interesting. genericLength isn't tail recursive either
15:49:34<EvilTerran>"sumS :: Num n => (forall a b. a -> b -> b) -> [n] -> n; sumS strictness = go 0 where go t [] = t; go t (x:xs) = t `strictness` go (t+x) xs" kinda thing
15:50:47<EvilTerran>with "strictly = seq; lazily = flip const", say, so you'd get "sumS strictly" and "sumS lazily"
15:51:38<Berengal>EvilTerran: With foldl and foldl' we dont' have too big a need for that I think
15:51:55<DRMacIver>Huzzah. Problem goes away if I manually write a strict length and use that instead of genericLength
15:51:59<DRMacIver>Thanks everyone
15:52:30<EvilTerran>Berengal, eh, true; i might keep thinking about it, though, see if i can think of some novel trick like that that's potentially nicer than using foldl vs foldl'
15:53:05<DRMacIver>It doesn't even take too long to run on this data
15:53:06<neoswish>is it a good idea to use general class for all binary operators a -> b -> c ? then it will be possible to use them anywhere you like =)
15:53:54<DRMacIver>It doesn't even take too long to run on this data (longer than I'd like, but well within the bounds of "well that's just a matter of optimisation")
15:54:23<jlaire>I have very long lists of Int64s and need to remove duplicates; what's a good way to do this? to IntSet and back eats too much memory
15:54:30<EvilTerran>the bounds of "i need more research grant so i can buy a faster computer, honest" :P
15:55:11<MyCatVerbs>jlaire: sort them and then scan the list dropping adjacent identical elements.
15:55:38<jlaire>MyCatVerbs: ok thanks, I'll try that
15:57:02<DRMacIver>EvilTerran: I don't believe in throwing hardware at problems. :)
15:57:57<MyCatVerbs>DRMacIver: throwing problems at hardware is much more fun. :3
15:58:02<EvilTerran>DRMacIver, feel free to throw it at me instead, if you'd rather. i could use some new hardware. :P
15:59:30<DRMacIver>Not throwing hardware at problems isn't the same as not cheerfully making use of the best hardware I can get my hands on. ;)
16:00:51<DRMacIver>I wonder if it's worth putting this on hackage. It's really special purpose, so probably not.
16:05:05<qaz>OO took a mathematical discipline and turned it into biology. it is time we make it mathematics again. yay for functional programming!
16:05:39<Badger>ACTION silences qaz before he can spread his propaganda further
16:06:26<MyCatVerbs>DRMacIver: eh, if it's stable and useful to at least somebody... :)
16:06:49<MyCatVerbs>I mean, the more libraries there are on Hackage, the better it compares with CPAN for our propaganda efforts. ;3
16:09:01<olsner>hmm, why would nub . sort be more efficient than fromSet . toSet?
16:09:03<cypher->yeah, but if Hackage gets cluttered with marginally useful libraries it will hurt the propaganda more than help it
16:09:40<pao>is it all about monads tutorial still relevant? is it worthwhile to send the author notice about typos?
16:09:51<pao>s/it/the/
16:10:01<jlaire>sorting is even less space efficient, I'll try switching to arrays
16:10:29<MyCatVerbs>jlaire: if you're having trouble with space consumption, be sure to use unboxed arrays rather than boxed ones.
16:10:39<jlaire>MyCatVerbs: sure I will
16:10:52<MyCatVerbs>pao: well, it's still accurate, and it's a good explanation of how most of the standard ones work, so sure.
16:11:12<pao>MyCatVerbs: thanks
16:11:32<byorgey>qaz =)
16:12:04<byorgey>olsner: it isn't. not asymptotically, at least.
16:12:26<byorgey>although I could believe that it's more efficient for small lists.
16:12:52<byorgey>and if you're using nub anyway there's no reason to be using sort.
16:13:35<MyCatVerbs>pao: I'm thinking, nnnno, thank *you*. ;)
16:13:44<trofi>> nub [1,2,3,1,2,3]
16:13:45<DRMacIver>MyCatVerbs: Well, I'm not yet entirely sure it's either of those. But we'll see. :)
16:13:45<lambdabot> [1,2,3]
16:13:53<duaneb>@src nub
16:13:53<lambdabot>nub = nubBy (==)
16:13:57<duaneb>@src nubBy
16:13:58<lambdabot>nubBy eq [] = []
16:13:58<lambdabot>nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs)
16:14:18<trofi>@src eq
16:14:19<lambdabot>Source not found. Do you think like you type?
16:14:27<pao>MyCatVerbs: :-)
16:15:06<duaneb>ok
16:15:08<duaneb>wish me luck
16:15:13<duaneb>I'm going to the dark side: OCaml
16:16:02<byorgey>good luck duaneb!
16:16:28<byorgey>that's not the dark side, that's like the insufficiently light side
16:16:30<duaneb>thanks :)
16:16:33<duaneb>heh
16:16:35<byorgey>PHP is the dark side
16:17:09<Taejo>BrainFuck is the magenta side
16:18:37<duaneb>malbolge is the dark side.
16:19:59<Smorg>Does lambdabot require a particular implementation of brainfuck?
16:20:15<Smorg>I'm trying to get it going on gentoo - there seems to be quite a few dependencies missing
16:20:33<qaz>> eq 1 2
16:20:34<lambdabot> Not in scope: `eq'
16:20:47<qaz>> Data.Eq.eq 1 2
16:20:48<lambdabot> Not in scope: `Data.Eq.eq'
16:20:52<qaz>> Data.Bool.eq 1 2
16:20:53<lambdabot> Not in scope: `Data.Bool.eq'
16:25:05<hatds>are there any types in the standard libraries that come with their own pretty printers?
16:25:52<malouin>Does ghc make the linker work hard in general? I am seeing ld processes that are using >500 MB of ram.
16:28:14<duaneb>malouin: There's usually some magnitude greater code (and symbols to link) generated by ghc
16:29:08<malouin>duaneb: ok, that makes sense.
16:29:32<wli>It does so far more often than e.g. C/C++ compilers. In general, not horrendously so.
16:31:28<ehird>"Haskell monads are like blog analogies about Haskell monads" —http://www.reddit.com/r/programming/comments/8kpgj/i_have_decided_to_learn_haskell_what_books/c09lood
16:33:47<malouin>is there a way to get ghc to invoke ld with --no-keep-memory?
16:34:22<hatds>you can pass flags to linkers by passing a flag to ghc
16:34:26<Igloo>-optl--no-keep-memory
16:34:43<hatds>that :)
16:35:36<malouin>thanks
16:41:32<burp_>how can I create such a http://hackage.haskell.org/packages/archive/numeric-prelude/0.1/doc/html/MathObj-Matrix.html matrix?
16:42:10<skorpan>burp_: probably using fromList
16:42:24<burp_>uh right
16:42:32<burp_>I just overlooked that
16:43:04<burp_>thanks :)
16:43:07<skorpan>np!
16:43:32<skorpan>anyone good with alex here? i'm trying to write a regular expression using alex's regexp syntax to match multiline comments, C style, i.e. /* .. */
16:46:05<duaneb>there needs to be an article "ocaml for haskell users"
16:47:03<jnaimard>the worst is the syntax
16:49:53<monadic_kid>duaneb: i dont see the point when you just look at the language spec
16:50:21<duaneb>monadic_kid: I need to use it for work
16:50:39<monadic_kid>duaneb: how does that change anything?
16:50:45<duaneb>monadic_kid: oh, I see
16:50:48<duaneb>the point of the article?
16:51:03<duaneb>because I don't want to read a spec
16:51:12<monadic_kid>duaneb: you don't have to read it all
16:52:20<monadic_kid>duaneb: i'm sure you can find a cheetsheet somewhere anyways
16:58:02<malouin>so is there any way to specify something like -optl to ghc that would always have affect? My other option seems to be to figure out how to get cabal to always tell ghc to pass these linker options.
16:58:39<Raevel>the latter: put GHC-Options: -optl under the library section of your .cabal
16:58:58<malouin>Raevel: ok, that seems good.
17:02:10<Philonous>If I had an IO action that yields a result and I wanted to execute this action once and for all subsequent calls to it return the memoized result, how would I do that?
17:03:59<Philonous>Or rather: I generate those actions on the fly.
17:04:26<malouin>Raevel: is that a cabal thing, or a cabal-install thing?
17:04:33<Heffalump>Philonous: are you generating it in IO?
17:04:43<Philonous>Yes
17:04:47<Heffalump>if so, construct an IORef (Maybe result) at the same time and store the result in that
17:04:49<malouin>Raevel: whoops nevermind, I found it.
17:05:33<Heffalump>so you can make something like IO (IO result), where the outer IO constructs the IORef, and the inner IO does the actual caching using the IORef.
17:06:23<Philonous>fair enough
17:15:44<ehird>Cale: your efforts were for naught; it seems that grauenwolf is just repeating his same example
17:15:54<Philonous>Is it sensible to put an IO function (a -> IO b) in unsaferPerfomIO and then use memocombinators on it? (that action would of course be referentially transparent)
17:18:36<hatds>if it is referentially transparent couldn't you use ST?
17:19:09<MoxJet>Is there a function that takes a Double and returns its IEEE representation?
17:19:48<Philonous>It reads data from files (that should not change during program execution, if they do I get all sorts of different problems)
17:20:15<ehird>Philonous: Shouldn't, but you cannot guarantee that.
17:25:16<Heffalump>MoxJet: there's no trivial and portable one
17:25:32<Heffalump>there's an unportable thing you can do with GHC involving unsafeCoerce on the unboxed representation
17:26:08<Heffalump>or you can write the portable one by hand using decodeFloat
17:26:36<codolio>You'd probably need a couple other functions, too.
17:26:45<dolio>Like isNaN.
17:27:12<dolio>Unless you want to figure out what decodeFloat turns NaN into, and check for that specifically.
17:27:19<dolio>> decodeFloat (0/0)
17:27:21<lambdabot> (-6755399441055744,972)
17:27:27<dolio>> decodeFloat (0/0 :: Double)
17:27:29<lambdabot> (-6755399441055744,972)
17:27:37<dolio>Huh, I thought it was worse than that.
17:27:44<dolio>> decodeFloat (1/0 :: Double)
17:27:44<duaneb>anyone else use haskell on TextMate?
17:27:45<lambdabot> (4503599627370496,972)
17:27:52<duaneb>the haskell support is pretty horrendous :P
17:28:45<hatds>how do you use the pretty printer library to pretty print a tree-like structure?
17:29:05<MoxJet>Heffalump: thanks :)
17:29:25<hatds>"nest" doesn't seem to move things to the next line
17:30:36<hatds>ah wait
17:31:06<hatds>how do you get ghci to show a string and convert newlines instead of printing "\n"?
17:31:35<dolio>> decodeFloat 1e-100
17:31:37<lambdabot> (7880401239278896,-385)
17:31:58<MoxJet>hatds: use putStr
17:32:40<hatds>MoxJet: thanks
17:32:40<qaz>hmm playing around with Erlang. Haskell really is a lot more complex and seems neater event hough it has a much higher learning curve
17:32:48<qaz>but Erlang has a nice platform in OTP
17:35:26<tetha>erlang certainly is interesting
17:40:35<cayennext>Hi! I am in the middle of my excercise from college, and I am trying to generate a sequence and having some troubles with it. Could you help? I am writing generator which takes a number and a list of lists of numbers and returns a list with so many different numbers as a number in param says and number on i'th position should be one of numbers from param list on i'th place.
17:40:46<cayennext>generate :: Int -> [[Int]] -> [[Int]]
17:40:46<cayennext>generate _ [] = [[]]
17:40:46<cayennext>generate diff (x:xs) = [ choosen:generate diff xs | choosen <- x]
17:41:02<cayennext>I come up with this, but it doesn't work, type error
17:42:39<duaneb>> let birthday d n = 1 - (foldr (\x a -> a * (1 - ((fromIntegral x) / d))) 1.0 [1..(n-1)]) in map (birthday 365) [1..35]
17:42:41<lambdabot> [0.0,2.739726027397249e-3,8.204165884781345e-3,1.6355912466550215e-2,2.7135...
17:42:42<dolio>x :: [Int], so choosen :: Int, but generate diff xs :: [[Int]].
17:42:54<dolio>And trying to prepend an Int onto an [[Int]] is a type error.
17:43:38<duaneb>> let birthday d n = 1 - (foldr (\x a -> a * (1 - ((fromIntegral x) / d))) 1.0 [1..(n-1)]) in map (birthday 365) [20..30]
17:43:39<lambdabot> [0.41143838358058005,0.44368833516520567,0.47569530766254997,0.507297234323...
17:43:42<dolio>Also note that you're always choosing elements from the first list in your list of lists. I don't know if that's what you want or not.
17:43:49<MoxJet>duaneb: nice :)
17:45:44<cayennext>I tried to map with (:): generate diff (x:xs) = [ map (\rest -> choosen:rest) $ generate diff xs | choosen <- x]
17:46:01<duaneb>MoxJet: thanks :)
17:46:03<cayennext>but it also has type errors
17:49:21<mightybyte>Is there a function ismilar to bind where the monad is different? i.e. :: m1 a -> (a -> m2 b) -> m2 b
17:50:04<vixey>mightbyte: no
17:50:13<Valodim>how would that work, not all monads are interchangable..
17:50:49<mightybyte>The specific case I'm looking at is where m1 is Maybe.
17:51:08<roconnor>@type maybe (fail "Nothing") return
17:51:10<lambdabot>forall (m :: * -> *) a. (Monad m) => Maybe a -> m a
17:51:14<mightybyte>...and I'm operating in another monad and would like to avoid the case.
17:51:37<mightybyte>roconnor: I was hoping to avoid fail
17:51:40<vixey>you 'avoid the case' by using something equivalent
17:52:37<vixey>mightbyte: why don't you just write your own function
17:52:41<mightybyte>Right, and Maybe's Monad instance is designed to do this, but I'm wondering if there is an idiomatic way to do this in this case.
17:53:08<vixey>show your code and I'll say if it's idiomatic
17:53:24<cayennext>Now it works, thanks for help :) | generate diff (x:xs) = [ choosen:rest | choosen <- x, rest <- generate diff xs]
17:59:14<mightybyte>vixey: Well, the obvious way was: do maybea <- ...; case maybea of (Just a -> f a) (Nothing -> g)
18:00:40<mightybyte>But I was hoping to take advantage of Haskell's machinery to avoid the boilerplate case of.
18:00:43<vixey>ok now write a function that does it
18:00:50<vixey>stop babbling about boilerplate and low hanging fruit
18:00:56<gio123>does haskel uses context variables?
18:02:00<mightybyte>Writing the function is easy. But if I just did that every time I came upon issues like this, I'd never learn about all the generic machinery that Haskell has available.
18:02:17<mightybyte>I look, but what I'm looking for isn't always easy to find.
18:02:35<vixey>write the function now
18:04:53<mightybyte>liftMaybe f g Nothing = g
18:05:00<mightybyte>liftMaybe f g (Just x) = f x
18:05:47<vixey>mightybyte: that already exists called 'maybe'
18:05:58<hatds>hmm.. why isn't there a pretty printing typeclass? Language.Haskell.Pretty defines one but it exports it as an abstract class
18:06:04<mightybyte>Ahhh
18:06:29<mightybyte>For some dumb reason, I was thinking that wouldn't work in my monadic context.
18:07:33<augustss>hatds: there's a pretty printing class on hackage
18:07:47<dancor_>is there a good way to return an autoincrement column as i insert a row in HDBC-postgresql
18:08:03<augustss>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/prettyclass
18:08:09<hatds>augustss: yea, but I might as well roll my own in that case
18:08:16<augustss>hatds: why?
18:08:50<augustss>hatds: it's better to reuse, that's why we have hackage
18:09:19<hatds>augustss: no, I just want a typeclass with one fucntion "pretty : a -> Doc"
18:09:19<dancor_>ACTION seconds reuse :)
18:09:33<matthew-_>hmm, how would people recommend I test for substring?
18:09:44<matthew-_>i.e. "bc" is a substring of "abcd"
18:09:46<dancor_>matthew-_: isInfixOf?
18:09:59<Colours_>hi! is this the place to ask for help regarding non-working cabal packages?
18:10:10<matthew-_>@where isInfixOf
18:10:11<lambdabot>I know nothing about isinfixof.
18:10:18<dancor_>http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v:isInfixOf
18:10:26<dancor_>@hoogle isInfixOf
18:10:26<lambdabot>Data.ByteString isInfixOf :: ByteString -> ByteString -> Bool
18:10:26<lambdabot>Data.List isInfixOf :: Eq a => [a] -> [a] -> Bool
18:10:26<lambdabot>Data.ByteString.Char8 isInfixOf :: ByteString -> ByteString -> Bool
18:11:03<hatds>augustss: there is such a typeclass in the standard libraries, but they won't let you declare instances
18:11:04<hatds>:(
18:11:25<matthew-_>dancor_: excellent, many thanks
18:11:57<dancor_>hatds: you only have to define pPrint in Pretty, right?
18:12:15<hatds>dancor_: pPrint?
18:12:31<dancor_>i don't understand how prettyclass is harder than what you want
18:14:13<hatds>what is prettyclass? all I see is Language.Haskell.Pretty.Pretty
18:14:21<dancor_>http://hackage.haskell.org/packages/archive/prettyclass/1.0.0.0/doc/html/Text-PrettyPrint-HughesPJClass.html
18:15:49<hatds>I see
18:16:02<hatds>what I meant before is that I'm too lazy to download a file
18:16:05<dancor_>oh
18:16:13<mm_freak>say i have a manager and a lot of workers with a lot of threads and there is a lot of communication… are TVars fast?
18:16:41<hatds>but I guess I don't have the luxury of a built in class :)
18:16:43<dancor_>cabal install will do that for you! :)
18:16:44<mm_freak>because with MVars i'm running into the problem that i can't want on multiple MVars at the same time
18:17:39<thou>hi, would someone be willing to help with sorting out a strictness problem (I think): using hGetContents + $! + parsec: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4960#a4960
18:17:48<zakwilson>I have lists of 32-bit integers on which I'm calling elem millions of times. This is slow. Can someone recommend a faster data structure to use? Storable Vector looks like the Right Thing, but I thought I'd check.
18:18:08<Cale>zakwilson: Set
18:18:15<thou>my program is working OK, except that it prints out info only at the very end, and uses gobs of memory during the process
18:18:25<Cale>zakwilson: Or even IntSet
18:18:27<thou>do i need DeepSeq or similar?
18:19:09<hatds>try to understand your strictness problems using `seq` and $! first
18:19:11<zakwilson>Cale: I'll try that. I should note that order does not matter for any other purpose, though it seems that you already guessed that.
18:19:36<Cale>zakwilson: Well, even if it did matter, you could collect them all into a Set anyway.
18:20:10<mm_freak>are TVars much slower than MVars?
18:20:22<thou>hatds: thanks, i'm not sure how to break this down more: parseContents h = hGetContents h >>= \s -> return $! parse Rfc822.message "" s
18:20:35<gio123>does haskel uses context variables?
18:20:45<Cale>thou: Are you sure it's a strictness problem at all?
18:20:57<Cale>gio123: What's a context variable?
18:21:19<gio123>variable which can be instatiated by context
18:21:37<Cale>gio123: I'm not sure what that means.
18:21:37<thou>Cale: no, i just can't think what else it would be -- if I parse 1000 messages, nothing gets printed until the very end of the program, and it's used up 1G of RAM at that point
18:21:44<gio123>context is a term with single occurence of hole, for instance f(a,hole)
18:22:05<Cale>thou: If is has anything to do with strictness, that means it is already too strict.
18:22:36<thou>Cale: if i change $! to $, then it blazes through it and returns (Message [] "") for every file
18:22:42<Cale>gio123: People construct special purpose datastructures for representing things of that sort, I suppose. It sounds like a zipper.
18:22:43<mm_freak>hmm… do TVars resemble MVars at all? i'm not sure
18:23:14<mm_freak>oh lol
18:23:19<Cale>thou: Of course $! won't change the end result vs $, only performance aspects.
18:23:19<mm_freak>there are TMVars for that
18:23:26<Cale>thou: So does that help?
18:24:16<Cale>thou: It sounds like either your parser is failing or you need to filter the output.
18:24:21<Cale>(or both)
18:24:23<thou>Cale: i'm sorry, does what help?
18:24:30<koeien>the -cafe is down?
18:24:38<Cale>thou: Well, it sounds like $ is performing better than $!
18:24:51<thou>yes, much - but it isn't actually reading any of the input :-/
18:25:00<Cale>Are you sure?
18:25:08<Cale>oh!
18:25:10<Cale>I see
18:25:21<Cale>You're calling hClose on an hGetContents'd handle
18:25:25<Cale>You should never ever do that.
18:25:28<thou>yes
18:25:47<Cale>If you run hGetContents on a handle, consider it as being essentially closed.
18:25:50<thou>i was trying to use something like this solution: http://www.mail-archive.com/haskell-cafe@haskell.org/msg31557.html
18:25:51<Cale>(it's half-closed)
18:26:51<thou>>readFile' f = do s <- readFile f
18:26:51<thou>> return $! (length s `seq` s)
18:26:53<lambdabot> Couldn't match expected type `[a]' against inferred type `Expr'
18:27:06<thou>I tried this readFile' solution, too, but it had the same symptom
18:27:09<Cale>If you really *need* to close the file-handles (operating systems can be picky about resources), then what you can do is use the Data.ByteString.Char8 version of hGetContents
18:27:21<Cale>(or readFile)
18:27:43<Cale>(not the lazy bytestring version)
18:27:53<thou>right, i forgot to mention the reason i started this whole thing, was that i'm running out of file handled
18:28:01<Cale>The difference is that version will slurp the whole file into a buffer at once.
18:28:32<thou>ok, so "use (strict) bytestring module" is the best solution
18:28:43<Cale>The normal hGetContents isn't good when you need to open a lot of files, because once you apply it, you're essentially handing control of that filehandle over to the garbage collector.
18:28:48<Cale>yeah, I think so
18:28:55<Cale>Also, it'll probably help performance anyway
18:29:12<thou>Cale: thanks a ton, i'll give that a shot. btw, you're a saint - i see you in here all the time answering crazy questions from people like me, it's amazing
18:29:39<Cale>My powers of procrastination know no bounds ;)
18:29:43<thou>hahaha
18:30:26<thou>well, you still have somethign to procrastinate on, so you must be succeeding somehow :-)
18:31:30<Cale>:)
18:35:22<mercury^>Cale: IRC is a community effort of procrastination. We help each other out with it here.
18:35:40<Cale>mercury^: Yeah :)
18:38:23<mercury^>A friend of mine once linked me this and then disappeared from IRC: http://lifelongactivist.com/file_download/35/ . Naturally, I haven't touched it yet.
18:38:42<qaz>the problem with haskell is it takes to long to really learn and appreciate its greatness
18:39:23<Cale>qaz: I wonder if that's actually a problem ;)
18:39:41<qaz>not if you want it as your secret weapon perhaps
18:41:03<vixey>> map ord "А Б В Г Д Е З И К Л М Н О П Р С Т У Ф Ц Ч Э Я"
18:41:04<lambdabot> [1040,32,1041,32,1042,32,1043,32,1044,32,1045,32,1047,32,1048,32,1050,32,10...
18:41:14<vixey>> map chr [1040..]
18:41:15<lambdabot> "\1040\1041\1042\1043\1044\1045\1046\1047\1048\1049\1050\1051\1052\1053\105...
18:41:18<vixey>:///
18:41:26<vixey>> var $ map chr [1040..] :: Expr
18:41:28<lambdabot> Ambiguous occurrence `var'
18:41:28<lambdabot> It could refer to either `Data.Number.S...
18:41:38<vixey>why does't it just do unicode by default ??
18:41:44<deech>Hi all,
18:42:33<deech>Is there some way of using HaXml to turn an XML document into a Data.Map where the key is a the tag and the value is its contents?
18:45:30<Cale>deech: I'm sure it can be done. I doubt there's a library function for it.
18:46:04<gio123>Cale: pm please
18:47:32<dancor_>vixey: what should it do?
18:47:58<vixey>work properly
18:48:17<dancor_>why doesn't haskell print unicode by default?
18:48:30<vixey>I don't because it sucks?
18:48:39<vixey>@faq can haskell suck when it comes to unicode
18:48:40<lambdabot>The answer is: Yes! Haskell can do that.
18:48:40<duaneb>ok, I'm rewriting the damn TextMate haskell bundle
18:49:05<dancor_>vixey: you keep confusing me by leaving out words and letters.
18:49:09<cypher->hmm.. lack of good unicode support is a real issue
18:49:20<dancor_>ironically. anyway, ya it is a real issue
18:49:34<Athas>GHC doesn't use Unicode by default?
18:50:17<dancor_>http://www.mail-archive.com/glasgow-haskell-bugs@haskell.org/msg21451.html
18:51:37<Athas>Oh, that's good to know. Unicode is something I care a lot about on an ideological plane.
18:52:02<dancor_>extended ideological plane
18:55:26<dancor_>s/extended/supplementary/ no more poorly-researched unicode humor
18:55:37<burp_>anyone know how I can access specific matrix entries in a matrix from numeric-prelude?
18:55:46<burp_>( this one http://hackage.haskell.org/packages/archive/numeric-prelude/0.1/doc/html/MathObj-Matrix.html)
18:57:33<burp_>hm, guess that has to be done with rows and columns
18:59:43<Taejo>:t unfoldr
18:59:44<lambdabot>forall b a. (b -> Maybe (a, b)) -> b -> [a]
19:06:54<Gracenotes>:.:
19:07:10<Gracenotes>.:: ::.
19:07:29<mm_freak>the namespace of record fields should be somehow attached to the type name
19:08:18<kacper_>i have a question, does "map f ( xs ++ ys ) = map f xs ++ map f ys" is correct for infinite lists?
19:08:18<mm_freak>like Type.fieldName
19:08:38<mm_freak>kacper_: yes
19:08:40<blackh>In QuickCheck's Gen monad, 'rand' returns the StdGen - but how can I push it back into the monad after I've used it? Or otherwise make sure that the random numbers aren't duplicated?
19:10:23<vixey>kacper_: it is true but I can't prove it
19:11:00<kacper_>for finite list it's easy way to prove but for infinite not ;)
19:12:31<mm_freak>kacper_: well, it's not straightforward to prove
19:12:40<qaz>is there no function to split a list in half?
19:12:42<mm_freak>you may find the wikibooks article about denotational semantics interesting
19:12:50<vixey>How do we prove an equation between infinite lists?
19:12:53<bombshelter13_>Hi... I'm trying to follow the tutorial on http://blog.haskell.cz/pivnik/building-a-shared-library-in-haskell/ to build a shared library written in Haskell that's accessible from C. Right now, Right now I'm trying to compile the code in the third 'code box' on the page using the ghc syntax shown in the fourth 'code box', as he instructs... however, it's resulting in an error about an undefined symbol, so i'm wondering if something i
19:12:58<mm_freak>qaz: see splitAt, length and div ;)
19:13:23<mm_freak>kacper_: http://en.wikibooks.org/wiki/Haskell/Denotational_semantics
19:13:52<mm_freak>does GHC support shared libs now?
19:14:23<mm_freak>on x86, that is
19:15:15<Cale>bombshelter13_: Your message was cut off at "something i"
19:15:35<bombshelter13_>... is wrong with my setup. The error it's generating is here, any ideas would be appreciated: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4961#a4961
19:15:51<bombshelter13_>there's the rest ;)
19:17:20<Cale>bombshelter13_: Well, I can try doing what you're doing and see...
19:17:43<bombshelter13_>yeah, i'm trying to get sshed into another system to try it there as well, curious to see what your results wil lbe
19:17:56<Cale>worksforme
19:18:09<Cale>What version of ghc are you using?
19:18:19<Cale>This seems like something possibly newish.
19:18:26<Cale>I didn't even know ghc could make .so files.
19:18:59<bombshelter13_>Heh, on the second system I've tried it on, I got a completely different error. Let me check my version
19:19:03<Cale>cale@zaphod:~$ ghc --version
19:19:03<Cale>The Glorious Glasgow Haskell Compilation System, version 6.10.3
19:19:10<bombshelter13_>6.10.1
19:19:14<Cale>hmm
19:19:34<bombshelter13_>does it work for you?
19:20:16<Cale>yes
19:20:28<Cale>cale@zaphod:~$ ghc -O2 --make -no-hs-main -optl '-shared' -o Test.so Test.hs
19:20:28<Cale>[1 of 1] Compiling Test ( Test.hs, Test.o )
19:20:28<Cale>Linking Test.so ...
19:20:28<Cale>cale@zaphod:~$
19:20:42<bombshelter13_>Hm, I'm gonna try to get 6.10.3 and see if that makes a difference.
19:20:57<vininim>is 6.10.3 going to hit Leonidas?
19:21:10<Cale>What is Leonidas?
19:21:13<vininim>fedora 11
19:21:35<Cale>ah
19:21:53<bombshelter13_>Hm, ports only seems to have 6.10.1, anyonw know the easiest route to get 6.10.3 on os x?
19:22:09<Cale>I'm using Ubuntu, but its support for Haskell is always way behind so I just get the binaries from GHC's website.
19:22:28<Cale>http://www.haskell.org/ghc/download_ghc_6_10_3.html
19:23:11<Cale>bombshelter13_: Get the installer pkg, probably
19:23:24<bombshelter13_>hm, must have not seen that. trying to recall why i'd have installed a ports version in the first place if there was an official binary, heh.
19:23:54<duaneb>I just build from source
19:23:56<duaneb>it works best that way
19:24:08<mjrosenb>ACTION installs from portage
19:24:10<Cale>I wouldn't recommend building from source.
19:24:11<Berengal>Building from source takes forever
19:24:25<duaneb>it works :)
19:24:25<Cale>It takes forever, and requires you to have a binary already.
19:24:31<Athas>Is compiling GHC really that slow?
19:24:32<duaneb>yea, well
19:24:33<duaneb>it works
19:24:43<duaneb>It only takes an hour or so for me
19:24:46<Cale>It works, but so must the binary you already have.
19:25:19<duaneb>well, yea
19:25:22<duaneb>but the upgrade!
19:25:22<voker57__>can one build ghc without ghc?
19:25:30<Cale>ACTION holds duaneb personally responsible for the heat death of the universe.
19:25:37<duaneb>voker57__: not from haskell source, but one can compile haskell to c
19:25:43<Cale>voker57__: Only with a lot of effort.
19:25:56<duaneb>which can then be compiled with gcc IF the c source files were generated for that platform
19:26:03<duaneb>so: not easily :)
19:26:04<Cale>duaneb: Er, ghc doesn't really do that though, does it?
19:26:07<qaz>> ((1:) *** (2:)) $ [1,2,3]
19:26:09<lambdabot> Couldn't match expected type `([t], [t1])'
19:26:09<Berengal>Don't you need to bootstrap 6.2 or something like that to get a ghc from just source?
19:26:16<duaneb>Cale: it does for bootstrap
19:26:20<qaz>> (1:) *** (2:) $ [1,2,3]
19:26:21<lambdabot> Couldn't match expected type `([t], [t1])'
19:26:25<Cale>Perhaps they have that working again.
19:26:32<qaz>> (1:) *** (2:) $ 1
19:26:33<lambdabot> No instance for (Num ([t], [t1]))
19:26:33<lambdabot> arising from the literal `1' a...
19:26:37<qaz>> (1:) *** (2:) $ [[1]]
19:26:37<lambdabot> Couldn't match expected type `([t], [t1])'
19:26:38<voker57__>Cale: involving tracing back to ghc written not in haskell?
19:27:03<qaz>> (1+) *** (2+) $ [1,2,3]
19:27:04<lambdabot> Couldn't match expected type `(t, t1)' against inferred type `[a]'
19:27:07<qaz>> (1+) *** (2+) $ 1
19:27:08<lambdabot> No instance for (Num (t, t1))
19:27:08<lambdabot> arising from the literal `1' at <i...
19:27:11<Cale>voker57__: There's a shorter path...
19:27:23<Cale>ACTION finds the instructions
19:27:24<qaz>> (1+) *** (2+) $ [[1]]
19:27:24<lambdabot> Couldn't match expected type `(t, t1)' against inferred type `[a]'
19:27:27<qaz>> (1+) *** (2+) $ [1]
19:27:28<lambdabot> Couldn't match expected type `(t, t1)' against inferred type `[a]'
19:27:37<duaneb>Cale: I was under the impression that ghc had to cross-compile its own haskell files to C files for a foreign platform
19:27:43<Athas>Is GHC the only Haskell implementation that can compile GHC?
19:28:19<Cale>duaneb: But the normal method of compilation via C doesn't produce executable C.
19:28:19<centrinia>Athas, not for all versions of GHC. ;)
19:28:33<duaneb>Cale: that's right
19:28:35<duaneb>there's some wonky thing...
19:28:41<Athas>centrinia: well, current versions then.
19:28:50<Cale>duaneb: It produces C code which gcc is meant to compile, and then the assembly output is mangled into something valid.
19:28:59<duaneb>ahah, we are both correct
19:29:00<duaneb>Bootstrapping GHC on a system without GHC already installed is achieved by taking the intermediate C files (known as HC files) from another GHC compilation, compiling them using gcc to get a working GHC.
19:29:02<bombshelter13_>Ahh, that's why I probably installed the ports version instead of the binary -- requires xcode to be installed, and i'd installed ghc way before i started using xcode...
19:29:08<duaneb>NOTE: Versions supported: between 6.0.1 and 6.6.2. We are working on getting bootstrapping working again in the 6.8 series, see #1346.
19:29:21<Cale>duaneb: hehe, yeah, that's pretty far back
19:29:22<kacper_>?src drop
19:29:22<lambdabot>drop n xs | n <= 0 = xs
19:29:22<lambdabot>drop _ [] = []
19:29:22<lambdabot>drop n (_:xs) = drop (n-1) xs
19:29:41<Athas>That sounds hilariously complicated.
19:29:57<mm_freak>is there an easy way to have multiple records with the same field name without needing multiple modules? like qualified record field names?
19:30:03<Cale>6.0.1 is close to the time I started programming in Haskell. I think I used one version from the 5.x series.
19:30:26<augustss>mm_freak: no
19:30:46<mm_freak>is there a way to write multiple modules in a single source file?
19:30:55<Cale>mm_freak: Theoretically, but no.
19:31:08<mm_freak>that's annoying
19:31:23<Cale>mm_freak: I just name my record field names disjointly.
19:31:36<Gracenotes>mm_freak: you can try a function that pattern matches on various constructors and returns the appropriate attribute
19:31:41<Cale>Usually by adding a little prefix or suffix.
19:31:51<Gracenotes>in each case
19:31:52<centrinia>Does the Prelude contain a function f :: Int -> (a -> a) -> (a -> a); f 0 _ = id; f n g = f (n-1) g . g ?
19:32:05<Cale>centrinia: The closest thing is iterate
19:32:06<Gracenotes>centrinia: no
19:32:08<mm_freak>hmm yeah, seems to be the only solution
19:32:17<Cale>> iterate (+1) 0 !! 20
19:32:18<lambdabot> 20
19:32:27<mm_freak>Gracenotes: i have a record, which is only a single constructor
19:33:05<augustss>mm_freak: There's an extension that might do what you need
19:33:34<Gracenotes>centrinia: there's also this
19:33:38<Gracenotes>> foldr (.) id (replicate 10 (+1)) 0
19:33:39<lambdabot> 10
19:33:50<Gracenotes>> foldr (.) id (replicate 10 (*2)) 1
19:33:51<lambdabot> 1024
19:34:06<augustss>mm_freak: -XDisambiguateRecordFields
19:34:12<Cale>mm_freak: It's important to notice that the record field names are not just record field names, but also automatically the names of functions which need to be well-typed.
19:34:13<centrinia>:t \n g -> foldr (.) id (replicate n g)
19:34:15<lambdabot>forall a. Int -> (a -> a) -> a -> a
19:34:26<obk>I have a tree structure (data Node = ...) and a mapTree :: (Node -> Node) -> Node -> Node that applies a function to all the nodes (bottom up). I now need mapTreeM :: (Node -> M Node) -> Node -> M Node. Is there a way to avoid duplicating the original (long!) mapTree implementation with "M" everywhere?
19:34:49<centrinia>:t \n g -> (!!n) . iterate g
19:34:50<lambdabot>forall a. Int -> (a -> a) -> a -> a
19:34:57<kacper_>so my question after write http://en.wikibooks.org/wiki/Haskell/Denotational_semantics is take 3 [1..] works and drop 3 [1..] doesn't work because after 3 times pattern-matching it evalueate to drop 0 _|_ and from def. it gives _|_ ?
19:34:58<Cale>obk: No, because mapTreeM actually has more information in it than mapTree
19:35:15<Cale>obk: (it contains information about execution order which the pure version can't)
19:35:19<vixey>> drop 0 undefined
19:35:20<lambdabot> * Exception: Prelude.undefined
19:35:23<augustss>obk: write just mapTreeM and use that to implement mapTree (with the identity monad)
19:35:35<shachaf>@src mapM
19:35:35<lambdabot>mapM f as = sequence (map f as)
19:35:37<Cale>Right, what augustss said :)
19:35:44<centrinia>> (\n g -> (!!n) . iterate g) 10 [0..]
19:35:45<shachaf>You could use an equivalent of sequence for your tree, perhaps?
19:35:46<lambdabot> Couldn't match expected type `a -> a' against inferred type `[a1]'
19:35:52<centrinia>> (\n g -> (!!n) . iterate g) 10 tail [0..]
19:35:54<lambdabot> [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34...
19:35:56<obk>augustss, Cale: That's what I figured by shachaf said it is a horrible practice :-)
19:36:08<mm_freak>augustss: i'll have a look at it, thanks
19:36:18<shachaf>ACTION didn't say that!
19:36:19<Athas>What's the state/future of dynamic libraries in GHC?
19:36:27<mm_freak>Cale: yeah, sure… but that's a piece of OOP i'm missing in haskell
19:36:50<obk>I expect using mapTreeM with the identity monad would not hurt performance _too_ much...
19:37:03<Cale>kacper_: hmm?
19:37:21<centrinia>Is (take 2) a catamorphism?
19:37:24<augustss>obk: don't worry about performance until you have to
19:37:34<Heffalump>centrinia: no
19:37:40<Cale>obk: But you might hang on to your current version just in case.
19:37:56<Gracenotes>grep -R 'optimized away' haskell_logs | wc -l
19:37:58<Gracenotes>>_>
19:37:59<obk>augustss: Actually the reason I am doing this is performance; the monadic version will be used to memoize the computations
19:38:04<centrinia>But (drop 2) is a catamorphism.
19:38:09<Gracenotes>I expect lots of results
19:38:12<obk>But I see your point. It should be better this way.
19:38:14<vixey>drop 2 isn't a catamorphism
19:38:26<Cale>kacper_: take 3 [1..] and drop 3 [1..] are both completely defined values
19:38:35<Cale>> drop 3 [1..]
19:38:37<lambdabot> [4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30...
19:38:42<Cale>> take 3 [1..]
19:38:43<lambdabot> [1,2,3]
19:39:08<Heffalump>centrinia: how?
19:39:11<Heffalump>I don't think it is
19:39:35<centrinia>drop 2 = foldr (.) id (replicate 2 tail)
19:39:55<mm_freak>the documentation says that the STM function 'orElse' is GHC only?!
19:39:58<Athas>Actually, about performance... are there any papers, articles or tutorials about how to optimise Haskell? I have a pretty good intuitive understanding of how to achieve fast code in Lisp, but I'm under the impression that GHC does much more intensive rewriting and requires less intuitive considerations.
19:40:01<Gracenotes>centrinia: eh. That would mean lots of stack space for large values...
19:40:11<mm_freak>is that true? is there another way to compose STM actions? Applicative?
19:40:12<Gracenotes>it'd work at least
19:40:24<Cale>mm_freak: STM is GHC-only.
19:40:30<mm_freak>oh, ok
19:40:48<centrinia>ACTION compiles ghc-6.10.3
19:41:00<Cale>(at least there are no other current implementations of Haskell with it)
19:41:09<mm_freak>hmm, STM is not an Alternative instance anyway (for whatever reason)
19:41:33<Cale>Athas: There was a guide on the wiki which looked like it might be good, but which I haven't actually read...
19:41:52<Gracenotes>lots of things that can be alternatives aren't :/
19:41:53<centrinia>Hmm, is there a special name for the composition of an anamorphism with a catamorphism?
19:41:56<Cale>http://www.haskell.org/haskellwiki/Performance
19:42:10<Gracenotes>hm. surely all MonadPlus instances are also Alternatives?
19:42:18<Athas>Cale: thanks.
19:42:19<dolio>hylomorphism
19:42:32<kacper_>?src take
19:42:33<lambdabot>take n _ | n <= 0 = []
19:42:33<lambdabot>take _ [] = []
19:42:33<lambdabot>take n (x:xs) = x : take (n-1) xs
19:42:42<dolio>Or metamorphism, I think, depending on what order you compose them in.
19:42:43<centrinia>dolio, a hylomorphism is the composition of a catamorphism with an anamorphism.
19:42:55<Gracenotes>> take 0 undefined
19:42:56<lambdabot> []
19:42:58<centrinia>Thanks. Metamorphism should be what I'm looking for. :)
19:43:19<centrinia>> take 0 $ take 0 undefined
19:43:21<lambdabot> []
19:43:27<centrinia>> take 1 $ take 0 undefined
19:43:29<lambdabot> []
19:43:32<Cale>It starts to get silly naming such things, I think. The nomenclature somehow isn't very compositional.
19:43:39<Gracenotes>>:[]
19:43:56<Berengal>Cale: Sort of ironic, isn't it?
19:44:17<Gracenotes>ISN'T IT IRONIC
19:44:17<centrinia>So there's no special name for the composition of a catamorphism with a metamorphism?
19:44:22<Gracenotes>don't make me sing it
19:44:50<Cale>We should start the convention of just concatenating the prefixes in the appropriate order.
19:44:57<Berengal>@quote prepromorphism
19:44:57<lambdabot>EvilTerran says: [on category theory] the same place of nightmares that spawned zygohistomorphic prepromorphisms :P
19:45:20<Gracenotes>catametamorphism
19:45:35<Cale>I suppose 'ana' tends to be problematic...
19:45:42<Cale>'cataanamorphism'
19:45:53<Berengal>katana morphism?
19:45:57<malouin>So when trying to compile things in low memory situations where swap access is slow, this might help?
19:46:01<malouin>cabal install --ghc-options='-optl-Xlinker -optl--no-keep-memory'
19:46:15<malouin>but it also might not.
19:46:15<Cale>"Santa Ana morphism"?
19:47:49<kacper_>can i prove by structural induction for e.g "map f ( xs ++ ys ) = map f xs ++ map f ys" but for infinite lists?
19:47:51<Gracenotes>catametahylohypometametahypoanamorphism
19:48:27<centrinia>Uh, what is a hypomorphism?
19:48:31<obk>Is there "fromM :: (Monad m) => m a => a" ? A generalization of fromJust ?
19:49:01<Cale>obk: That sort of type pains me ;)
19:49:08<Gracenotes>doesn't exist
19:49:17<Cale>obk: (I really dislike the use of Monad to express failure)
19:49:18<centrinia>obk, Yes.
19:49:33<Cale>oh, wait...
19:49:36<obk>Really? What is it called?
19:49:37<Gracenotes>obk: eek. fromJust is pretty unsafe to begin with
19:49:38<Cale>err...
19:49:53<Cale>actually, that's not even what I thought it was
19:49:55<centrinia>:t unsafePerformIO . unsafeCoerce
19:49:57<lambdabot>Not in scope: `unsafePerformIO'
19:49:57<lambdabot>Not in scope: `unsafeCoerce'
19:49:57<bombshelter13_>Huh, interestingly, I've completed updating to 6.10.3 and am experiencing the same error.
19:49:58<Cale>ACTION should read more carefully
19:50:00<Gracenotes>fromM goes against the point of monads -- to sequence things in composition
19:50:00<obk>It makes sense in my case.. and it would cut down the rw-write effort by 90% :-)
19:50:04<Cale>That simply does not exist.
19:50:15<Cale>There is no polymorphic function (Monad m) => m a -> a
19:50:21<Gracenotes>and there shouldn't be!
19:50:23<Cale>(which isn't everywhere undefined)
19:50:26<Gracenotes>>_>
19:50:40<hatds>fromJust is not that bad though :)
19:50:41<dolio>Why not just tell him: undefined :: m a -> a? At least that won't cause flagrant segfaulting.
19:50:44<Jedai>kacper_: Yes the fact that the lists can be infinite shouldn't have any import on the proof
19:50:59<Cale>dolio: But it will get you the next best thing ;)
19:51:13<kacper_>?src map
19:51:13<lambdabot>map _ [] = []
19:51:13<lambdabot>map f (x:xs) = f x : map f xs
19:51:18<obk>So if I have : mapNode f (Foo a b) = f $ Foo (mapNode f a) (mapNode f b), then mapNodeM _must_ use do notation. Oh well...
19:51:23<dolio>Yeah. It's still better than unsafePerformIO . unsafeCoerce.
19:52:27<hatds>but you only write your mapM's and what not once for each data structure
19:53:39<Jedai>obk: Look at traversable for a generalisation of mapM
19:54:04<kacper_>can i prove by structural induction for e.g "map f ( xs ++ ys ) = map f xs ++ map f ys" but for infinite lists?
19:54:07<Jedai>obk: You'll get instance for many of the usual types, and you should write an instance yourself
19:54:21<obk>Jedai: Will look. Thanks!
19:54:37<centrinia>obk, There is a coreturn :: (Comonad m) => m a -> a
19:54:38<Jedai>kacper_: I already answered that... Yes, and the proof isn't different from the usual
19:55:30<roconnor>@hoogle point
19:55:30<lambdabot>package pointfree
19:55:31<lambdabot>package fixpoint
19:56:14<kacper_>but In my exercise is written prove it for infinite lists or mark when it's correct only for finite lists
19:56:41<Jedai>kacper_: And ?
19:56:48<kacper_>for e.g reverse $ reverse [1..] fails
19:57:03<kacper_>for infinite but for finite is good
19:57:20<obk>Jedai: Traversable seems exactly what I need. Thanks!
19:57:58<kacper_>should i prove that reverse $ reverse = id ?
19:58:23<Jedai>kacper_: That would be "reverse . reverse", not "reverse $ reverse"
19:59:09<kacper_>reverse . reverse [1..10] fails
19:59:20<NEEDMOAR>reverse . reverse $ [1..10]
19:59:27<roconnor>(reverse . reverse) [1..10]
19:59:33<Jedai>kacper_: And since reverse doesn't start producing a result before it gets to the end of the list, it's obvious that "reverse . reverse" == "id" is only true for finite lists...
19:59:47<wabash>Hey, ppl. Exciting, the haskell channel has more and more peopel everytime I come back!
19:59:47<NEEDMOAR>@type reverse $ reverse
19:59:47<lambdabot> Couldn't match expected type `[a]'
19:59:47<lambdabot> against inferred type `[a1] -> [a1]'
19:59:47<lambdabot> In the second argument of `($)', namely `reverse'
19:59:54<NEEDMOAR>@type reverse . reverse
19:59:54<lambdabot>forall a. [a] -> [a]
19:59:59<wabash>I have some general questions....
20:00:09<wabash>What happens in Haskell if you have overflow of float math?
20:00:13<wabash>or underflow?
20:00:46<Jedai>kacper_: whereas map is good producer
20:01:13<roconnor>> 10**(10**10) :: Double
20:01:15<lambdabot> Infinity
20:01:19<Gracenotes>wabash: Float and Double follow IEEE
20:01:27<roconnor>> 10**(-(10**10)) :: Double
20:01:29<lambdabot> 0.0
20:01:36<wabash>Gracenotes: THanks.
20:01:36<roconnor>> isIEEE $ 10**(-(10**10)) :: Double
20:01:38<lambdabot> Couldn't match expected type `Double' against inferred type `Bool'
20:01:43<roconnor>> isIEEE (10**(-(10**10)) :: Double)
20:01:45<lambdabot> True
20:01:50<wabash>But I'm confused. When there is over/under flow, how will you know?
20:02:08<Gracenotes>> isNaN (0/0)
20:02:09<lambdabot> True
20:02:15<Gracenotes>> isInfinite (1/0)
20:02:16<lambdabot> True
20:03:57<mm_freak>any problems with mixing normal primitives like MVar with STM in concurrent code?
20:04:45<wabash>Gracenotes: Is there an exception of some sort that is raised?
20:05:02<Gracenotes>it's IEEE floating point. no exceptions are raised.
20:05:10<Gracenotes>as in any other proper implementation
20:05:26<Gracenotes>> 1 `div` 0 -- although, this, but those are integers
20:05:26<jbjohns>hi
20:05:28<lambdabot> * Exception: divide by zero
20:05:39<jbjohns>intersect :: Ord a => [(a,a)] -> [(a,a)] -> [(a,a)]
20:05:40<jbjohns>intersect [] _ = []
20:05:42<jbjohns>intersect _ [] = []
20:05:44<jbjohns>intersect x'@((a,b):x) y'@((c,d):y)
20:05:45<jbjohns> | b < c = intersect x y'
20:05:47<jbjohns> | d < a = intersect x' y
20:05:48<jbjohns> | otherwise = case b `compare` d of
20:05:50<jbjohns> LT -> (max a c, b) : intersect x y'
20:05:52<jbjohns> GT -> (max a c, d) : intersect x' y
20:05:53<jbjohns> EQ -> (max a c, b) : intersect x y
20:05:54<jbjohns>oops
20:05:56<jbjohns>can anyone make that better? :)
20:07:02<wabash>Gracenotes: Ok, so how does one write a robust program that catches errors?
20:07:27<Gracenotes>uh, know where the errors occur?
20:08:54<Gracenotes>and if you're using an exception-causing function, check the preconditions first or (if you absolutely must) use a Control.Exception function. However, these are I/O, and condition-checking is the best defense really
20:09:31<wabash>Ok, so you have input, right? And it's a series of numbers. Some of them may be very small ,some very large. Say matrix computations and multiplications. You have no predetermined restrictions on inputs. So if I have two ints, that are both 2^30 in size, and I multiply them, I need to know that they overflowed.
20:10:04<copumpkin>cast them to a larger type, multiply them there
20:10:16<copumpkin>and check if it's greater than the max of the smaller one
20:10:17<Gracenotes>hm. might not be good for performance though >_>
20:10:58<copumpkin>on x86, multiplying two 32-bit ints automatically gives you a 64-bit int anyway
20:11:00<Cale>jbjohns: hmm, the (a,a) pairs are like intervals?
20:11:12<DBAlex>hey
20:11:13<jbjohns>dates actually
20:11:20<Cale>wabash: Use Integer.
20:11:32<Cale>> 2^30 * 2^30
20:11:33<lambdabot> 1152921504606846976
20:11:41<wabash>Cale: Is there a huge penalty for using this type?
20:11:47<Cale>wabash: Not really.
20:11:49<jbjohns>they start out being some period apart, e.g. a year and the above algo finds the overlap
20:11:51<wabash>I see.
20:11:59<wabash>Cale, that answers my question.
20:12:02<Cale>wabash: Well, it's as small as can be expected anyway
20:12:07<DBAlex>I just found a sort of haskell anamoly, I know last [1..999999999999999] is slow because it has to construct the last due to running last first but it would be a nice optimization to just use the last value after the .. and not evaluate anything before it
20:12:38<DBAlex>right?
20:12:47<dolio>There's the checked library on hackage, too.
20:12:49<wabash>Now, in native C and C++, there is no way to do it with ints or doubles or floats. But processors have detection flags, and the processor itself finds out in hardware. So how is it done in C++ or C?
20:13:11<DBAlex>> last [1..99999999999999999999]
20:13:27<lambdabot> thread killed
20:13:33<DBAlex>heh :)
20:14:04<DBAlex>*construct the list
20:14:21<Cale>DBAlex: You could add a rewrite rule to GHC, but generally the way that lists work, it's not possible to get the last element quickly.
20:14:43<DBAlex>Cale: ok, but do you see my point
20:14:47<BMeph>wabash: The traditional C detection mechanism is: "Segmentation fault (core dumped)." ;p
20:14:56<qaz>hmm, the only reason to use Erlang over Haskell seems to be OTP, if you have problem that have to do with lagre-scale distirbuted stuff. otherwise use Haskell.
20:15:00<DBAlex>I suppose it can't have a special case for last
20:15:05<dolio>The rewrite rule would be pointless, because no one ever writes "last [1..9999999999999999999]" in their code.
20:15:11<DBAlex>its just a silly optimization :)
20:15:12<Cale>DBAlex: If you need fast access to the end of a list, you shouldn't be using lists.
20:15:16<qaz>but Haskell could be used easily for dsitributed stuff too?
20:15:22<qaz>how is the actor package on Hackage?
20:15:28<DBAlex>dolio: heh, true :D
20:15:35<Cale>DBAlex: It can actually, you can add one with a pragma.
20:15:48<DBAlex>ok
20:16:53<Cale>DBAlex: http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html#rules
20:17:03<Cale>er, no
20:17:03<DBAlex>ok
20:17:04<Cale>http://www.haskell.org/ghc/docs/latest/html/users_guide/rewrite-rules.html
20:17:04<DBAlex>cheers
20:17:06<DBAlex>brb :D
20:17:09<jbjohns>qaz: Erlang has some other interesting features like.... ugh, what's that prolog term where the variables are all tried until they fit the pattern? unification?
20:18:06<jbjohns>it's not as thorough as Prolog's of course, but it can do some interesting things, including once a variable is set it can then be used as a pattern as though it were a constant or whatever
20:18:20<Cale>{-# RULES "last/enumFromTo" forall x y. last (enumFromTo x y) = y #-}
20:18:42<jbjohns>last [1..9999999999999999999999999999]
20:18:55<jbjohns>hrm, I guess it didn't take effect
20:19:04<Cale>oh, it doesn't apply to the bot
20:19:10<Cale>and not without optimisations anyway
20:19:16<jbjohns>ah and I didn't send it to the bot anyway *bonk self*
20:20:24<Cale>It works in a compiled program I just wrote
20:20:33<Cale>{-# RULES "last/enumFromTo" forall x y. last (enumFromTo x y) = y #-}
20:20:33<Cale>main = print (last [1..9999999999999999999])
20:25:13<obk>Turns out Traversable will not work for me because it only works for things like "Tree a" and mine is just a simple "Tree" :-(
20:26:28<copumpkin>is that always true?
20:26:35<copumpkin>> [0.5 .. 1.5]
20:26:37<lambdabot> [0.5,1.5]
20:26:42<copumpkin>> [0.5 .. 1.4]
20:26:44<lambdabot> [0.5,1.5]
20:28:14<dolio>Yes, well, the floating point Enum instances are evil.
20:30:15<Cale>copumpkin: Right, it's not always true.
20:31:24<BMeph>It just *ought* to be. :)
20:33:19<skorpan>@src intercalate
20:33:19<lambdabot>intercalate xs xss = concat (intersperse xs xss)
20:50:39<Cale>BMeph: I can imagine that failing that property is okay. I just don't think that [x..y] should ever contain elements strictly larger than y
20:50:56<Cale>(or less than x)
20:51:15<duaneb>anyone here on OS X?
20:51:56<obk>ACTION just pasted http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4966#a4966 to demonstrate the problem.
20:52:10<copumpkin>duaneb: I am
20:52:18<duaneb>what editor do you use?
20:52:30<duaneb>I WAS using textmate, but its haskell support is limited
20:52:31<copumpkin>textmate usually
20:52:37<duaneb>heh
20:52:50<copumpkin>what do you need it to do?
20:54:16<duaneb>umm
20:54:22<duaneb>highlight the syntax regularly? :P
20:54:59<duaneb>for example, paste this into TM: (.+.) :: v -> v -> v -- component add
20:55:08<copumpkin>fix the bundle then :P I don't care that much about it
20:55:09<BMeph>Cale: Oh, you mean how [0.5..2] can have 2.5 in it? :P
20:55:18<BMeph>> [0.5]..2]
20:55:18<lambdabot> <no location info>: parse error on input `..'
20:55:22<BMeph>> [0.5..2]
20:55:23<lambdabot> [0.5,1.5,2.5]
20:55:34<Cale>BMeph: right
20:55:44<Cale>BMeph: In my opinion, it should stop at 1.5
20:56:03<Raevel>wierd!
20:56:28<skorpan>wired!
20:56:50<Gracenotes>well, floor 2.5 is still 2. eh.
20:57:02<BMeph>> [0.5..2.2]
20:57:03<lambdabot> [0.5,1.5,2.5]
20:57:15<BMeph>'nuff said.
20:57:37<Gracenotes>well. floor 2.2 is still floor 2.5.. ... . .. . ......
20:57:49<glguy>> map floor [0.5,1.5..]
20:57:50<lambdabot> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,...
20:58:02<glguy>> map round [0.5,1.5..]
20:58:04<lambdabot> [0,2,2,4,4,6,6,8,8,10,10,12,12,14,14,16,16,18,18,20,20,22,22,24,24,26,26,28...
20:58:12<Gracenotes>what the hell? 15 minutes of credits?
20:59:29<hatds>the heck, why are Floats in Enum?
20:59:43<shachaf>Would it be possible to make obk's example work with Data.Tree? Select and Max look like they might be troublesome...
20:59:45<roconnor>hatds: it's stupid!!
20:59:55<hatds>roconnor: yea
21:00:12<roconnor>I at some point thought that Enum should be broken into two classes.
21:01:02<inimino>IEEE floats are enumerable
21:01:14<roconnor>but enum doesn't enumerate them.
21:01:37<hatds>yea, you should be able to reach any Enum value by starting at an arbitrary value and using succ or pred
21:01:55<copumpkin>I made something that did that a while ago
21:01:56<dolio>> (last [2^31 - 2 .. 2^31] :: Int, 2^31)
21:01:58<lambdabot> (2147483648,2147483648)
21:02:02<inimino>what does it do with them?
21:02:08<inimino>you should be able to do that with floats
21:02:11<hatds>it adds 1!
21:02:19<inimino>oh.
21:02:22<dolio>> (last [2^63 - 2 .. 2^63] :: Int, 2^63)
21:02:23<lambdabot> (* Exception: Prelude.last: empty list
21:02:28<roconnor>enumeration Float is dumb anyways
21:02:32<roconnor>enumerating
21:03:06<opqdonut>i'd like to see a proper Enum instance
21:03:10<hatds>I only sorta makes sense if you think of Floats as a finite set, by the instance doesn't even reflect that
21:03:13<opqdonut>that gives the next float
21:03:15<hatds>*I=it
21:03:31<vixey>@src Enum
21:03:32<lambdabot>class Enum a where
21:03:32<lambdabot> succ :: a -> a
21:03:32<lambdabot> pred :: a -> a
21:03:32<lambdabot> toEnum :: Int -> a
21:03:32<lambdabot> fromEnum :: a -> Int
21:03:34<lambdabot>[3 @more lines]
21:03:38<vixey>I don't see a problem
21:03:44<copumpkin>the Int is a pain
21:03:50<copumpkin>and the instance for Float/Double is a pain
21:04:13<hatds>I think of Enum as being a witness for being finite or countable
21:05:24<hatds>(cause they're called, you know, *Enum*)
21:05:39<copumpkin>infinite things can be enumerable
21:05:55<hatds>by countable I mean coutably infinite
21:06:03<copumpkin>see, but the Int prevents that
21:06:09<hatds>but it's finite
21:06:16<hatds>"finite or countable" ish
21:06:59<Phyx->Hi, quick question what option do i need to enable to allow the syntax "data Test :: * -> * where" ? i have GADTs enabled but ghc still complaints
21:07:15<vixey>try KindSignatures
21:07:48<Phyx->that seems to work, thanks vixey
21:08:22<Phyx->i was reading http://en.wikibooks.org/wiki/Haskell/GADT, it shows the syntax just not what to use to enable it. or i missed it
21:09:02<opqdonut>{-# LANGUAGE GADTs #-}
21:09:05<opqdonut>in the source file
21:09:18<MyCatVerbs>Above the module line.
21:09:33<opqdonut>you might need an other extension for the kind signature
21:09:44<Phyx->opqdonut: i already had that, but without KindSignature it wouldn't take it
21:09:47<duaneb>is there a list of all the pragmas somewhere? :P
21:10:05<copumpkin>http://www.haskell.org/ghc/docs/latest/html/users_guide/ghc-language-features.html
21:10:14<thoughtpolice>duaneb: ghc --supported-languages
21:10:21<thoughtpolice>hi copumpkin!
21:10:29<copumpkin>ohai2u
21:10:46<copumpkin>:P
21:12:05<Phyx->ACTION wonders why he always ends up having so many language extensions enabled
21:12:16<skorpan>because haskell sucks
21:12:18<copumpkin>because we need a new standard that enables them by default
21:12:29<SubStack>skorpan: it's true
21:12:39<hatds>I don't think it is much of a hassle
21:12:46<copumpkin>ACTION coughs: http://haskell.org/haskellwiki/?title=UnnamedStandard
21:13:01<Phyx->lol
21:13:03<SubStack>it however sucks less than the alternatives
21:13:14<skorpan>indeed
21:13:27<sjanssen>copumpkin: that page doesn't seem useful
21:14:01<hatds>needs to be a named instances proposal in there
21:14:02<Phyx->"concat means the same thing as join. We propose we don't use concat at all" <-- while i agree... doing so would require you to immediately teach someone monads no?
21:14:05<sjanssen>I don't think Haskell '98 has any monoid classes?
21:14:09<copumpkin>sjanssen: it wasn't meant to be, it was meant as a first step to give people somewhere to put down ideas (because I've seen people complain about h98 hundreds of times in the few months since I've been here)
21:14:27<sjanssen>ACTION loves Haskell '98
21:14:34<sjanssen>ACTION also thinks a few bits of it are dumb
21:14:40<MyCatVerbs>Phyx-: not quite, mostly it just means you need to immediately teach someone type constructors.
21:15:03<hatds>there's nothing wrong with having both concat and join, imho
21:15:06<roconnor>sjanssen: ya, like gcd 0 0
21:15:11<roconnor>ACTION still isn't over it.
21:15:15<copumpkin>there are just lots of small silly things
21:15:20<Phyx->hatds: agreed
21:15:24<copumpkin>that could be fixed easily
21:15:47<copumpkin> but you'd need to get enough people interested first
21:15:55<sjanssen>this page (and hatds and roconnor) illustrates the problem with just making a wiki page: it becomes a place to whine about your favorite issues
21:15:56<qaz>vixey: what's your interest in Erlang?
21:16:01<sjanssen>roconnor: nobody cares about gcd 0 0
21:16:20<hatds>I do :)
21:16:26<vixey>roconnor cares about gcd 0 0 and he convinced me it should be 0
21:16:26<sjanssen>nobody really cares about MonadPlus v. Monoid
21:16:37<roconnor>ACTION is a nobody
21:16:39<Phyx->MyCatVerbs: but that would be something i could see that you'd want to postpone
21:16:45<copumpkin>sjanssen: no, my point was to create the page so the whining could go to a certain place, so we could stop getting it every few days on IRC and keep track of what really bothers people
21:16:53<copumpkin>I guess I'm a nobody too
21:17:04<hatds>I'm kinda ambivalent about using Monoid everywhere for every binary op
21:17:07<roconnor>sjanssen: actually I think the monadplus v monoid is moderately serious.
21:17:36<copumpkin>I guess monoid isn't in the report itself
21:17:41<copumpkin>but still
21:17:42<sjanssen>I think the different uses for each are very clear
21:18:04<copumpkin>but is there a good reason to keep them separate, other than the fact that it's always been that way?
21:18:06<duaneb>what's a monoid?
21:18:19<glguy>what isn't :P)
21:18:24<sjanssen>copumpkin: look at the Maybe instances for each class
21:18:28<copumpkin>I mean, we also have alternatives
21:18:33<copumpkin>Alternative, that is
21:18:36<sjanssen>copumpkin: they're both useful, and should both be named
21:18:39<hatds>duneb: just a binary operation with identity
21:18:53<sjanssen>copumpkin: Alternative/MonadPlus is the real redundancy
21:19:01<copumpkin>sjanssen: so we do what we did with Sum and Product?
21:19:23<rickasauruss>I’m curious about this idea of arrows as opposed to monad.
21:19:30<copumpkin>I don't see why the entire class should be duplicated because more than one possible instance exists
21:19:42<copumpkin>oh, and ArrowPlus :P
21:19:44<sjanssen>copumpkin: they have different kinds
21:19:53<sjanssen>this is fundamental
21:19:58<rickasauruss>so what is an arrow?
21:20:01<copumpkin>true
21:20:14<copumpkin>it still feels rather dirty to me though
21:20:21<sjanssen>MonadPlus doesn't care about the what's contained, it should be a "shallow" combination of two values
21:20:22<copumpkin>Monoid, Monoid1 :P
21:20:42<sjanssen>Monoid can care about what is contained, it should be a "deep" combination of values
21:20:48<sjanssen>Maybe is a great example of this
21:21:19<hatds>but what about alternative vs plus?
21:21:21<mm_freak>is there some kind of a RS monad? i.e. RWS without W?
21:21:36<glguy>sure, stack statet on readert
21:21:41<sjanssen>hatds: there's a redundancy there, one of them should go away
21:21:49<mm_freak>hmm, that's ugly
21:22:00<glguy>mm_freak, RWS is an abomination
21:22:04<sjanssen>no, RWS is ugly
21:22:08<tomh>mm is there a way to catch an exception thrown by "read" ?
21:22:23<mm_freak>hmm
21:22:28<glguy>tomh, yeah, but it is a bad idea, if you want it to throw IO exceptions, use readIO
21:22:33<sjanssen>tomh: the better thing to do is to inspect the value of 'reads' instead
21:22:34<glguy>if you want to catch it purely, use reads
21:22:35<copumpkin>sjanssen: anyway, the monoids thing was one example, but there is a fair amount of redundancy in the current stdlib, as well as extraneous methods in many classes that make reasonable instances painful, and most people seem to agree on that...
21:22:39<mm_freak>ok, thanks
21:22:56<sjanssen>tomh: case reads foo of [(x, "")] -> success!; _ -> o noes!
21:23:07<tomh>mm
21:23:13<tomh>@src reads
21:23:13<lambdabot>reads = readsPrec minPrec
21:23:14<glguy>async exceptions are a last resort hack
21:23:20<copumpkin>also, ArrowPlus/ArrowZero seem to be pretty similar to MonadPlus/Alternative, too
21:23:22<tomh>:type reads
21:23:22<hatds>copumpkin: which instances for example?
21:23:30<tomh>:t reads
21:23:31<lambdabot>forall a. (Read a) => String -> [(a, String)]
21:23:35<hatds>copumpkin: about being burdensome to create
21:23:57<copumpkin>hatds: the obvious examples are Num
21:24:09<sjanssen>copumpkin: I'm ignorant of Arrow, but again I think it's about the kinds
21:24:14<hatds>@src Num
21:24:14<lambdabot>class (Eq a, Show a) => Num a where
21:24:14<lambdabot> (+), (-), (*) :: a -> a -> a
21:24:14<lambdabot> negate, abs, signum :: a -> a
21:24:14<lambdabot> fromInteger :: Integer -> a
21:24:18<hatds>heh
21:24:57<copumpkin>:k ArrowPlus
21:24:58<lambdabot>Class `ArrowPlus' used as a type
21:24:59<sjanssen>copumpkin: also, Haskell doesn't have type language for the constraint "Monad m, Monoid (forall a. m a)"
21:25:13<copumpkin>yeah, I know
21:25:19<hatds>do any of the standard classes that have Num as a superclass actually *use* signum or abs?
21:25:44<copumpkin>I'll agree that we'd need at least two or three different Monoids for different kind "arities"
21:25:53<copumpkin>in that case I still think they should be named consistently though
21:26:27<sjanssen>copumpkin: anyway, I'm not too hopeful of radical changes like this, since even the conservative Haskell' process doesn't seem to do anything
21:27:00<copumpkin>well, I'd really just like to see the other prelude moved in as a replacement
21:27:03<hatds>it's tempting to try to figure out how it should be even if nothing will happen :/
21:27:11<copumpkin>the numerical typeclasses are what bugs me the most
21:27:19<vixey>sjanssen: shouldn't that be forall a. Monoid (m a)?
21:27:19<vixey>a
21:27:41<copumpkin>that one is possible to write isn't it?
21:27:43<roconnor>we need a set of darcs patches, not a wiki.
21:27:52<hatds>the type family paper gives an example of having implicit conversion for things like (+)
21:28:41<copumpkin>roconnor: well, I guess I'm not arrogant enough after a few months of haskelling to start writing my own standard library, but I have picked up that people find there are shortcomings, and wanted there to be a place to discuss it
21:28:44<zachk>i sort of enjoy the pain of mixing different "?members?" of the Num class
21:28:54<sjanssen>vixey: in English, "given Monad m, (m a) is a Monoid for all a"
21:28:55<roconnor>copumpkin: few months?
21:29:02<roconnor>copumpkin: haven't you been here for years?
21:29:06<copumpkin>lol
21:29:10<copumpkin>should I take that as a compliment?
21:29:22<vixey>sjanssen: so forall a. Monoid (m a)
21:29:32<opqdonut>you might take it as a complement
21:29:37<opqdonut>being copumpkin and all
21:29:42<sjanssen>vixey: where is m bound?
21:29:42<copumpkin>har har :)
21:30:26<sjanssen>vixey: anyway, Haskell can't express this
21:30:58<copumpkin>roconnor: I started learning last december, after glancing over my girlfriend's shoulder for a month or two before that (she was taking a course in it)
21:31:00<hatds>instance Monad m => Monoid (m a)?
21:31:00<vixey>I'm just saying shouldn't the forall be outside 'Monoid' not inside it
21:31:18<glguy>most of these Prelude problems don't show up in big programs
21:31:18<sjanssen>hatds: that outlaws any sort of useful instance
21:31:21<copumpkin>hatds: not sure we'd want that in general
21:31:24<glguy>its the small examples that suffer for them
21:31:35<sjanssen>vixey: yeah, that probably does make more sense
21:31:51<hatds>sjanssen: I'm confused as to what you were saying is different
21:32:04<sjanssen>Monad m, forall a. Monoid (m a) -- more clear
21:32:21<hatds>ah, only particular monads?
21:32:34<sjanssen>hatds: we want to write separate tailor-made instances for particular Monads
21:32:51<duaneb>what is wrong with cabal!?
21:32:58<copumpkin>duaneb: you tell us!
21:32:59<duaneb>it ignores my config
21:33:07<duaneb>and after I install something
21:33:08<copumpkin>duaneb: the config lines are commented out by default
21:33:17<hatds>where would a simple "Monoid (m a) =>" context not be sufficient?
21:33:21<duaneb>it says that it's not installed
21:33:21<copumpkin>duaneb: did you remember to uncomment the line you changed?
21:33:24<copumpkin>oh
21:33:50<sjanssen>hatds: that context means (m a) is a Monoid, but doesn't say anything about (m b), (m c) or (m String)
21:33:53<dcoutts>duaneb: are you mixing up "runghc Setup" with "cabal"
21:34:00<duaneb>no, cabal
21:34:22<dcoutts>duaneb: ok, does ghc-pkg list say the thing is installed? or are we talking about a program?
21:34:27<duaneb>i.e. 'cabal install happy && cabal list happy' says 'Latest version installed: [ Not installed ]'
21:34:41<dcoutts>duaneb: ah, it should say [ unknown ]
21:34:53<dcoutts>it does not track programs, only libs
21:35:03<dcoutts>because only the latter are registered with ghc
21:35:32<sjanssen>hatds: whereas with "MonadPlus m =>" we can use mplus on any type applied to m
21:35:40<duaneb>hmm
21:35:41<duaneb>ok...
21:35:47<hatds>I see
21:36:13<duaneb>ahh
21:36:14<duaneb>well
21:36:20<duaneb>it also ignores my config
21:36:36<dcoutts>duaneb: how so?
21:36:48<duaneb>I have gmp installed in /opt/local/lib
21:36:57<duaneb>and I have that set in my .cabal/config
21:37:01<duaneb>and it STILL won't look there
21:37:35<duaneb>extra-include-dirs: "/opt/local/include"
21:37:38<duaneb>extra-lib-dirs: "/opt/local/lib"
21:38:02<dcoutts>duaneb: is it a package with a ./configure script that fails? perhaps you should use hpaste.org to show us the log
21:38:26<hatds>sjanssen: so they'd have to allow for passing instances, not just passing dictionaries
21:38:32<duaneb>no, it's definitely cabal :P
21:38:37<copumpkin>duaneb: so you uncommented the lines?
21:38:41<duaneb>I mean, it's `cabal install happy`
21:38:42<hatds>sjannsen: er, instance decls
21:38:45<duaneb>copumpkin: yes :P
21:38:52<glguy>ACTION imagines a "really-a-flag" kind of cabal flag
21:39:02<glguy>to compliment the "feel free to ignore this flag" kind
21:39:06<glguy>to get both benefits
21:39:13<copumpkin>:)
21:41:30<roconnor>Heh, SPJ et. all's Type level GCD functions says that the GCD of Zero and Zero is Zero.
21:42:25<copumpkin>good for them :P
21:42:44<copumpkin>is it possible to write non-total type-level functions?
21:42:49<copumpkin>partial, I guess
21:43:00<roconnor>all type level functions are open?
21:43:22<roconnor>so that means it would be impossible to write a total type-level function, if I understand correctly
21:43:27<thoughtpolice>yeah, type families are open
21:43:27<vixey>I don't think. therefore I'm not.
21:43:35<thoughtpolice>so it's possible to have nonsensical instances
21:43:37<copumpkin>ah, that makes sense
21:43:55<hatds>well, excluding type constructors ^_^
21:44:03<vixey>I think that type familes are not 'partial' but they can get stuck
21:44:17<roconnor>oh god, this type level equality has frightening power.
21:44:39<vixey>roconnor: found something neat?
21:45:11<roconnor>just reading the locking/unlocking example in SPJ et al.'s paper
21:45:18<roconnor>well, skimming
21:45:21<thoughtpolice>so, if you have something like 'Flip Even = Odd' and 'Flip Odd = Even', someone can come along and say 'Flip Char = Even', although that would break the invariant 'Flip (Flip x) = x' which is what you need
21:45:40<roconnor>acquire :: (Get n p ~ Unlocked) =>
21:45:42<roconnor>Lock n -> LockM p (Set n Locked p) ()
21:45:52<copumpkin>thoughtpolice: so you'd need KindClasses? :P
21:45:59<vixey>oh cool
21:46:08<copumpkin>or I guess typeclass constraints, only
21:46:16<duaneb>ACTION has bang patterns all over the place
21:46:17<vixey>I've not played with ~ actually only used it implicitly from GADT
21:46:25<monadic_kid>if you're reading fun with fun types, check out boost mpl
21:46:29<thoughtpolice>schrijvers, monnier, etc. describe type invariants, which as far as I can tell essentially give you a form of proofs for type functions
21:46:34<roconnor>mpl?
21:46:42<thoughtpolice>metaprogramming library
21:47:35<thoughtpolice>also, type equality in superclass constraints is also useful from what I've seen, but AFAIK it's still not implemented in HEAD
21:47:47<glguy>are type families still good for writing a->b type coersion functions in 6.10.3?
21:48:06<thoughtpolice>compared to like 6.10.1? probably
21:48:29<thoughtpolice>i don't remember seeing any patches that affect type families significantly going into the 6.10 branch
21:49:43<monadic_kid>roconnor: it's even mentioned in the paper that it's very similar to type computations with templates
21:49:55<thoughtpolice>roconnor: you'd probably like this - http://tomschrijvers.blogspot.com/2008/11/type-invariants-for-haskell.html
21:50:57<burp_>how does cabal check for external c library existance? I'm especially interested in gsl check
21:51:14<glguy>it checks for extenal library existance?
21:51:16<dcoutts>burp_: it makes a c program and compiles it
21:51:49<glguy>is that different than when it fails to find the include files at build time?
21:52:05<dcoutts>glguy: it checks includes and libs at configure time
21:52:24<burp_>it it possible to keep the file it creates to check the existance?
21:52:28<glguy>cool, what version is that in
21:52:40<monadic_kid>typedef find_if< vector<size_t, foo, bar>, is_pod<_1> >::type result_type;
21:52:45<glguy>I always run into the problem when I have the library but not the -devel package
21:52:53<dcoutts>burp_: sadly not, it's on our TODO, since especially the include checks are not fully accurate
21:52:54<glguy>so ghc just fails at compile time
21:53:00<burp_>dcoutts, thats my problem
21:53:22<burp_>gsl check doesn't seem to work here for me
21:53:46<dcoutts>burp_: so if you're sure the header files exist, then it's almost certainly due to the headers not being able to be included on their own, eg requiring other stuff included first.
21:54:13<dcoutts>burp_: see the "includes:" lines in the .cabal file, make a trivial .c file that #includes them in that order, compile it with gcc and see how it fails
21:54:30<burp_>good point, I'll try
21:54:31<thoughtpolice>@seen ndm
21:54:31<lambdabot>I haven't seen ndm.
21:54:36<thoughtpolice>@seen ndmitchell
21:54:36<lambdabot>I haven't seen ndmitchell.
21:54:37<vininim>hilarity: changing from sparse to dense matrix in my octave program got ride of ``out of memory'' error.
21:55:09<thoughtpolice>man i love types
21:55:43<dcoutts>glguy: the check was added in Cabal-1.6.0.2 (which came with ghc-6.10.2)
21:56:32<thoughtpolice>i needed derive to work on lhc, which doesn't work GHC head template haskell changes. after 30 minutes, x changes later, when it compiles, it works.
21:56:43<thoughtpolice>ACTION loves that feeling
21:56:53<burp_>what would it include for gsl?
21:57:03<ajdhs>Is anyone here familiar with QuickCheck?
21:57:06<burp_>kind of #include "gsl.h".. ?
21:57:06<glguy>dcoutts, is there a cabal upgrade --ignore-system-level-packages ?
21:57:37<dcoutts>glguy: you mean, "stick with these versions of these core packages" ?
21:57:52<glguy>dcoutts, yeah, since they seem to break otherwise
21:58:04<dcoutts>glguy: you can use --constraint=
21:58:27<dcoutts>and I think that can go in the cabal config file
21:59:07<ajdhs>so I'm using quickcheck to test some properties on a rather complicated data structure
21:59:09<dcoutts>glguy: I'd appreciate input on the best way to manage that, what the UI should be.
21:59:19<ajdhs>specifically, it's a Data.Map.Map with lots of strings inside
21:59:24<ajdhs>and lots of different values
21:59:32<ajdhs>and long identifiers that can't be entered by hand
21:59:45<dcoutts>glguy: once we've got the data, putting extra constraints into the solver is fairly straightforward
21:59:55<ajdhs>so I'm wondering if there is a way to tell QuickCheck, when it encounters a failure, to give me the actual values that it failed on
21:59:59<ajdhs>as opposed to just printing them out
22:04:15<burp_>damn, I need that file to be kept
22:06:26<burp_>at least it could show why compilation failed
22:06:43<ajdhs>hm
22:06:45<copumpkin>you can ask it to
22:06:50<copumpkin>which file needs keeping?
22:06:56<ajdhs>well, I see that QuickCheck gives me back a StdGen if a test fails
22:07:10<ajdhs>but is there a way to turn the StdGen back into the values that QuickCheck tested?
22:07:39<burp_>the temporary testfile which cabal created to test if the external c library works
22:08:00<duaneb>ok, so I try to run this:
22:08:01<duaneb>http://hpaste.org/save
22:08:04<duaneb>whoops
22:08:04<burp_>I'm trying to get hmatrix working with nix build system
22:08:09<duaneb>this: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4967#a4967
22:08:25<duaneb>and it spits out this: Object.hs:26:32: Not in scope: `a'
22:08:26<dcoutts>burp_: I don't follow, so the cabal configure succeeds?
22:08:31<burp_>nope
22:08:46<duaneb>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4967#a4969
22:09:08<duaneb>is that where not included in the let?
22:10:02<gnuvince_>How does one sort a list by multiple predicates? For example, sorting strings from shortest to longest and in alphabetical order.
22:10:39<vixey>gnuvince_: mappend
22:10:47<Cale>gnuvince_: The monoid instances for Ordering and functions are useful
22:11:10<gnuvince_>@index mappend
22:11:10<lambdabot>Data.Monoid, Control.Monad.Writer, Control.Monad.RWS
22:11:17<Cale>> sortBy (comparing length `mappend` compare) (words "Here is a list of words to sort first by length and then alphabetically.")
22:11:19<lambdabot> ["a","by","is","of","to","and","Here","list","sort","then","first","words",...
22:11:44<Zao>Where by alphabetically considers uppercase before lowercase?
22:11:49<Cale>yeah
22:11:53<Cale>It's just the usual order.
22:12:02<gnuvince_>asciibetically if you will
22:12:03<Cale>> sortBy (comparing length `mappend` comparing (map toLower)) (words "Here is a list of words to sort first by length and then alphabetically.")
22:12:04<lambdabot> ["a","by","is","of","to","and","Here","list","sort","then","first","words",...
22:12:17<Cale>That would be more proper
22:12:22<mrd>> 1+1
22:12:24<lambdabot> 2
22:12:33<duaneb>is there a reason why my let's variables would not extend to the later where?
22:12:36<Cale>> sortBy (comparing length `mappend` comparing (map toLower)) (words "A b C d")
22:12:37<lambdabot> ["A","b","C","d"]
22:12:48<roconnor>duaneb: yes
22:13:31<duaneb>roconnor: care to expand? :P
22:13:32<Cale>duaneb: 'where' scopes over the entire guard block
22:13:40<gnuvince_>@index comparing
22:13:41<lambdabot>bzzt
22:13:41<roconnor>{function param = { expession }} where {where block}
22:13:45<Cale>duaneb: So the 'where' is technically outside the 'let'
22:13:49<copumpkin>Data.Ord iirc
22:13:54<MyCatVerbs>duaneb: let bindings only extend as far as the "in" expression.
22:13:57<duaneb>ahh
22:13:59<roconnor>{function param |guard1 = { expession1 } | guard 2 = {expression2}} where {where block}
22:14:12<duaneb>well, I actually need a 'local' where
22:14:19<roconnor>duaneb: in particular the where block covers all guard conditions.
22:14:21<duaneb>how can I force it into a smaller scope?
22:14:24<Cale>Just put it inside the let
22:14:34<roconnor>> let x = y where y = 3 in x
22:14:36<Cale>I mean, move the definitions into the let
22:14:36<lambdabot> 3
22:14:39<duaneb>just open a guard and have a True function in there?
22:14:45<Cale>hm?
22:15:03<duaneb>Cale: I separated them so that I wouldn't have to calculate them in the case that I returned "Miss"
22:15:09<duaneb>and I plan on stricting them later :P
22:15:20<Cale>duaneb: Things which are defined by let aren't necessarily computed
22:15:45<roconnor>duaneb: there is no way of having the let expression extend to the where clause without putting the where clause into the let expression.
22:15:48<Cale>duaneb: It only makes declarations, it doesn't force them to evaluate
22:16:02<roconnor>> let {x = 7; z = y where y = x} in z
22:16:04<lambdabot> 7
22:17:08<Cale>duaneb: There's no difference between let and where except the scope.
22:17:36<Cale>(in fact, the compiler turns where into let)
22:18:16<duaneb>achh
22:18:25<duaneb>I was using strictness as a way to unbox prettily
22:19:13<roconnor>Cale: we can write where !z = some stupid strict thing ?
22:19:44<burp_>don't say http://code.haskell.org/hmatrix just wen down?
22:19:55<Cale>roconnor: Ah, bang patterns turn into case expressions in that strange corner case, yeah.
22:20:00<burp_>just when I try to work with it
22:22:13<roconnor>burp_: http://code.haskell.org/hmatrix just wen down just when you try to work with it.
22:22:37<burp_>I guess so :(
22:23:50<Phyx->damnabit... i though this "type family RF (a::*->*)" is correct syntax..
22:24:02<korpios>Anyone here successfully use haskell-tyrant? I keep getting an error when trying to run the example code.
22:24:40<vixey>Phyx-: doesn't kind inference get it?
22:25:06<Phyx->vixey: it's giving a parse error, "parse error on input `)'"
22:25:17<vixey>if you use type family RF a ...
22:25:25<vixey>doesn't kind inference figure it out it is * -> *?
22:25:28<Saizan>Phyx-: have you enabled KindOperators ?
22:25:55<Saizan>vixey: in the type family declaration you're never going to use 'a' so i'd be surprised if it does
22:26:05<Phyx->Saizan: it's saying "unsupported extension: KindOperators"
22:26:18<Saizan>Phyx-: sorry, KindSignatures
22:26:27<Phyx->Saizan: yes i have that
22:27:05<Phyx->vixey: using only a it does typecheck, but since i haven't declared any instances yet, i don't know if it'll get the right kind or give me an error later
22:27:23<Saizan>Phyx-: you've to use spaces
22:27:32<Saizan>Phyx-: (a :: * -> *)
22:27:34<vixey>why doesn't type family use
22:27:40<vixey>?
22:28:05<Phyx->Saizan: wow.. that's annoying
22:28:06<Phyx->lol
22:28:07<Phyx->thanks
22:28:58<Saizan>it's actually prettier, imho :)
22:29:40<marcusb>hi again. say I have "data Foo = Bar Int Int | Baz Int Int", shouldn't I be able to map "Bar" and "Baz" (the constructors) to something with say "func :: (Int -> Int -> Foo) -> Bool" "func Bar = True" "func Baz = False" ? But I get a "Couln't match expected type Int -> Int -> Foo against inferred type Foo" error.
22:29:53<Phyx->Saizan: yeah, but i never expected spaces to give errors. but ok,I know now
22:30:55<roconnor>func :: (Int -> Int -> Foo) -> Bool has to work on every function Int -> Int -> Foo, not just the constructors.
22:31:19<roconnor>You could write func :: (Foo) -> Bool
22:31:20<vixey>Baz isn't a pattern
22:31:28<vixey>(Baz x y) is a pattern
22:31:31<roconnor>func (Bar _ _) = True
22:31:32<vixey>you have to fully apply
22:31:37<roconnor>func (Baz _ _) = Falze
22:31:40<roconnor>False
22:31:50<Phyx->can someone actually explain in "(f:: (* -> *)-> * -> *)::(* -> *)-> * -> *" the meaning of :: in this case to me?
22:31:56<Phyx->since it doesn't seem to make sense at all atm
22:32:26<vixey>Phyx- where did you find it
22:32:59<Saizan>it means: f, which has kind (* -> *)-> * -> *, has kind (* -> *)-> * -> *
22:33:01<roconnor>:: means kind of
22:33:09<roconnor>er "has kind"
22:33:09<Phyx->vixey: course outline
22:33:11<roconnor>@kind Maybe
22:33:13<lambdabot>* -> *
22:33:33<Phyx->vixey: isn't that saying things double?
22:33:34<MyCatVerbs>roconnor: cheap strawberries :: yummy.
22:33:47<marcusb>vixey: so type constructors are not first class functions?
22:34:02<vixey>marcusb: what???? lol
22:34:08<marcusb>or mh
22:34:17<marcusb>or is the problem just that I can't match them?
22:34:18<roconnor>marcusb: they are first class functions, however you cannot pattern match on functions.
22:34:23<marcusb>I see.
22:34:25<dsouza>maybe a silly question, but I can't figure why ghc complains when trying to compile this code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4971#a4971
22:34:35<Phyx->vixey: for instance, if i ommit the last ::<etc> shouldn't that say the same thing?
22:34:51<qaz>when doing naive 2D-graphics I often find the painting very slow. I don't see how ti could possibly scale to 3d graphics with loads of things ahppening at the screen.
22:35:00<monadic_kid>marcusb: you mean data constructor, not type constructor
22:35:01<qaz>what is the best way of redrawing a screen?
22:35:07<marcusb>monadic_kid: ok, thanks
22:35:12<Saizan>Phyx-: are you sure that's not part of something larger?
22:35:12<roconnor>marcusb: you can only pattern match on data types, (and you can fake pattern match on Integers and such)
22:35:15<qaz>like just moving an aeroplane on a 2D view and it just goes so slow
22:35:25<qaz>but jumping 5 pixels at the time is not a good solution
22:35:34<marcusb>ok
22:35:40<copumpkin>roconnor: why is it fake?
22:35:45<marcusb>I'll just have to pass through the whole value then
22:35:52<roconnor>copumpkin: because it is really using Eq
22:36:08<vixey>qaz GPU
22:36:09<monadic_kid>marcusb: and data constructor can be treated as normal functions so they can be treated as first-class functions as well
22:36:11<copumpkin>hmm
22:36:26<marcusb>monadic_kid: yes, my confusion was that I tried to pattern match them
22:36:40<marcusb>because I can pattern match the data I was confused
22:37:02<Phyx->Saizan: larger as in? only thing i didn't paste was the type family name, It's just the first time i've seen :: after a ::, lol. Though i haven't used type families alot
22:37:03<marcusb>it makes sense that I can't pattern match on function names
22:37:04<roconnor>copumpkin: for example you could "pattern match" with 7 on a function if the function type was an instance of Num (I believe).
22:37:13<copumpkin>interesting
22:37:29<roconnor>but it would use the Eq instance of the function.
22:37:41<qaz>vixey: not using normal processor but graphics processor instead? and how do I do that? doesnt ti happen automatically with openGL?
22:37:42<roconnor>whatever that would do.
22:37:51<monadic_kid>marcusb: "func :: Foo -> Bool" func Bar _ _ = True func Baz _ _ = False
22:37:54<vixey>yes
22:37:56<MyCatVerbs>roconnor: you can't define Num on functions because Num requires Eq, though.
22:38:04<Saizan>Phyx-: type family Foo (f :: ( * -> *) -> * -> *) :: (* -> *) -> * -> * means something else.
22:38:30<roconnor>MyCatVerbs: you can make an Eq instance for functions whose domain is compact.
22:38:33<Saizan>Phyx-: it means that Foo takes an index of kind (* -> *) -> * -> * and returns a type of the same kind
22:38:44<Phyx->Saizan: do you have a paper or a link that i can read more about it?
22:39:03<marcusb>what I wanted to do is to convert data Exp = Mul Int Int | Add Int Int to "a * b" and "a + b" with "op val1 val2 = (show val1) ++ op_to_string (op) ++ (show val2) where op_to_string maps Mul to "*" and Add to "+"
22:39:10<Saizan>Phyx-: search for type families in the haskell wiki
22:39:16<roconnor>MyCatVerbs: Making Bool -> Int and instance of Num wouldn't be totally insane. Just a little insane.
22:39:23<Phyx->Saizan: ok, cool, thanks
22:40:30<monadic_kid>marcusb: you mean you want' t define + and * as data constructors?
22:40:40<marcusb>monadic_kid: no just for pretty printing
22:41:05<roconnor>marcusb: you can write op_to_string(op val1 val2)
22:41:22<Axman6>marcusb: take a look at real world haskell, they do just that
22:41:27<roconnor>marcusb: well, not quite like that
22:41:38<MyCatVerbs>roconnor: ah, yes, I suppose. What does the term "compact" mean when applied to a set?
22:42:03<roconnor>MyCatVerbs: um, good question.
22:42:14<marcusb>roconnor: yes, I realize that now. it would be nice somehow to ask a function what it thinks it is and get some kind of differentiating response
22:42:30<marcusb>but it doesn't work in general of course
22:42:55<roconnor>marcusb: what you are doing is fairly common, but you are sort of doing it the wrong way here.
22:43:16<marcusb>roconnor: what's the right way? :)
22:43:44<roconnor>show (Mul a b) = showInfix "*" a b
22:43:57<roconnor>show (Add a b) = showInfix "+" a b
22:43:59<roconnor>...
22:44:37<roconnor>others may suggest slight variations on this.
22:45:08<marcusb>yeah. well, two problems here. I don't want to change the default view, but apart from that, I just tried to generalize/refactor binary operators and operator names
22:45:20<marcusb>it seemed dull to repeat the same rule over and over again
22:46:19<marcusb>but yeah, I think I was overdoing it
22:47:49<roconnor>marcusb: there is no way out unless you are willing to guarentee that every constructor for Exp has exactly two Int parameters
22:47:56<marcusb>yeah
22:48:01<roconnor>and even then you still have to write the same amount of code, if not more.
22:48:01<marcusb>roconnor: thanks for the light
22:48:12<roconnor>and it will be less general
22:48:17<marcusb>showInfix is a nice touch, that actually removes most of the boilerplate I was worried about
22:48:19<roconnor>and more dangerous
22:48:29<roconnor>marcusb: that's good.
22:48:49<marcusb>is showInfix a standard function?
22:48:54<roconnor>no
22:48:58<marcusb>ok
22:50:05<dsouza>could someone give some pointers why can't compile this code on ghc? -> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=4971#a4971
22:51:02<qaz>@type showInfix
22:51:03<lambdabot>Not in scope: `showInfix'
22:51:03<dsouza>I could't undestand the reason this fails
22:51:17<qaz>> ((+1) *** (+3)) $ 3
22:51:18<lambdabot> No instance for (Num (b, b'))
22:51:18<lambdabot> arising from the literal `3' at <i...
22:51:20<qaz>> ((+1) *** (+3)) $ (3,4)
22:51:21<lambdabot> (4,7)
22:51:26<qaz>> ((+1) &&& (+3)) $ 3
22:51:27<lambdabot> (4,6)
22:51:38<qaz>> ((+1) &&& (+3)) <$> [1,2,3]
22:51:39<lambdabot> [(2,4),(3,5),(4,6)]
22:52:20<augustss>dsouza: because magnitude has type a->b
22:52:22<dsouza>s/could't/couldn't/
22:52:34<roconnor>dsouza: as it stands your magnitude function has to return any type of floating type.
22:52:46<roconnor>dsouza: but your instance only returns one type of floating instance.
22:53:00<augustss>dsouza: Looking at the instance I'd say it has type Vector a -> a
22:53:02<roconnor>dsouza: you need to use type families :)
22:53:09<augustss>VectorT a -> a
22:53:13<roconnor>er
22:53:14<roconnor>ya
22:53:16<roconnor>sorry
22:53:21<roconnor>dsouza: listen to augustss
22:53:32<roconnor>I have too much type family on my brain.
22:53:49<dsouza>I have the empty set in mine :-)
22:54:14<roconnor>hmm
22:54:21<augustss_>dsouza: Perhaps yoo want: class Vector v where magnitude :: v a -> a
22:54:50<duaneb>so how can I get the haskell equivalent of DBL_MAX
22:55:11<augustss_>dsouza: And then: instance Vector VectorT where ...
22:55:15<roconnor>> maxBound :: Double
22:55:17<lambdabot> No instance for (Bounded Double)
22:55:17<lambdabot> arising from a use of `maxBound...
22:55:20<duaneb>maxBound
22:55:48<augustss_>duaneb: It's a bit fiddle, you need to extract the maximum exponent and construct the maximum mantissa
22:55:51<duaneb>damn.
22:55:52<augustss_>fiddly
22:55:54<dsouza>augustss_: but in this case, if for any reason I created an VectorT Int,
22:56:05<duaneb>augustss: yea, but shouldn't it be defined somewhere
22:56:07<dsouza>that magnitute would fail because of sqrt. is it right?
22:56:32<augustss_>dsouza: I meant: instance (Floating a) => Vector VectorT where ...
22:56:40<duaneb>I happen to know that the max is 1.7976931348623157e+308 on my machine
22:56:44<augustss_>duaneb: It should, but I don't know that it is
22:57:12<augustss_>duaneb: It would be a good thing to write generically and put on hackage