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> | Im 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 |