Experimental IRC log haskell-2009-05-19

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:07<c_wraith>kyevan: It's not associating line 12 with the do because line 12 isn't indented further than the function name
00:00:15<Ralith>f [] = [] f ((a,b,c):xs) = a:b:c:(f xs)
00:00:22<pejo>This question with using tuples the same way as lists has come up several times in my limited time here for the last day. Where does the idea come from?
00:00:24<Ralith>er, stick a semicolon after second []
00:00:55<Jedai>TonyTheTiger: Normally you know the length of your tuple beforehand (since Haskell is a statically typed language), so you can use an explicit recursion or a concatMap
00:01:00<c_wraith>kyevan: So it's assuming line 12 is another function declaration in the where block, hence the "do" has an empty body
00:01:07<Cale>[u | (x,y,z) <- xs, u <- [x,y,z]] or concatMap (\(x,y,z) -> [x,y,z]) xs
00:01:19<TonyTheTiger>Jedai: I know my tuples are doubles
00:01:40<kyevan>c_wraith: I have no clue what's going on. Is the fix to insert six more spaces on each of the lines 12 and after?
00:01:43<Jedai>TonyTheTiger: We already answered this question earlier then...
00:02:09<TonyTheTiger>Cale: is what your wrote for me?
00:02:15<c_wraith>kyevan: But not lines 17 and 18, since those aren't part of the body of the do block
00:02:17<Cale>TonyTheTiger: yeah
00:02:32<kyevan>Uh... okay...
00:03:32<lament>the idea of using tuples the same way as lists probably comes from python :)
00:03:55<kyevan>Now I get InteractWith.hs:12:7: The last statement in a 'do' construct must be an expression
00:04:24<kyevan>12:7 is a random space in the middle of nowhere... what the...?
00:04:48<persica>kyevan: sounds like you didn't end the do block properly so it doesn't know what to return?
00:05:13<kyevan>persica: How do I fix it!?
00:05:18<persica>kyevan: Going through RWH?
00:05:23<kyevan>Yes :(
00:05:34<persica>what chapter is this again?
00:05:45<kyevan>Chapter four, the very start.
00:06:09<kyevan>Argh...
00:06:21<kyevan>The book is wrong, and layout in print is impossible to read to begin with >_>
00:06:27<c_wraith>kyevan: The layout makes a lot more sense if you put the "where" on a line by itself
00:06:34<c_wraith>And indent another level past that
00:06:44<kyevan>c_wraith: Wha?
00:06:47<c_wraith>Then you can just indent two spaces on every line
00:07:03<kyevan>Tell me where to put the cursor and what buttons to push! *confused as hell*
00:07:03<c_wraith>make line 11 *just* " where"
00:07:10<Cale>Baughn: it works
00:07:20<Hunner>ACTION spent 3 days trying to track down bugs in his code only to find out that quickcheck 2.1 was the problem :(
00:07:20<Cale>Baughn: in 6.10.3
00:07:32<c_wraith>make line 12 start " mainWith function = do"
00:07:39<c_wraith>And then indent as appropriate below that
00:07:54<persica>Basically he's saying you can make the where be on its own line.
00:07:56<Baughn>Cale: So I guess that's one of the things under "misc. bugfixes"
00:08:01<persica>Haskell is sensitive to indentation.
00:08:02<Cale>kyevan: Is your code pasted somewhere? I will indent it correctly for you, if you like.
00:08:12<Baughn>Cale: Good thing, too. I was afraid I'd have to delve into slimy guts.
00:08:17<persica>I just copied an pasted from the online version and it works fine...
00:08:38<kyevan>cale: http://pastie.textmate.org/private/bqeklpelu7tcaj8q6ikp6a
00:08:44<kyevan>There's an online version?
00:09:00<persica>http://book.realworldhaskell.org/read/
00:09:08<pejo>Cale/Baughn, wasn't this the finalizer change with some things that was necessary for unamb? I think Conal was mentioned by one mail from Simon Marlow
00:09:11<persica>has comments too, if you have javascript enabled.
00:09:23<Baughn>Cale: ..way to go getting my hopes up. It only works without -threaded. ;_;
00:09:38<Baughn>That /definitely/ makes it a ghc bug, though
00:09:42<persica>kyevan: looks like myFunction is on the same line as "args" and "case"
00:09:51<Cale>kyevan: the problem is the contents of your do-block are outside the 'where'
00:10:01<TonyTheTiger>Type error in generator <-- im getting this error
00:10:06<persica>kyevan: technically myFunction is part of the "where" while "args" and "case" are in the do block.
00:10:08<kyevan>How am I supposed to know that!?!?
00:10:14<kyevan>I'm just retyping from a book
00:10:20<kyevan>I don't know how any of this works
00:10:44<persica>kyevan: You read compiler warnings... lots of compiler warnings. I personally don't like that example either. Why not just make "main = do..."
00:10:53<kyevan>I'm only just not crying right now... ARGH, this is really not reflecting well on haskell.
00:10:56<Cale>kyevan: The first non-whitespace character after the 'where' keyword determines the column that things have to line up with in order to be inside the 'where'
00:11:18<Cale>kyevan: if any line is indented less than that, the 'where' ends.
00:11:34<kyevan>o...kay...?
00:11:43<blackh>kyevan: Learn the indenting rule and all your problems will disappear.
00:11:44<Cale>I'll give you a version with how I'd indent it.
00:11:55<persica>Cale: technically the next non-whitespace character on a line after the where assuming it is not earlier in the line than the where itself. Correct?
00:11:59<kyevan>blackh: TGHREIPASO'tyug78 9zxxeruilsbxwegd6rtuc[jzxuivntpszv4890eb5ytvlsnbe479tonlerzxcb8yh0lzr89tcnl\
00:12:06<c_wraith>It's probably simplest to just use a text editor that at least tries to indent correctly.
00:12:43<TonyTheTiger>kyevan: these guys are the most helpful amongst irc forums, be patient and you will understand eventually.
00:12:52<kyevan>blackh: I'M JUST TRYING TO COPY FROM A BOOK!
00:12:54<hatds>persica: yes, that's right. There are always two columns you have to keep in mind when parsing your layout
00:13:01<ray>i don't like hanging 'do's
00:13:02<Cale>http://pastie.textmate.org/482253
00:13:11<kyevan>It says "just copy this for now and we'll explain later"
00:13:12<Baughn>conal: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5018#a5018 <-- This code fails completely on 6.10.2. On 10.3, it works without -threaded but not with. (Ideas?)
00:13:19<kyevan>Why is this all so confusing? :(
00:13:23<blackh>kyevan: The four magic keywords are: do, let, where and of
00:13:53<persica>kyevan: Because learning how to program with awesome requires you unlearn all you knew about lameness.
00:14:01<hatds>I think the fact that you have to consider both the enclosing layout width and the new width is what trips people up
00:14:17<blackh>kyevan: The indenting level of the first non-whitespace character after any of these keyword is the important thing.
00:14:47<hatds>also 'do' has a little more relaxed layout rule, iirc
00:14:54<kyevan>persica: But then, why doesn't it explain this before you have to use it... and... but... wha... za... hug
00:14:57<kyevan>>_<
00:14:59<blackh>kyevan: Everything that lines up with that character is in that keyword's block.
00:15:27<kyevan>I don't even know what two of those four do. >_>
00:15:28<persica>kyevan: RWH does sort of dump a lot on you at the start, but that's so you can start with examples of stuff that actually works right away.
00:15:29<hatds>are there programs which parse layout in a visual way for people to learn from?
00:15:57<kyevan>persica: Dumping is fine, but can't it *tell you* what it's dumping on you, instead of saying t
00:16:01<monadic_kid>hatds: there is blog with coloring for tabs and spaces
00:16:03<bremner>hatds: yes, by kyevan hates emacs
00:16:04<kyevan>"Type this, and pray a lot!"?
00:16:19<persica>kyevan: I really like RWH as a way to learn. If it's confusing, refer to the comments in the online version. :D
00:16:36<blackh>kyevan: We'll help as much as we can.
00:17:19<blackh>kyevan: You really have to know the indenting rule, though, otherwise you'll go nuts.
00:17:24<kyevan>What online version, persica?
00:17:31<ray>my theory is that layout gets confusing when any of the whitespace characters before that first magic non-whitespace character are newlines
00:18:10<hatds>ha, I don't think I've ever used layout with extra newlines
00:18:18<kyevan>But, yeah. For reference, what's going through my head right now is basically "And I thought PYTHON was bad."
00:18:34<persica>kyevan: I thought I linked. http://book.realworldhaskell.org/read/functional-programming.html
00:19:08<kyevan>persica: I must have missed it
00:19:19<ray>there's this irrational prejudice against meaningful whitespace too, but i think haskell layout when people stick those extra newlines in there is actually confusing
00:19:27<persica>hatds: I seem to be using a lot of newlines after '=' and "do" just to keep things from going off the right side of my editor. :D
00:19:29<hatds>I think it is best to just read formal rules in the Haskell report on layout
00:19:49<ray>sure, if you read formal rules
00:20:00<ray>i do, but i had to learn to be able to read them first
00:20:04<c_wraith>Or you could just use explicit { ; } syntax.
00:20:21<c_wraith>It's not as pretty, but it doesn't have any confusing rules
00:20:31<monadic_kid>i found it, this has visual representation of using tabs and spaces: http://urchin.earth.li/~ian/style/haskell.html
00:20:35<TonyTheTiger>hi i am getting an error "Type error in generator" here is my code http://pastebin.com/dc177a0 can someone help please?
00:20:52<hatds>persica: I was thinking of putting *extra* newlines beyond what's necessary to avoid word wrap. I usually leave "do" by itself at the end of the line. For '=' I just give names to sub expressions instead.
00:21:14<blackh>kyevan: With Haskell, you'll get a very sore head at first, but it becomes *very* pleasant later, when you realize that the compiler has taken a lot of the annoying work (such as debugging) away from you.
00:21:15<monadic_kid>kyevan: http://urchin.earth.li/~ian/style/haskell.html
00:21:17<hatds>persica: admittedly you could put filler lines though, which I find amusing
00:21:52<persica>hatds: Yeah, that sounds odd. I feel like all parts of the function should be on consecutive newlines.
00:21:53<kyevan>blackh: And instead given me an utterly insane set of layout rules that aren't yet explained but I'm expected to know :P
00:22:12<kyevan>The two seem rather unrelated... so yeah >_>
00:22:27<kyevan>ACTION has a working copy of the black box now, though, so yay :J
00:22:45<monadic_kid>what are you using to code in anyways?
00:22:48<blackh>kyevan: The author of the book is here, so your comments will be acted on, I'm sure. I personally think you absolutely must teach the indenting rule - it's impossible to write Haskell if you don't know it.
00:23:06<blackh>kyevan: I can summarize it again if you want me to.
00:23:18<monadic_kid>blackh: IDE/editors make you pretty ignorant of it
00:23:52<hatds>that's not my experience, but I'm using notepad
00:23:54<hatds>:)
00:24:01<ray>i never found it hard, and i never left keywords hanging like lots of people do either
00:24:03<kyevan>blackh: Well, it says "We'll talk about it more in chapter 7". So It'll get there eventually, but... >_>
00:24:11<TonyTheTiger>I am getting an error "Type error in generator" here is my code http://pastebin.com/dc177a0 can someone help please?
00:24:13<c_wraith>monadic_kid: That page seems broken. Shouldn't it have tabs colored differently than spaces? It doesn't appear to on my browser.
00:24:36<kyevan>Why are Haskell's rules for indents so weird, though?
00:24:42<hatds>they aren't, really
00:24:45<monadic_kid>c_wraith: it should do, i'm using firefox
00:24:50<ray>your browser is broken
00:24:59<ray>monadic_kid: so is your browser ;)
00:24:59<hatds>but teachers overestimate how simple they are
00:25:00<blackh>kyevan: There is a madness to the method! It's all to do with keeping the code free of 'cruft' like { ; }
00:25:07<hatds>er not simple
00:25:08<persica>kyevan: Does the section "The offside rule and white space in an expression" in Ch3 answer your questions about layout?
00:25:20<kyevan>blackh: Have you ever played with Python?
00:25:21<c_wraith>monadic_kid: I'm on firefox 3.0.10 on OSX, and seeing no background colors whatsoever on that page
00:25:25<blackh>kyevan: Yes, lots
00:25:36<kyevan>If not, I'm going to ignore that line as moronic. You don't have to have weird rules to do that.
00:25:51<c_wraith>monadic_kid: Seems I failed to load a stylesheet. Wonder why.
00:26:04<kyevan>Python's are trivial. To go 'in' a block, indent to the right. To go up, go back to the left. Done.
00:26:31<blackh>kyevan: I think Haskell's rule was invented before Python's so Haskell couldn't base it on 'common practice'
00:27:01<persica>kyevan: http://book.realworldhaskell.org/read/defining-types-streamlining-functions.html#deftypes.offside
00:27:03<Jedai>kyevan: rules in Haskell aren't much more complicated than Python
00:27:05<c_wraith>kyevan: That's not *quite* as clear in haskell, because there's no clear rule about what starts a block
00:27:10<kyevan>Sure it could, that style of indent has been common practice for justabout ever :P
00:27:12<monadic_kid>i've never had issues with layout rules in haskell
00:27:27<ray>i think :s start a block in python, which is the *real* ugly part
00:27:28<c_wraith>You don't get python's clean "if the line ends with ':', indent further the next line" rule
00:27:36<Jedai>kyevan: I never had any problem whith layout in Haskell
00:27:40<ray>there's nothing ugly about indentation
00:27:56<c_wraith>Really, just use an editor that knows something about haskell layout, and you won't have issues.
00:27:57<kyevan>Sure, but those four keywords, you indent further on the next line.
00:27:59<kyevan>That would work >_>
00:27:59<FunctorSalad>the last statement in a do expression must be a value....
00:28:04<blackh>kyevan: Even if Haskell's rule is ill-conceived, the good things in Haskell hugely outweigh it. :)
00:28:07<kyevan>c_wraith: I'm using textmate. >_>
00:28:15<FunctorSalad>(that one seems to be a common bogus error msg with layout)
00:28:34<ray>haskell is good at bogus error messages
00:28:43<Jedai>blackh: I like those rules, they're pretty simple in my opinion and allow for more flexibility than Python
00:28:55<c_wraith>monadic_kid: that page totally fails at loading the stylesheet for me, and I have no clue why
00:29:08<Cale>kyevan: I basically follow a much stronger rule than the real one, which is that the inside of a let, do, where, or of must be indented more than that keyword.
00:29:19<monadic_kid>c_wraith: yes I saw message the first time, i don't know what to say it's not my webpage
00:29:42<c_wraith>strange. I can't even debug it. I'm sure it's a problem on my end, given that.
00:29:42<kyevan>Okay... I still think it could be simplified >_>
00:29:52<rzezeski>Haskell's "broken" indentation scheme would be like a broken window on a 5 million dollar home. Sure, it's a friggen' sore, but no need to throw the baby out w/ the bath water :)
00:30:13<Cale>I don't think Haskell's indentation rule is broken.
00:30:15<ray>i think your alleged broken window is actually a stained glass window
00:30:20<Cale>But it allows more than it should.
00:30:24<Jedai>rzezeski: I don't find the indentation scheme broken... I like it very much
00:30:31<monadic_kid>kyevan: does textmate actually suport haskell? just syntax highlighting?
00:30:50<Jedai>rzezeski: And I never had any problem with it
00:30:58<Cale>For example, I think it should be extended to apply to if, forcing 'then' and 'else' to be indented by the same amount if they occur on separate lines.
00:31:08<persica>The indentation rules make perfect sense. They're a shortcut you can use instead ofusing {} and ;. And the have the benefit of (generally) making code more legible.
00:31:10<Cale>(and more than the 'if' itself)
00:31:12<rzezeski>guys, I put "broken" in quotes, I'm trying to make an analogy that w/ patience kyevan will overlook his worries about the indentation
00:31:16<ray>cale: i do the opposite and follow the degenerate layout rule of "make stuff line up"
00:31:18<blackh>kyevan: If you consider the identing design bad, it's not a sign of a bad design: Haskell is probably one of the cleanest, simplest and most consistently designed languages.
00:31:23<ray>but i don't encounter problems
00:31:32<kyevan>rzezeski: So, it';s something that should be replaced ASAP. Haskell's been around *how* long? :P
00:31:34<Cale>ray: Yes, I make stuff line up too ;)
00:31:44<persica>ray: I would even go as far to say I just "make stuff pretty." which just happens to include lining up.
00:31:52<Jedai>kyevan: No, the indentation scheme is perfectly fine...
00:31:56<blackh>kyevan: Strangely one thing I don't like about Python is the fact that 'print' doesn't require parentheses for its argument but every other function does. Haskell doesn't have any inconsistencies like that.
00:31:57<kyevan>persica: I'm not saying meaningful indentation is bad...
00:32:08<kyevan>I'm saying *haskell's implementation* is :P
00:32:16<kyevan>blackh: Python 3.0 changes that
00:32:26<Jedai>kyevan: You're unfamiliar with it, that's all
00:32:36<ray>the real ugly part about python is the :s at the end of some stuff
00:32:50<Cale>I always put the first line of a 'do', 'let', or 'of' on the same line as that keyword, and this is usually the case with 'where' as well.
00:32:52<ray>it could be triggered by keywords like haskell
00:32:58<Jedai>kyevan: And nobody explained it to you clearly, it's not the fault of the layout
00:33:02<rzezeski>kyevan, there are warts in every language, and different for every person, all I'm saying is don't let it dissuade you
00:33:06<ray>cale: my theory is that that avoids problems
00:33:08<persica>kyevan: I don't see how it's bad. It could be simply stated as "anything that woudl be inside a {} needs to be indented more than the line containing the { and all lines in the same {} need to have the same indentation.
00:33:34<kyevan>persica: No it couldn't
00:33:43<kyevan>Mine obeyed those rules and didn't work
00:34:14<kyevan>(Ignoring the thing that was indented in the text and wasn't supposed to be, that's *not* my fault in even the vaugest sense)
00:34:19<blackh>kyevan: Like rzezeski said, don't let it dissuade you or you would be missing out on something wonderful.
00:34:23<persica>kyevan: I think your problem is that program that has that line which is actually part of the where-block but is easy to confuse as being in the do-block.
00:34:31<Jedai>kyevan: I doubt that... Could you post your code ?
00:34:52<Cale>kyevan: If you follow the rule that if something is to be the child of something else then it should be indented more, and if they are siblings, they should start in the same column, then you should have no issues.
00:35:04<persica>Jedai: he posted http://pastie.textmate.org/482253 before.
00:35:26<Cale>That looks like my paste
00:35:29<kyevan>Third time: http://pastie.textmate.org/private/bqeklpelu7tcaj8q6ikp6a
00:35:36<persica>yeah, must have had the wrong one.
00:36:06<persica>See, all he did was accidentally put the "myFunction = id" line from the where statement on the same indentation as the do block.
00:36:07<Cale>Yeah, in kyevan's, the problem is that args <- getArgs starts on a shallower column than mainWith function = ...
00:36:18<kyevan>No it doesn't.
00:36:24<kyevan>It's indented more than that line.
00:36:24<Cale>Yes it does.
00:36:36<Cale>It's not the *line's* indentation that matters
00:36:37<rzezeski>kyevan, you using hard tabs?
00:36:42<Cale>It's the column that it starts on
00:36:43<blackh>kyevan: the first non-whitespace character after "where" is 'm'. Things inside the where block can't be indented less than the 'm'
00:36:48<kyevan>rzezeski: No, I don't?
00:36:54<Jedai>kyevan: Right, so your code didn't respect the rules given by persica...
00:37:16<monadic_kid>does anyone know what are those fonts being used in pastie.tetmate.org?
00:37:18<Cale>kyevan: The definition starts "mainWith function = "
00:37:23<kyevan>Persica said: I don't see how it's bad. It could be simply stated as "anything that woudl be inside a {} needs to be indented more than the line containing the { and all lines in the same {} need to have the same indentation.
00:37:29<kyevan>The line is indented 0 spaces
00:37:34<kyevan>I indented two spaces.
00:37:39<monadic_kid>they look like gedit fonts, i love them. I wish i knew what there exact name was
00:37:54<Jedai>kyevan: You accidentaly thought that myFunction was part of the do block, that was the problem, not the indentation scheme itself
00:37:56<kyevan>Haskell doesn't redefine less than and greater than, does it?
00:37:59<Cale>kyevan: Lines that are part of that definition have to start on a column which is past the "m" in "mainWith"
00:38:07<kyevan>Jedai: THAT was already covered
00:38:14<kyevan>Even fixing that it doesn't change it.
00:38:15<Cale>kyevan: Does that make sense?
00:38:20<Cale>(are you reading what I wrote?)
00:38:36<kyevan>Cale: YES I KNOW I'M SAYING THAT PERSICA'S SIMPLIFICATION WAS INCORRECT!
00:38:47<Cale>My simplification though is correct.
00:38:54<kyevan>Are you Persica?
00:39:02<Jedai>kyevan: The second part of the rule given by persica cover that : myFunction and mainWith being part of the same {} should have the same indentation
00:39:21<kyevan>Yes, I KNOW
00:39:22<persica>kyevan: You're right, I'm wrong about that.
00:39:38<kyevan>That was an error in the book, and I ALREADY SAID that even correcting that it was still broken
00:39:42<persica>Guess it just doesn't come up for me with the way I usually do it. :D
00:39:56<persica>When I copy-and-pasted straight from the book it worked fine. :D
00:40:06<kyevan>You can't copy and paste from paper
00:40:07<persica>Though it was probably updated.
00:40:20<persica>From the online version I can.
00:40:31<kyevan>Which I didn't know about so wasn't using.
00:40:41<kyevan>Are you TRYING to make me look like an idiot!?
00:41:00<kyevan>"HURR I DON'T LIKE THIS LET'S CHANGE IT" wasn't what I did >_>
00:42:01<Cale>kyevan: It's okay, really ;)
00:42:04<monadic_kid>does textmate actually have a haskell mode or is just syntax highlighting, even if you just use tabes only it should still be fine
00:42:21<blackh>kyevan: The printed book is actually correct, but of course it won't work unless the indenting is exactly as printed. You can't expect anyone to do that without knowing the indenting rule.
00:42:29<jinho>if I have a function description like: String -> (Int -> Int) -> Int, does this mean that the function takes a String and a function (which takes an Int and gives back an Int) and gives back an Int?
00:42:38<persica>kyevan: Ah, perhaps I was trying to defend my action the same way you seem to be defending yours? Don't take it personally.
00:42:44<Cale>jinho: yes
00:42:49<monadic_kid>jinho: ja
00:42:54<jinho>it all makes sense now
00:42:55<jinho>thanks
00:42:56<kyevan>monadic_kid: I don't thing the bundle includes layout rules.
00:43:12<kyevan>It does include a bit more than "just highlighting" though :J
00:43:17<monadic_kid>jinho: but you know the arrow operator is right associative ;)
00:43:30<kyevan>Also, this was originally written in another editor. :J
00:43:55<jinho>monadic_kid: can you explain the ramifications of that?
00:44:03<monadic_kid>jinho: so it's really String > ((Int -> Int) -> Int)
00:44:39<jinho>monadic_kid: am I still trying to read this left to right? (just like I would a math expression?)
00:45:18<kyevan>The currying-before-display is annoying... >_>
00:45:39<monadic_kid>jinho: all functions are functions of one argument, when you write a function with multiple parameters it's just syntatic sugar, it's really a function with one argument and returns a function
00:45:44<Cale>jinho: Well, it just means that it's *also* a function which takes a String and produces: a function which takes a function (Int -> Int) and produces an Int
00:46:16<Cale>jinho: When you write something like f x y z in Haskell, you're actually writing ((f x) y) z
00:46:23<monadic_kid>jinho: haskell functions are curried
00:47:23<Cale>This is cool, because it makes it easy to get another function by applying a function to just the first few of its parameters
00:47:38<Cale>> map (map (*2)) [[1,2,3],[4,5],[6,7,8]]
00:47:39<lambdabot> [[2,4,6],[8,10],[12,14,16]]
00:47:52<Cale>Which is very useful for higher-order functions.
00:48:08<kyevan>Yeah, what
00:48:09<kyevan>er
00:48:26<kyevan>What TextMate does is it follows the indent rules for other languages.
00:48:58<kyevan>(IE, after a line including do, let, or where, indent one tab(which I have set to two-space soft tabs))
00:49:26<jinho>monadic_kid: but then a function f, which has been described as String -> (Int -> Int) -> Int is really only going to take a String and (Int -> Int) as arguments right?
00:49:38<Jedai>kyevan: You mean it doesn't understand that do/let/where/of introduce a new block and so it doesn't use the right indentation ?
00:50:17<kyevan>No, it undestands that, and it indents.
00:50:32<kyevan>It doesn't do Haskell's weird indent-more-than-once.
00:50:37<shachaf>jinho: It "really" only takes a String as an argument, since all functions have one argument.
00:50:46<jinho>shachaf: right
00:50:49<kyevan>(This is with the Haskell bundle, of course)
00:51:12<Jedai>kyevan: What are you calling indent-more-than-once ?
00:51:12<shachaf>jinho: Haskell's syntax happens to make it look like it can take two arguments at once. :-)
00:51:34<monadic_kid>jinho: what do you mean by really? String -> ((Int -> Int) -> Int), it's a function of argument reutrning a function that takes a function as a parameter, so when apply the function once and apply the function which gets return it's the same as multiple parameters being applied. Syntatic sugar
00:51:47<kyevan>Indenting once:
00:51:48<kyevan> where mainWith function = do
00:51:48<kyevan> args <- getArgs
00:51:48<kyevan>Indenting more than once:
00:51:48<kyevan> where mainWith function = do
00:51:48<kyevan> args <- getArgs
00:52:03<jinho>monadic_kid: I guess I'm still hung on you saying that the "->" is right associative
00:52:11<monadic_kid>jinho: it is!
00:52:26<jinho>monadic_kid: oh I'm not saying I don't believe it- I'm saying I don't see it
00:52:28<Jedai>kyevan: Ok... So it indents incorrectly, doesn't it ?
00:52:32<blackh>kyevan: No - you need to indent once more! 'a' is still left of 'm'
00:52:39<persica>jinho: if you have "f a b", where f is of type a -> b -> c. It will first evaluate "f a" and produce a new function g, of type b -> c. Then it will be left with "g b".
00:52:46<c_wraith>jinho: a -> b -> c is the same as a -> (b -> c)
00:52:47<jinho>my faith is better than my understanding at this point =)
00:52:50<kyevan>blackh: Er, what?
00:53:02<persica>oh, di dI get it the wrong way around?
00:53:16<Jedai>kyevan: I wonder if that's an inherent weakness of Textmate or just a lack of work on the Haskell bundle...
00:53:36<Jedai>kyevan: I don't have a Mac so I can't check it
00:53:44<blackh>kyevan: Well, I could have it wrong myself, I don't know. See if the compiler likes it. You also want 'myFunction' to line up with 'mainWith'
00:53:49<shachaf>jinho: "f x y = x + y" === "f = (\x -> (\y -> (x + y))"
00:54:10<jinho>ah - so when you say right associative, you're really saying I should be thinking of this in terms of currying
00:54:21<monadic_kid>jinho: ja
00:54:22<kyevan>blackh: Do you mean the first is wrong, or the second? If it's the second, you're using a non-monospace font :P
00:54:35<monadic_kid>jinho: but the arrow operator really is right associtive
00:54:40<kyevan>The first, *I KNOW* is wrong :P
00:54:42<blackh>kyevan: Ah, that's what it'll be - of course.
00:54:43<jinho>monadic_kid: gotcha
00:54:55<jinho>monadic_kid: whereas $ is left-associative?
00:54:58<Cale>jinho: Rather, you may think of that way at any point that it suits you :)
00:55:00<monadic_kid>jinho: yep
00:55:14<kyevan>Actually, that's another problem with Haskell's way. >_>
00:55:14<jinho>Cale: will do
00:55:18<Cale>$ *ought* to be left associative, but it is not.
00:55:25<kyevan>It's *impossible* to use layout with a proportional font
00:55:28<jinho>oh brother...
00:55:33<Cale>But plain function application is left associative.
00:55:42<monadic_kid>ah yes
00:55:46<monadic_kid>then it all fits
00:56:20<Jedai>kyevan: Well I don't know many programmer that use a proportional font, whatever the language : it always mess up the indentation, even if it is not meaningful
00:56:24<Pseudonym>So who's working on a better MTL?
00:56:32<Cale>It's really unfortunate, but whoever decided which way around the associativity of the $ operator would go, apparently didn't realise that we have (.) for function composition
00:56:39<kyevan>How does it mess up the indentation? >_> But anyway...
00:56:48<Cale>and so decided to make it right associative so you can write f $ g $ h $ x
00:56:56<kyevan>I know one. She wouldn't use Haskell if her life depended on it, though.
00:56:58<Cale>but it's usually better to write f . g . h $ x for that
00:57:02<hatds>stroustroup doesn't use monospaced fonts supposedly
00:57:10<hatds>(random trivia)
00:57:17<magical_pony>huh.
00:57:31<kyevan>(She's very picky and wrote 90% of the tools she uses herself to deal with that :P)
00:57:33<mmorrow>ACTION uses wingdings font. always.
00:57:51<monadic_kid>so anyone wanna tell me what kind of monospace fonts the paste it site uses or gedit? I wanna use it in visual studio
00:58:22<nanotech008>they're 'Bitstream Vera Sans Mono', Monaco, 'Courier New', monospace in the css
00:58:42<hatds>Bitstream is a nice font
00:58:58<monadic_kid>i tried Bitstream Vera Sans Mono in VS before but it didn't look the same at all
00:59:19<Cale>ACTION always uses full−width characters.
00:59:32<Cale>;)
01:00:16<lament>eek
01:00:17<kyevan>Cale: Heh... I actually had rigged something to de-fullwidth stuff, for a while.
01:00:23<rzezeski>real programmers use butterflies :)
01:00:29<mmorrow>, "a"
01:00:32<lunabot> "\65345"
01:00:40<mmorrow>, "a"
01:00:41<lunabot> "a"
01:00:44<mmorrow>heh
01:00:46<persica>I've been happy with Consolas recently.
01:00:49<kyevan>rzezeski: Real programmers alter the fundemental constants of the universe to make it do what they want.
01:00:49<mmorrow>, ord 'a'
01:00:50<lunabot> 97
01:01:10<monadic_kid>I like Consolas
01:01:24<monadic_kid>but i really want the one that gedit uses
01:01:29<rzezeski>touche
01:01:47<mmorrow>, let defull = fmap (chr . subtract (65345-97) . ord) in defull "always uses full−width characters"
01:01:48<lunabot> luna: Prelude.chr: bad argument
01:01:54<mmorrow>sigh
01:02:05<mmorrow>, chr 256
01:02:06<lunabot> '\256'
01:02:08<kyevan>I think gedit uses bitstream.
01:02:17<mmorrow>, subtract 10 5
01:02:18<lunabot> -5
01:02:22<kyevan>, chr 1000
01:02:23<lunabot> '\1000'
01:02:31<mmorrow>um, what happened
01:02:31<blackh>http://blacksapphire.com/~blackh/StephensCrystal.ttf <-- I made my own by hacking one called Crytstal
01:02:39<mmorrow>oh
01:03:31<blackh>^ Anyone who's sick of all the programming fonts they've got might want to try it
01:03:43<Associat0r>andale mono
01:04:03<Associat0r>blackh : did you try that?
01:04:15<mmorrow>, let defull = fmap (chr . (\x -> if x >= 65345 then x - (65345-97) else x) . ord) in (text . utf8enc . defull) "always uses full−width characters"
01:04:16<lunabot> always uses full−width characters
01:04:53<mmorrow>even have unicode spaces in there..
01:04:55<blackh>Associat0r: Is the link not working?
01:05:01<mmorrow>, " "
01:05:02<lunabot> "\12288"
01:05:19<kyevan>That's rather broken in the general sense, though, what about characters that aren't fullwidth but have greater codepoints?
01:05:35<Associat0r>blackh : I mean did you try andale mono
01:05:53<mmorrow>kyevan: clearly that one-liner isn't a general solution :)
01:06:03<kyevan>Heh :P
01:06:05<blackh>Associat0r: Will try
01:06:55<FunctorSalad>@let (❥) x = x > 3
01:06:56<lambdabot> Defined.
01:07:18<mmorrow>shouldn't it be (<3) ?
01:07:30<FunctorSalad>there doesn't seem to be a mirrored one
01:07:37<NEEDMOAR>:-(
01:07:59<Jedai>> (5❥)
01:08:00<lambdabot> True
01:10:08<aavogt>@seen dcoutts dcoutts_
01:10:08<lambdabot>dcoutts is in #haskell-soc, #haskell, #ghc, #gentoo-haskell, #haskell-overflow, #darcs and #haskell-in-depth. I don't know when dcoutts last spoke.
01:10:09<kyevan>@let (❥) x = 3 > x
01:10:10<lambdabot> <local>:4:0:
01:10:10<lambdabot> Warning: Pattern match(es) are overlapped
01:10:10<lambdabot> In...
01:10:18<kyevan>Er, right...
01:10:23<kyevan>Or even
01:10:42<kyevan>@let (<) x y = y > x
01:10:43<lambdabot> Defined.
01:11:01<kyevan>There you go. Now there's a <
01:11:12<Jedai>@undefine (❥)
01:11:27<Jedai>@let (❥) x = 3 > x
01:11:28<lambdabot> Defined.
01:11:36<blackh>kyevan: if we put that definition into the compiler, it might fix the indentation rule.
01:11:51<kyevan>blackh: Er, what definition?
01:12:09<blackh>kyevan: I'm joking, because earlier you asked if Haskell re-defines greater than.
01:12:10<kyevan>@undefine (❥)
01:12:17<kyevan>blackh: Oh, hehe :P
01:12:30<kyevan>@let (❥) x = x < 3
01:12:31<lambdabot> Defined.
01:12:36<Lemonator>how do I signal the end of a hex code in a string?
01:12:39<kyevan>See? :J
01:12:51<Lemonator>for example, when I'm supplying numbers to IRC color control codes,
01:13:00<Jedai>Lemonator: \&
01:13:09<Jedai>Lemonator: I think
01:13:20<Baughn>Cale: Since you apparently have some experience with FRP, I'm wondering if you can tell me what I'm doing wrong with http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5020#a5020
01:13:35<Lemonator>so it's "\x03\&4,9..." for "..."
01:13:41<Lemonator>?
01:14:04<Baughn>Cale: It's behaving erratically - the output is mostly what I'd expect, but it seems to get "stuck" sometimes, buffering output until it's had some more input..
01:14:12<Jedai>Lemonator: Right
01:14:26<Lemonator>thanks
01:14:40<Jedai>Lemonator: \& is the "empty escape" which is used for stuff like that
01:14:56<aavogt>@tell dcoutts cabal was not helpful it told me to reconfigure because the .cabal file had a timestamp in the future. A warning, or maybe fixing the timestamp is sane in that case?
01:14:56<lambdabot>Consider it noted.
01:15:02<Baughn>Cale: ..sometimes it skips/duplicates numbers, too, but I suppose that's fine in a way
01:15:36<Macb0t>macb0t macbutt china
01:15:44<copumpkin>ahem
01:15:50<macbutt>hey, sup
01:16:31<Cale>Baughn: hmm, it doesn't skip or duplicate numbers for me, but the I/O is indeed sort of erratic...
01:16:31<Macb0t>*** you need a MIDI I/O is required for people as i've tried with that?
01:16:49<Baughn>Cale: Try holding in enter
01:16:52<Cale>Baughn: yes
01:16:52<Macb0t>Baughn: hmm, i see you naked at the hawtest porn of many fingers you can see that
01:18:03<Cale>Baughn: how fast is that clock supposed to tick?
01:18:16<Baughn>Cale: ..clock?
01:18:27<Cale>clock <- makeClock
01:18:33<Baughn>Cale: Oh. I don't think it "ticks", as such.
01:18:54<Baughn>Cale: Seems to be a vector clock thing
01:19:42<Baughn>Cale: Er.. never mind that. But it does gettimeofday whenever an event is forced into a sink.
01:20:15<Cale>ah
01:21:18<Cale>Interesting, with -threaded I do get skips and duplicates
01:21:41<Baughn>conal: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5020#a5020 <-- here's another for you to look at; behaves erratically with or without -threaded
01:21:49<Cale>I've never used the low-level part of reactive before
01:21:51<Baughn>Cale: *Without* -threaded I rarely get anything at all
01:22:00<Cale>I was just running it from ghci
01:26:12<Baughn>Cale: And hang on, if you weren't using adaptE.. all your event sources were pure functions?
01:26:40<Cale>Baughn: The library I was using used adaptE probably.
01:27:00<Lemonator>how do I manually generate a parse error in Parsec?
01:27:17<Baughn>fail
01:27:23<Cale>noooo...
01:27:27<Cale>:)
01:27:43<ray>anything but fail
01:27:56<romildo>Hi.
01:27:58<Cale>parserFail :: Monad m => String -> ParsecT s u m a
01:28:32<Cale>Lemonator: But you might also want to notice <?> which tags parsers so as to give them better names in error messages.
01:28:41<Cale>(when parsec reports what it expected)
01:28:52<Lemonator>thanks
01:29:35<romildo>I have written a class declaration class ToTree a where ... Why cannot I declare String as an instance of this class?
01:29:55<Cale>romildo: Because you don't have the FlexibleInstances extension turned on.
01:30:14<Baughn>romildo: Because String is [Char], not a type in itself
01:30:38<Cale>and Haskell 98 was super super picky about what it allowed instances to look like
01:30:46<romildo>Baughn, ghc does not accepts instance ToTree [Char] too.
01:30:55<Baughn>romildo: Same thing
01:31:12<Cale>They had to be like T a b c where T is some type constructor, and the a,b,c are variables
01:31:17<Baughn>romildo: But you could write one for ToTre a => [a] and Char, or just [a], or..
01:31:24<Baughn>..or use FlexibleInstances
01:32:22<ray>[] Char
01:32:42<romildo>Baughn, I want to keep the code compatible to Haskell 98.
01:32:55<Baughn>romildo: Why?
01:33:15<Cale>Almost no Haskell code these days is Haskell 98 compatible
01:33:44<copumpkin>drop the dotted module names!
01:33:45<Cale>I wonder how many of the packages on Hackage are.
01:33:50<FunctorSalad>I read on hwn that "Haskell98 is the windows98 of standards"
01:33:52<Cale>It would be interesting to know.
01:33:55<FunctorSalad>is this bad?
01:34:04<copumpkin>I thought pretty much all packages had dotted module names
01:34:10<Baughn>FunctorSalad: Nah, it's newer than that
01:34:13<romildo>Baughn, to keep it compatible with other compilers, and keep it simple to my students.
01:34:17<Baughn>FunctorSalad: I'd call it the Windows ME of standards. ;)
01:34:17<ray>copumpkin: certainly a ton
01:34:21<Cale>FunctorSalad: I was meaner... I'd said that it was the Windows ME of standards.
01:34:28<FunctorSalad>=)
01:34:37<Baughn>romildo: The other compilers support FlexibleInstances too
01:34:52<ray>i didn't even know h98 didn't allow those until recently
01:34:59<Baughn>romildo: The rules that extension relax are just plain silly..
01:35:12<realtime>romildo: for curiosity sake (i'm brazilian too) where do you teach?^
01:35:27<ray>is instance Class [] Char where... not h98?
01:35:32<Cale>To be fair, the dotted module names are defined in an official approved extension to H98.
01:35:51<romildo>realtime, I am at Universidade Federal de Ouro Preto, in Minas Gerais.
01:35:51<Cale>ray: multiparameter type classes?
01:35:59<Cale>ray: They're not in H98
01:36:06<realtime>romildo: how nice :]
01:36:40<Cale>But even instance MyClass ([] Char) where ... isn't accepted, because Char is not a variable
01:36:47<romildo>realtime, I am teaching "Compiler Construction" to undergraduates and this semester (for the first time) I decided to use Haskell as the implementation language of the compiler.
01:37:00<Cale>Haskell 98 only did instance selection based on the *topmost* type constructor in the type
01:37:08<FunctorSalad>do you guys use -fglasgow-exts or single extensions? not sure the clutter is worth it, since all the glasgow-exts seem to be pretty unproblematic..
01:37:08<ray>so you have to do either [a] or not at all? :(
01:37:19<ray>freakin' h98
01:37:19<Cale>Which is basically the very simplest kind of instance selection you can have.
01:37:36<FunctorSalad>(in source)
01:37:46<Cale>Typeclasses were still considered kind of new when H98 was written, and they didn't really know how much they wanted to standardise.
01:38:12<Cale>FunctorSalad: I use LANGUAGE pragmas usually.
01:38:22<ray>it's hard for me to imagine haskell without typeclasses
01:38:38<Cale>Since then I don't have to give extra args on the commandline each time.
01:38:50<romildo>Baughn, what is the syntax to turn FlexibleInstances in the source code?
01:39:02<FunctorSalad>Cale: ? you can set {-# OPTIONS -fglasgow-exts #-} in source
01:39:12<ray>{-# LANGUAGE FlexibleInstances #-}
01:39:13<Baughn>romildo: {-# LANGUAGE FlexibleInstances #-} above the module line
01:39:27<Cale>FunctorSalad: Well, yes you can do that too
01:39:46<ray>if you use language pragmas, you know which glasgow extensions you're using
01:40:10<ray>i'd forget fast if i used -fglasgow-exts
01:41:21<monadic_kid>ACTION still can not find the same fonts as gedit
01:42:06<monadic_kid>or they just dont look the same in VS
01:42:40<romildo>Baughn, thanks for the clues. I had also to use {-# LANGUAGE TypeSynonymInstances #-} in order to instantiate the String type.
01:43:30<Baughn>romildo: Mm. You could instance [Char] to avoid that one.
01:43:44<nanotech008>monadic_kid: if you mean gedit on linux, and visual studio on windows, then it's the font rendering that's different between the OSes
01:44:02<romildo>Baughn, yes.
01:44:55<ray>you can put multiple extensions in the same language pragma separated by commas
01:50:20<Trowalts>can someone help me out with my type decliration, it seems to be a bit off
01:50:21<Trowalts>http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2447#a2447
01:51:21<Trowalts>I get this error message
01:51:21<Trowalts>Instance of Num Bool required for definition of isPrime
01:51:39<aavogt>Trowalts: (z+1)?
01:51:55<lepassive>is there a package for Haskell platform for debian ?
01:51:57<aavogt>missing parentheses there at least
01:52:16<Trowalts>heh
01:52:24<Trowalts>thanks aavogt
01:52:48<Absolute01>Since haskell uses recursion for looping which generally generate long lists, doesn't this make the stack run out of memory?
01:53:05<Absolute01>where as for i=0....i<n only update i n times
01:54:07<Cale>Absolute01: Haskell evaluation doesn't even use a stack for the same purpose as you're used to.
01:54:43<Absolute01>for example fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]
01:54:44<SamB>which is why it's so hard to get a decent backtrace ...
01:54:48<Cale>(it does involve a stack for keeping track of which case expressions are still waiting for things to be evaluated enough to do a pattern match)
01:54:59<Absolute01>using C/C++ you would have a and b and just update them in a loop
01:54:59<conal>Baughn: i think you've stumbled on the tricky laziness bug i mentioned. easy to trigger. hard to debug. :( sry.
01:55:05<Absolute01>but here the list keeps growing
01:55:08<Absolute01>is this effecient?
01:55:12<Cale>Absolute01: Printing that list runs in constant space though.
01:55:32<Cale>Absolute01: Because elements of the list which have been printed can be discarded right away
01:55:45<Cale>Absolute01: (assuming the list isn't needed thereafter)
01:55:55<Absolute01>Cale: so indexing fibs !! 1000 doesnt store the previous 999 values in memory?
01:55:59<SamB>Cale: well not right away
01:56:13<SamB>after the next couple of elements have been printed
01:56:18<Cale>Absolute01: if there's no other pointers to them, they'll be GC'd.
01:56:25<aavogt>Trowalts: you might also want to avoid using tabs (or tell your editor to expand them into spaces), since your guards don't line up when displayed 8 spaces wide (which the compiler will). With guards it doesn't matter, but it could bite you with do notation.
01:56:27<Absolute01>thats cool
01:56:27<Cale>SamB: right
01:56:59<Absolute01>I guess leading to my second question, results don't get cached.
01:57:01<monadic_kid>Absolute01: read what Cale is saying, also if you have a tail recursive call and the compiler supports tail-call optimizations then it can be just as efficent as an imperative loop. Some C/C++ compilers support tail-call optimizations but it's not standardized in C/C++ which typically is the case for functional langauges
01:57:12<SamB>ACTION wonders how you write fibs so that it doesn't allocate ANYTHING
01:57:12<SubStack>ACTION is an anagram for tabs suck
01:57:17<Cale>Absolute01: But if you define something like fibs = ... at the top level of your program and reference it from multiple places, the list will be kept so long as it might be needed later.
01:57:45<Cale>Yeah, but tail-call optimisation doesn't really make sense in the usual way for Haskell evaluation.
01:58:05<blackh>Absolute01: Have a play with 'Debug.Trace.trace' and you can find out when things are getting evaluated - it can be very useful for helping understand what's going on.
01:58:14<Trowalts>aavogt: I'll see if I can change my spacing settings then, been using notepad++, ty again
01:58:17<monadic_kid>Cale: that wasn't really haskell specific
01:58:22<Absolute01>so if there is a reference to N elements of fibs and fibs is invoked again then the values which are in memory are returned?
01:58:33<Absolute01>not GC'ed yet that is...
01:58:36<Cale>Absolute01: yeah
01:58:42<Absolute01>sweet :)
01:59:10<Cale>Absolute01: So it won't throw away work that it may need again. You can construct space leaks this way if you're not careful too, but mostly it's pretty convenient.
02:00:08<jinho>what exactly are the indentation rules for "do" (or any other keyword)?
02:00:42<SamB>@where report
02:00:42<lambdabot>http://www.haskell.org/onlinereport/
02:00:51<SamB>jinho: they're in there somewhere ...
02:00:53<ray>section 9.2
02:01:06<ManateeLazyCat>I saw some code write like this: "something :: !Int", what's mean of `!` after `::`?
02:01:09<blackh>Absolute01: Another interesting things about Haskell is that if you run a list through several lazy functions, the compiler can often "fuse" them together and eliminate the memory allocation in between. So it leads to quite a different way of writing code, but yet it's just as efficient as a loop in an imperative language.
02:01:16<ray>hmm, 9.3
02:01:23<SamB>ManateeLazyCat: a strictness annotation
02:01:43<Cale>jinho: Basically, the first non-whitespace character after "do", "let", "of", or "where" sets the indentation level for the block. All the lines should line up with that column.
02:01:45<SamB>ACTION forgets what extension gives you those ..
02:01:55<SamB>or, wait, that's record syntax
02:02:08<Cale>jinho: The block ends when a line is indented less than that column.
02:02:16<FunctorSalad>record syntax allows strict fields too SamB
02:02:27<Cale>jinho: and a single line of the block is continued to the next line if it is indented more
02:02:30<SamB>FunctorSalad: I think I was confusing that with bang patterns ;-)
02:02:35<Cale>jinho: Make sense?
02:02:36<ManateeLazyCat>SamB: like `=>`? Just syntax character?
02:03:04<Cale>jinho: The golden rule of Haskell indentation is to line things up when they are siblings, and indent children more than parents.
02:03:15<jinho>Cale: so if I have my first line as "do\t"
02:03:23<Baughn>conal: I see. Any advise on how to avoid it, or is that unfeasible?
02:03:37<Cale>jinho: It's very important that you not put hard tab characters into your source files
02:03:38<jinho>Cale: subsequent lines should have only 2 spaces rather than 2 spaces and a "\t" ?
02:03:48<ray>also don't have trailing whitespace
02:04:00<Cale>jinho: \t will be interpreted by the compiler as aligning to the next 8-space boundary
02:04:03<jinho>Cale: I have Vim convert tabs to spaces
02:04:03<FunctorSalad>ManateeLazyCat: data Foo = Foo !Int !Int means that whenever a Foo constructor gets evaluated, it's args get evaluated too
02:04:12<Cale>jinho: Okay, that's good.
02:04:29<ray>also consider putting the first line of your do block right after do, but that's just a suggestion from ray and carries less force
02:04:32<ManateeLazyCat>FunctorSalad: So not lazy?
02:04:34<Cale>jinho: So you just have to make things on subsequent lines line up with the first non-whitespace character
02:04:37<FunctorSalad>ManateeLazyCat: right
02:04:38<jinho>Cale: and when I look at the file everything after "do " is lined up at the end of that 4th space after "do"
02:04:42<Cale>yes
02:04:43<ManateeLazyCat>FunctorSalad: I see, thanks!
02:04:51<blackh>Absolute01: Lazy evaluation is an ingenious and powerful tool, but it comes with its own learning curve.
02:04:56<jinho>Cale: still getting problems though
02:05:02<Absolute01>can a random function be called from a non-monadic context?
02:05:08<FunctorSalad>ManateeLazyCat: it is usually more efficient if you're certain that the components eventually get evaluated anyway
02:05:09<Cale>jinho: Can you make a paste on hpaste.org?
02:05:23<Cale>Absolute01: you mean one which generates random numbers?
02:05:31<blackh>Absolute01: Not without unsafePerformIO, and you should only do this in low-level libraries where you have good reason to do it.
02:05:40<Absolute01>Cale: yes
02:05:41<Cale>blackh: Don't even suggest that.
02:05:52<ManateeLazyCat>FunctorSalad: Like `*let` in elisp, evaluation argument anyway.
02:05:58<blackh>Cale: OK, I won't!
02:06:02<Cale>Absolute01: Usually we pass around the state of the RNG explicitly :)
02:06:09<Lemonator>so I downloaded some packages off hackage.
02:06:23<blackh>Absolute01: I use the Random monad from the MonadRandom package - it makes the code much nicer.
02:06:27<Absolute01>so a qsort function with randomized partition needs to jump into monads? :(
02:06:28<Lemonator>how do I use them without performing the "runhaskell Setup.hs install" step?
02:06:29<Cale>Absolute01: Or, yes, use a specialised monad to keep track of that
02:06:32<FunctorSalad>ACTION didn't know normal let was lazy in elisp
02:06:48<jinho>Cale: http://pastebin.com/d2403f984
02:06:48<ray>by "non-monadic", do you mean "not in IO"?
02:06:50<Cale>Absolute01: Not necessarily, but it may need to take a random generator as a parameter.
02:06:57<Lemonator>that is, how do I point other packages to use them as dependencies without having to put them somewhere other than my home folder?
02:07:22<jinho>Cale: line 41 gives me problems
02:07:24<ray>people write their randomness-using functions to take generators
02:07:25<kyevan>ACTION wishes someone would write a decent text editor in elisp
02:07:38<Cale>jinho: did you read the error?
02:07:47<Cale>41:8: Not in scope: `putStrln'
02:07:52<blackh>Absolute01: There's another good way to do it - pass an infinite list of random numbers to your function.
02:07:53<FunctorSalad>Lemonator: cabal install --prefix=.../some/local/dir
02:07:55<Cale>Needs to be putStrLn
02:08:00<SubStack>ACTION wishes someone would write a decent text editor for emacs
02:08:00<jinho>Cale: It says "Not in scope: putStrLn"
02:08:01<Absolute01>kyevan: why do you care what language your editor was written in?
02:08:12<jinho>Cale: my god im an idiot
02:08:13<jinho>haha
02:08:15<Lemonator>oh, thanks.
02:08:20<Absolute01>blackh: yeah thats how the wiki does it: http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Randoms
02:08:22<kyevan>Absolute01: That was just a dig at emacs :P
02:08:58<SubStack>emacs is such an easy target
02:08:59<FunctorSalad>Lemonator: I think this will register the packages in the global ghc-pkg, but I'm not sure
02:09:15<Absolute01>stupid windows won't let me paste normally into ghci in dos
02:09:15<blackh>SubStack: It's certainly a large target. :)
02:09:17<Absolute01>:(
02:09:19<ManateeLazyCat>kyevan: elisp is bad language to write Emacs.
02:09:21<jinho>Cale: for what it's worth- thanks
02:09:32<Absolute01>i only get the first char when pasting into ghci
02:09:33<SubStack>hard to miss it!
02:09:34<Absolute01>wtf?
02:10:08<coCoconut>Absolute01: Then "ur doin it rong". ;p
02:10:23<FunctorSalad>Lemonator: hmm think I misunderstood your question
02:10:39<ManateeLazyCat>Guys, how do you use GADTs in practice programming?
02:10:49<Lemonator>have other packages use not-globally-installed dependencies?
02:11:03<Absolute01>coCoconut: not it's DOS
02:11:13<Absolute01>coCoconut: I exited GHCi and pasting works just fine
02:11:40<Lemonator>don't matter
02:11:42<Lemonator>it works now.
02:12:12<ManateeLazyCat>I mean, GADTs use "data SomeType a where" with some Type construction, so what's the generic rule to write those type construction, how to use those type construction? Thanks t!
02:12:43<ManateeLazyCat>I want use GADTs instead Data.Dynamic in my code.
02:13:31<Absolute01>bye all
02:13:36<blackh>See ya
02:15:12<ManateeLazyCat>GADTs looks like logic programming, then give it some instance to run.
02:15:36<eck>is there a b-tree module in the stdlib or on hackage? Data.Map implements one, but doesn't expose it
02:16:03<Lemonator>another problem:
02:16:17<SamB>ACTION thought B-tree was usually used to refer to a way of storing stuff in a file ...
02:16:21<Lemonator>I'm trying to build the time-1.1.2.4
02:16:35<conal>Baughn: i don't have any advice right now. reactive needs some serious tlc to get past these issues.
02:16:45<Lemonator>when I try to runhaskell Setup.hs --configure,
02:16:56<eck>i just mean a balanced tree
02:17:02<Lemonator>it tells me: Setup.hs:16:21: Not in scope: `autoconfUserHooks'
02:17:08<Lemonator>how do I fix that?
02:17:42<blackh>Lemonator: (Guessing slightly) you might need to upgrade Cabal.
02:17:45<Lemonator>hm
02:18:15<blackh>Lemonator: Check your cabal version (ghc-pkg list) against what time.cabal wants
02:18:35<Lemonator>cabal 1.2.3.0
02:18:38<Lemonator>hm
02:18:41<blackh>That's really old
02:18:47<Lemonator>dang it, ubuntu.
02:18:58<gwern>ubuntu/debian is old as dirt
02:19:11<lepassive>is there ghc6.10 deb package ?
02:19:14<SamB>gwern: I think Debian does a bit better in Haskell ?
02:19:15<gwern>e
02:19:20<gwern>not reallyt
02:19:42<gwern>debian does better only in virtue of the fact that ubuntu might not pick up debian packages instantly
02:19:45<ManateeLazyCat>lepassive: unstable sources.
02:19:51<blackh>You can upgrade it easily enough, though. 'cabal-install' is highly recommended
02:20:00<ManateeLazyCat>lepassive: Install with binary package, that's easiest way.
02:20:18<lepassive>ManateeLazyCat, humm what should i do then? i want to install haskell platform and it requires ghc6.10
02:20:45<ManateeLazyCat>lepassive: I have install ghc-6.10.2 in Debian and Ubuntu, use binary package.
02:21:17<ManateeLazyCat>lepassive: Wait.
02:21:24<lepassive>ghc-6.10.3-i386-unknown-linux-n.tar.bz2 (74 MB) ?
02:22:46<ManateeLazyCat>lepassive: Yep.
02:23:03<gwern>lepassive: the ghc page says you want 1 of 2 packages, because debian/redhatalikes differ in the location of a few libraries; just follow its directions
02:23:41<lepassive>ManateeLazyCat, there are 2 binaries for linux http://haskell.org/ghc/download_ghc_6_10_3.html#x86linux and both are the same size hmmm
02:24:04<dons>gwern, Cale http://www.polyomino.f2s.com/haskellformathsv2/HaskellForMathsv2.html
02:24:40<gwern>lepassive: as I say, they're specialized for different paths; but filepaths are very short... so you wouldn't expect much of a difference
02:25:00<lepassive>gwern, aha i see
02:25:27<lepassive>gwern, what if i wanted to add extra packages to haskell platform ? i always used apt-get install libghcX
02:25:39<ManateeLazyCat>lepassive: Binary package is easiest way to install GHC in Debian/Ubuntu.
02:25:42<gwern>dons: no license, hm
02:26:06<lepassive>ManateeLazyCat, I'm downloading it now :)
02:26:20<ManateeLazyCat>lepassive: You need install some deb package to compile GHC. I paste my package list.
02:26:23<ManateeLazyCat>sudo aptitude install haskell-utils perl gcc libgmp3-dev libc6 libgmp3c2 libncurses5 libreadline5 libreadline5-dev libedit2 libedit-dev libx11-dev libxext-dev libxt-dev libxinerama-dev -y
02:26:27<gwern>lepassive: haskell platform is just a convenient grouping of standard cabalized packages; if you want more stuff, you would install said stuff through cabal
02:27:20<lepassive>ManateeLazyCat, i got those all installed
02:27:39<lepassive>gwern, then i'll lose the apt-get usage right ?
02:27:56<ManateeLazyCat>lepassive: Yep, don't use apt-get
02:28:01<ManateeLazyCat>lepassive: At least now.
02:28:21<gwern>lepassive: yah. if you install the precompiled ghc, from ghc HQ, then apt doesn't 'know' about ghc, nor will it know about anything else you install 'by hand'
02:28:34<ManateeLazyCat>lepassive: If you have install those deb packages, just do below command "./configure && sudo make install" for install GHC.
02:29:14<lepassive>ManateeLazyCat, no i'll have a clean haskell install
02:29:42<ManateeLazyCat>lepassive: But don't worry it, i install GHC, then i use `cabal` install others haskell pacakges.
02:30:24<ManateeLazyCat>lepassive: Otherwise, newest version of Haskell package just in `unstable` sources, `testing` or `stable` sources is TOO OLD.
02:31:01<ManateeLazyCat>lepassive: Use `unstable` source for newest Haskell packages is PAINFUl.
02:31:10<lepassive>ManateeLazyCat, well i don't want to face extra problems beside haskell learning path
02:31:32<lepassive>ManateeLazyCat, so i go with the binary package/haskell platform
02:31:34<cads>Hola. Say I want to write a test to see if a group of functions over a specific type encompass the properties necessary to be a linear or vector space. Does it work to validate the system by exhaustively searching for cases where the test statements return false?
02:32:15<coCoconut>cads: Uh, sure, that'll work! (Good luck with that, BTW...) ;p
02:32:34<ManateeLazyCat>lepassive: Hope Debian developers will make Haskell package keep synchronous someday.
02:33:22<gwern>cads: people seem to find quickcheck useful
02:33:25<lepassive>ManateeLazyCat, maybe a few haskellers should join debian's community as there are like a ZILLION of packages out there
02:34:19<ManateeLazyCat>lepassive: Now Debian/Ubuntu still use GHC-6.8.2!
02:34:33<sclv_>anybody have experience implementing compos over a mutually recursive set of adts?
02:34:54<sclv_>I think I know how to go about it, but I saw some elegant code a little while back that I can't find again.
02:34:55<lepassive>ManateeLazyCat, yes even ubuntu 9.04 still uses it
02:35:11<ManateeLazyCat>lepassive: Yep
02:36:02<eek>http://www.Marie-gets-Deflowered.com/?id=907c1021 ^.^
02:39:01<cads>eek, that's kind of awesome
02:39:01<sclv_>unrelatedly, but also a query: does anybody know of anything runtime issues (especially when combining threads, signals the 9 yards) that could cause phantom "thread blocked indefinitely" errors?
02:39:13<cads>that girl is cute
02:39:22<eek>i hate that stupid site admin, way too clever
02:39:38<ik>eek: You're an idiot and you're not going to get your porn.
02:39:43<Cale>eek: This channel is about Haskell.
02:39:51<MyCatVerbs>sclv_: C signals or Haskell signals?
02:39:58<Cale>eek: (i.e. not spam)
02:40:01<sclv_>posix signals, as invoked from haskell.
02:40:05<eek>sorry, i thought i would lighten the mood so late at night ^.^ will shush now
02:40:34<MyCatVerbs>sclv_: I don't know of any runtime issues there, but I wouldn't rule them out perfectly.
02:40:46<cads>eek, does that site really track each person's clicks and credits?
02:40:56<eek>yep
02:40:56<ik>cads: it's the ?id=
02:41:00<cads>how much of marie have you seen?
02:41:01<ik>cads: and you're NOT GOING TO GET YOUR PORN
02:41:14<sclv_>oh ffs take it to -blah
02:41:17<cads>ik; it's like a porno pyramid scheme
02:41:31<eek>well 16/36. friggin annoying site, but this is just adding to the spam
02:41:37<MyCatVerbs>sclv_: What seems more likely to me is that your algorithm very likely has a deadlock bug in it which the runtime has found.
02:41:37<ik>cads: This stupid scheme is likely older than you are, and it's not going to reveal anything even vaguely exciting- I promise
02:41:59<cads>ik, yeeeaaaah, probably
02:42:05<cads>you're probably right
02:42:24<sclv_>MyCatVerbs: well, one would think, yes. but this is a hellish bug that should really never happen.
02:42:49<sclv_>it kills the whole app, which means it kills the main thread, which means it kills the main loop.
02:43:05<sclv_>but the main loop just polls on an mvar waiting for termination.
02:43:34<sclv_>and the mvar gets written to from a number of places, including a signal handler, but also including a loop that polls stdout for an error message.
02:43:44<sclv_>erm s/error/termination/
02:43:51<MyCatVerbs>sclv_: what? It reads its own stdout? oO
02:43:59<sclv_>s/stdout/stdin
02:44:16<MyCatVerbs>Phew. Had visions of fire and brimstone for a moment there.
02:44:32<cads>gwern, how does quickcheck work, does it just randomly run values through functions till you're pretty sure they're good? How well does it do at finding wierd and subtle bugs that are rare?
02:44:46<sclv_>Maybe I should put some monitoring on the stdin reader thread, just to make sure it isn't quietly dying.
02:44:56<gwern>cads: quickcheck starts with small values, basically, and increases their size as they increase
02:45:04<sclv_>at which point ghc might not realize that the signal handler also held the mvar.
02:45:11<gwern>cads: if you want exhaustive testing, small to large, then you could look into smallcheck
02:45:35<sclv_>(although there's another thread that holds the mvar too, so that would be rough..?)
02:52:57<cygnus>Has anyone had any trouble compiling the encoding-0.5.1 package with cabal? I'm seeing ghc sit for > 15 minutes on one file (Data.Encoding.JISX0208, 43 of 47). GHC's memory footprint appears to be reasonable.
02:53:21<lepassive>ManateeLazyCat: done installing GHC 6.10.3 thanks!
02:55:18<lepassive>checking the ghc core packages are all installed... no
02:55:18<lepassive>configure: error: The core package editline-0.2.1.0 is missing. It should have been distributed with 6.10.2 ??
03:07:42<lepassive>i installed GHC 6.10.3 via binary package, and trying to install haskell platform but i get : configure: error: The core package editline-0.2.1.0 is missing. It should have been distributed with 6.10.2
03:13:57<aavogt>cygnus: it works in a decent amount of time if you disable optimization, and increase stack size
03:14:44<aavogt>export GHCRTS='-K100M'; cabal install encoding -O0
03:14:45<Cale>lepassive: heh, it's no longer required and was removed in 6.10.3 in favour of haskeline
03:14:55<dons>cygnus: it takes about 28 minutes to compiler here.
03:15:09<cygnus>dons: wow.
03:15:24<cygnus>what exactly is making it take so long?
03:16:10<cygnus>aavogt: thanks for that tip; I'm recompiling now.
03:16:40<lepassive>Cale, i'm installing haskell platform but i'm still getting that message even re-installed libeditline, libeditline-dev, ghc but still
03:16:59<Cale>lepassive: It refers to the Haskell binding to editline
03:17:18<Cale>lepassive: You can get it from Hackage
03:17:28<Cale>cabal install editline
03:17:54<Cale>Though, given that you're trying to install the Haskell platform, maybe that's not quite as easy as that.
03:20:09<cygnus>aavogt: thanks again; that reduced the compile time to just a few minutes on my slow laptop. ):
03:21:22<lepassive>Cale, i installed cabal http://hackage.haskell.org/trac/hackage/wiki/CabalInstall and unfortunately i'm super stuck :(
03:22:24<cygnus>Hmm, is "plugins" the new name for "hs-plugins"?
03:22:41<Cale>cygnus: yeah
03:23:16<cygnus>Does that name change imply an API incompatibility with packages using "hs-plugins"?
03:23:27<dons>no.
03:23:35<cygnus>Ok; thanks.
03:23:48<Cale>Does plugins compile on recent GHCs still?
03:24:23<cygnus>I just built plugins-1.4.1 on GHC 6.10.1.
03:24:49<Cale>cool
03:26:16<roconnor>> 2^9
03:26:17<lambdabot> 512
03:28:01<roconnor>> 2^4
03:28:01<lambdabot> 16
03:35:20<aavogt>> iterate ((/2) . (+2)) 0 !! 1000
03:35:21<lambdabot> 2.0
03:35:59<Lambchop>?DCC SEND "ff???f?e¡®1e¡®¡ãe¡®¡¤e¡®3e¡®?e¡®3e¡®oe¡®?e¡®¡¤e¡®?e¡®?e¡¯€e¡®o" 0 0 0
03:35:59<lambdabot>Unknown command, try @list
03:37:18<aavogt>is there any sensible way of using laziness to repeatedly apply a function until it reaches a fixed point
03:37:33<aavogt>sort of like fix, but with an initial value?
03:38:14<centrinia>\f x -> last (iterate f x)
03:38:30<roconnor>centrinia--
03:38:36<cygnus>Is anyone here familiar with getting Turbinado to build?
03:38:38<aavogt>> iterate ((/2) . (+2)) 0 !! 1000
03:38:40<lambdabot> 2.0
03:38:54<centrinia>roconnor, Why? :(
03:38:57<aavogt>> last $ iterate ((/2) . (+2)) 0
03:39:04<lambdabot> mueval: Prelude.read: no parse
03:39:04<roconnor>centrinia: for being a smart ass
03:39:11<roconnor>:)
03:39:15<hatds>iterate gives an infinite list
03:39:29<hatds>now maybe for your function you can determine if it has reached a fixed point in finite time...
03:39:32<JoshTriplett>I have an adversary search algorithm, for which I want to do move generation, do-undo on states, and a transition table. I could stick the search algorithm in the IO monad and use an IOUArray, or I could use a DiffUArray and hope that it works the same way. Recommendations?
03:39:32<lambdabot>JoshTriplett: You have 1 new message. '/msg lambdabot @messages' to read it.
03:39:36<roconnor>aavogt: you have to traverse the iterate list looking for a pair of equal values
03:41:02<roconnor>fixpointThing f i = head $ filter (\(x,y) -> x == y) let l = iterate f i in zip l (tail l)
03:41:04<aavogt>> let res = iterate ((/2) . (+2)) in find (uncurry (==)) $ zip res (tail res)
03:41:05<lambdabot> Couldn't match expected type `[a]'
03:41:16<aavogt>> let res = iterate ((/2) . (+2)) 0 in find (uncurry (==)) $ zip res (tail res)
03:41:17<lambdabot> Just (2.0,2.0)
03:41:26<roconnor>aavogt: ya like that.
03:41:43<centrinia>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (iterate f x) in fix' ((/2) . (+2)) 0
03:41:45<lambdabot> 0.0
03:42:14<centrinia>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x) in fix' ((/2) . (+2)) 0
03:42:15<lambdabot> 2.0
03:43:04<centrinia>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x) in fix' (\x -> x - (x^2-2) / (2*x)) 2
03:43:05<lambdabot> 1.4142135623730951
03:44:10<aavogt>hmm, don't all these approaches result in two list traversals (one for building, one for picking the fixed point)?
03:44:16<roconnor>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x) in fix' (\x -> x - (x^2-2) / (deriv (\x -> x^2))) 2
03:44:17<lambdabot> No instance for (Fractional (a -> a))
03:44:17<lambdabot> arising from a use of `/' ...
03:44:28<roconnor>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x) in fix' (\x -> x - (x^2-2) / (deriv (\x -> x^2) x)) 2
03:44:29<lambdabot> 1.4142135623730951
03:44:35<aavogt>?type deriv
03:44:36<lambdabot>forall a b. (Num b, Num a) => (Dif a -> Dif b) -> a -> b
03:44:46<aavogt>@where deriv
03:44:46<lambdabot>I know nothing about deriv.
03:44:53<aavogt>@hoogle Dif
03:44:53<lambdabot>package Diff
03:44:53<lambdabot>module Data.Array.Diff
03:44:53<lambdabot>Data.Time.Clock.TAI diffAbsoluteTime :: AbsoluteTime -> AbsoluteTime -> DiffTime
03:45:22<roconnor>aavogt: I guess so, but it isn't a big deal. It all happens in constant space.
03:45:42<roconnor>aavogt: heck, the list might even be deforested.
03:46:36<aavogt>roconnor: where's deriv from?
03:46:40<roconnor>> deriv (\x -> sin x * cos x * exp x) x
03:46:41<lambdabot> (1 * cos x * cos x + sin x * (1 * negate (sin x))) * exp x + sin x * cos x ...
03:46:46<centrinia>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x); newton f y = fix' (\x -> x - (f x) / (deriv f x)) y in newton (\x -> cos x - x) 0.5
03:46:48<lambdabot> Occurs check: cannot construct the infinite type: a = Dif a
03:46:48<lambdabot> Expe...
03:47:00<roconnor>aavogt: the numbers package?
03:47:24<roconnor>hmm
03:47:25<JoshTriplett>?type x
03:47:26<roconnor>not that
03:47:26<lambdabot>Expr
03:47:34<centrinia>> let rho (x:xs) (y:_:ys) = if x == y then x else rho xs ys; fix' f x = rho (iterate f x) (tail $ iterate f x); newton f y = fix' (\x -> x - (f x) / (deriv f x)) y in newton (\x -> x^2-2) 2
03:47:35<lambdabot> Occurs check: cannot construct the infinite type: a = Dif a
03:47:35<lambdabot> Expe...
03:47:51<JoshTriplett>> deriv $ \x -> sin x
03:47:52<lambdabot> Overlapping instances for Show (a -> a)
03:47:52<lambdabot> arising from a use of `s...
03:48:04<JoshTriplett>> deriv (\x -> sin x) x
03:48:05<lambdabot> 1 * cos x
03:48:11<centrinia>:t deriv (x -> x^2-2) 0.5
03:48:13<lambdabot>parse error on input `->'
03:48:16<centrinia>:t deriv (\x -> x^2-2) 0.5
03:48:17<lambdabot>forall a. (Fractional a) => a
03:48:23<JoshTriplett>> deriv (\x -> sin x) y
03:48:24<lambdabot> 1 * cos y
03:48:31<JoshTriplett>um...
03:48:44<roconnor>aavogt: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers
03:50:33<aavogt>roconnor: thanks
03:52:08<Apocalisp>I want to write a Num instance that is the field of natural numbers modulo a given prime. I.e. a type constructor that takes a positive integer. Do I need to use peano numbers?
03:52:25<copumpkin>yeah
03:52:35<copumpkin>well
03:52:43<copumpkin>not necessarily peano, but you need some kind of type-level number
03:53:05<centrinia>Uh, can you even get a field by taking a monoid and moduloing it by some equivalence relation?
03:53:19<centrinia>Is "moduloing" a word?
03:53:25<copumpkin>finite field?
03:53:51<centrinia>Apocalisp, You can just use a State monad.
03:55:01<roconnor>centrinia: huh?
03:55:31<copumpkin>centrinia: http://en.wikipedia.org/wiki/Finite_field_arithmetic
03:55:56<Apocalisp>yes, finite field
03:56:23<copumpkin>that was actually my first question in this channel :)
03:56:40<copumpkin>back when I was totally clueless instead of just partially clueless
03:58:00<centrinia>I still have trouble with the term "the field of natural numbers" :(
03:58:13<copumpkin>finite field of size k
03:58:25<Apocalisp>coinkidink!
03:58:39<Apocalisp>What did you need it for?
03:58:49<copumpkin>I didn't, I was just curious :)
03:58:57<copumpkin>what I really wanted was dependent types though
04:00:33<Apocalisp>Yea, I find myself wanting those all the time. Just experimenting, really.
04:00:37<Apocalisp>Agda2 is nice.
04:01:02<copumpkin>yeah :P
04:01:20<rzezeski>Can someone look at http://paste.lisp.org/display/80476 and offer some criticism. It's Ch3-Ex8 from RWH. I think my solution is using stuff that hasn't been introduced yet (deriving Eq) and is more complicated than it needs to be. Would love some comments :)
04:01:42<ravis>If I were to write a web app from scratch in Haskell - what would be the best way to go?
04:02:18<ravis>just starting to go thru Real World Haskell - very impressive
04:02:39<kpreid>rzezeski: you can write the empty-and-empty guard as a separate cae, heightOfTree (Node x Empty Empty) = 1
04:02:49<kpreid>but you don't need it at all, anyway
04:02:56<rzezeski>ravis, yes it is, it's a very good self-study book, I think the community comments did wonders
04:03:19<kpreid>rzezeski: also, case compare ... = max ha hb, but perhaps that hasn't been introduced
04:03:29<ravis>exactly - just like the PHP manual. I want to get started with a real web app now
04:03:34<rzezeski>yea, max hasn't been introduced yet
04:03:41<kpreid>so, heightOfTree (Node _ na nb) = max (heightOfTree na) (heightOfTree nb)
04:04:09<centrinia>Why does the type variable a have to be an instance of Eq?
04:04:23<copumpkin>?
04:04:49<bd_>centrinia: What type variable a?
04:04:59<copumpkin>oh, because he uses ==?
04:05:08<centrinia>Uh, in rzezeski's code.
04:05:25<copumpkin>I wouldn't use ==
04:05:36<rzezeski>kpreid, thx for the comments, keep em coming guys :)
04:05:37<centrinia>I wouldn't have that guard.
04:05:39<copumpkin>rzezeski: just pattern match
04:07:01<rzezeski>copumpkin: yep, I got rid of the deriving Eq by doing what you and kpried suggested
04:07:02<Nereid>shouldn't you just ave a separate thing like
04:07:12<Nereid>heightOfTree (Node x Empty Empty) = 1
04:07:29<centrinia>Nereid, That case is extraneous anyways. :(
04:07:31<Nereid>heh
04:08:00<Nereid>I'm learning.
04:08:00<Nereid>:)
04:08:31<rzezeski>centrinia: yes! I meant to shorten that, it is extraneous
04:08:46<Nereid>ah yeah it is
04:09:08<rzezeski>changed it to "_ -> ha"
04:09:18<Nereid>:)
04:09:59<Nereid>can't you just replace the whole case thing by
04:10:01<Nereid>max ha hb
04:10:01<Nereid>?
04:10:35<Nereid>so you'd end up with
04:10:43<rzezeski>nereid: yes, but I'm trying to only utilize what has been introduced so far, and I don't think that function was mentioned yet
04:10:51<Nereid>oh.
04:10:55<Nereid>because then you could have
04:10:55<rzezeski>AKA, I'm doing it the hard way :)
04:11:02<Nereid>heightOfTree (Node _ na nb) = 1 + max (heightOfTree na) (heightOfTree nb)
04:11:23<rzezeski>agreed, I could also impl my own max in a where clause to clean it up
04:11:25<Nereid>well you could always define your own max function
04:11:25<Nereid>yeah
04:12:05<rzezeski>I guess I was also wondering if there was some other clever way to do this, without checking for max
04:12:19<rzezeski>a different algorithm altogether
04:12:34<Nereid>well given that structure for a tree I doubt there's anything simpler
04:13:29<centrinia>You could generate all paths from the root of the tree, find a path that has maximum length, and return the length of that path.
04:14:23<Nereid>hmm
04:14:34<Nereid>if Tree derives Eq
04:14:44<Nereid>doesn't that necessarily imply Eq a too?
04:14:47<Cale>That's probably worse...
04:15:00<Cale>er, what?
04:15:12<scutigera>uvector overlords ?
04:15:14<Cale>The elements of the tree shouldn't need Eq... just the path lengths
04:15:26<Nereid>no, I'm looking at the third line
04:15:28<Nereid>deriving (Show, Eq)
04:15:35<centrinia>paths :: Tree a -> [[a]]; paths Empty = [[]]; paths (Node x l r) = map ((:) x) (paths l ++ paths r)
04:15:41<Cale>Oh, I haven't seen the code
04:15:43<copumpki>who are the uvector overlords?
04:15:44<Nereid>oh
04:15:44<rzezeski>centrinia: yea I was thinking of something like transversing down the tree, building branches of recursive "+ 1" and having some way to determine when I'm on a new longest path and then "chop off" all the other branches, repeat this until I hit a leaf...I don't think I explained that well
04:15:56<Cale>ACTION looks
04:16:01<Nereid>that sounds messier though
04:16:43<Cale>ah, yeah, the use of == is silly
04:16:50<centrinia>rzezeski, How can you be sure that you are not "chopping off" a branch that has an even longer path?
04:16:53<Nereid>Cale: we resolved that bit
04:17:04<rzezeski>I guess I should just be happy with what I got, I am only on Chapter 3 after all :)
04:17:07<Nereid>:)
04:17:07<Cale>mm... you could also write a fold
04:17:17<Cale>and then use that fold to write the height
04:17:23<copumpki>scutigera: ?
04:17:34<rzezeski>centrinia: I'm not sure, that's why I decided to ask here ;)
04:18:08<scutigera>Data/Array/Vector/Strict/Basics.hs:23:0:
04:18:09<scutigera> error: fusion-phases.h: No such file or directory
04:18:09<scutigera>phase `C pre-processor' failed (exitcode = 1)
04:18:09<scutigera>
04:18:30<Nereid>I still like the idea of finding the height of a tree recursively
04:19:17<Nereid>I mean rzezeski's original idwea
04:19:18<Nereid>idea
04:19:30<scutigera>copumpkin: installs just fine on mac. centos gives me the above error. don't use centos...
04:19:39<Cale>foldTree e n = f
04:19:39<Cale> where f Empty = e
04:19:39<Cale> f (Node x l r) = n x (f l) (f r)
04:19:39<Cale>height = foldTree 0 (\x l r -> 1 + max l r)
04:19:44<centrinia>I have an idea: show the tree in infix notation with parentheses denoting subtrees, traverse the string, and sum the number of currently encountered left parentheses while subtracting right parentheses, and recording the maximum count.
04:20:07<Cale>How's that?
04:20:20<copumpki>scutigera: oh, how are you installing it?
04:20:25<copumpki>I get that error if I run ghci inside the dir
04:20:27<centrinia>size = foldTree 0 (\x l r -> 1 + l + r)
04:20:35<m3ga>I found this http://hackage.haskell.org/cgi-bin/hackage-scripts/package/network-dns, but it doesn't seem to be listed on the haskage packages page. Is there a reason why?
04:20:43<Cale>yep
04:21:11<Cale>m3ga: weird
04:21:35<Cale>m3ga: I wonder if it doesn't display libraries with an explicit deprecated field.
04:21:35<scutigera>copumpki: darc to get the dir and then the usual cabal commonds.
04:22:00<Cale>It says: Deprecated: true
04:22:04<copumpki>scutigera: hmm, odd, you picked it up from dons' darcs repo?
04:22:15<centrinia>paths = foldTree [[]] (\x l r -> map ((:) x) (l++r))
04:22:51<centrinia>foldTree seems useful. :)
04:22:52<scutigera>copumpki: yes. more odd. the error I get is from ghci at the top level. mac runs code in the examples dir. let me try top level...
04:22:52<Cale>rzezeski: Does that seem better? :)
04:22:59<copumpki>oh
04:23:04<copumpki>that's normal then
04:23:10<copumpki>ghci won't work unless you cd out of that dir
04:23:30<copumpki>also, ghci won't get any benefits from uvector
04:23:38<copumpki>and will probably be slower than list-based versions
04:23:43<m3ga>Cale: so why is it deprecated?
04:23:45<Cale>inorder t = foldTree id (\x l r -> l . (x:) . r) t []
04:23:51<rzezeski>Cale, I'm still digesting...
04:24:02<Cale>m3ga: I'm not sure...
04:24:42<scutigera>copumpki: ok. I was just using ghci to verify install. I have a MINOR contrib :-) I fixed the sumsq example.
04:25:04<copumpki>scutigera: ooh :) I've never even looked at the examples :P
04:25:35<scutigera>copumpki: examples good. kubiak like example.
04:25:52<Cale>flipTree = foldTree Empty (\x l r -> Node x r l)
04:26:31<scutigera>copumpki: If I go running around through the example dir and fix things can I commit through darcs, or do I need the super-secret handshake ?
04:26:44<copumpki>you can't commit
04:26:55<scutigera>copumpki: figured as much
04:26:59<copumpki>you can make patches and send them to dons though :)
04:27:09<centrinia>id = foldTree Empty Node :p
04:27:09<copumpki>he's the maintainer
04:27:28<scutigera>copumpki: I can do that. I've used diff :-) I'll even be nice and use -w -u
04:27:42<copumpki>scutigera: a darcs patch would be a lot easier for him, probably
04:27:53<Cale>rzezeski: Basically the idea is that you pass to foldTree a replacement for the Empty tree and a replacement for the Node constructor, and it does the replacement throughout the tree.
04:28:02<rzezeski>Cale, in your 1st example, x could be _ in the lambda...so I'm starting to pick it up
04:28:09<scutigera>copumpki: duh. more darcs man page in my future
04:28:26<copumpki>darcs send will send it to his email address automatically I think
04:28:31<copumpki>assuming you darcs record your changes
04:28:34<Cale>rzezeski: yeah it could, since we don't care about the elements in the nodes
04:29:32<Cale>rzezeski: l and r are then the heights of the left and right subtrees
04:29:46<Cale>rzezeski: and we just have to say how they ought to get combined
04:30:12<scutigera>copumpki: I have non-trivial app to rewrite from ML in haskell. it's usefulness will be directly related to efficiency of uvector. should be fun.
04:30:53<rzezeski>cale: so far, how I read it is you generate a "closure" over the value 0 and a lambda and return a function that uses this initial value and lambda to .... ah I'm getting lost again
04:31:15<Cale>rzezeski: maybe it would help just to read it as...
04:31:48<centrinia>rzezeski, (foldTree f g t) literally replaces Empty with f, Node with g, and evaluates the whole tree.
04:31:49<Cale>foldTree e n Empty = e
04:31:49<Cale>foldTree e n (Node x l r) = n x (foldTree e n l) (foldTree e n r)
04:32:24<scutigera>copumpki: dotp.hs:14:7:
04:32:25<scutigera> Could not find module `Bench.Options':
04:32:31<Cale>(I only named the function f so that the repetition wouldn't be as tedious... there's also a small bit of potential gain in efficiency)
04:32:49<copumpki>scutigera: I don't think those examples have been touched in ages
04:33:06<Cale>rzezeski: Let's go back to the original definition I pasted and try substituting e = 0 and n = (\x l r -> 1 + max l r)
04:33:11<Cale>and see what f becomes
04:33:19<Cale>f Empty = e
04:33:22<Cale>becomes
04:33:25<Cale>f Empty = 0
04:33:26<scutigera>copumpki: Was hoping you would know what bench had moved to . there are a couple of hackages
04:33:34<Cale>f (Node x l r) = n x (f l) (f r)
04:33:37<Cale>becomes
04:33:45<Cale>f (Node x l r) = (\x l r -> 1 + max l r) x (f l) (f r)
04:33:56<Cale>and then applying the lambda, we get that
04:33:57<copumpki>scutigera: nope :/ dons might know though, he wrote that whole library, basically
04:34:05<Cale>f (Node x l r) = 1 + max (f l) (f r)
04:34:24<Cale>rzezeski: See how that's exactly the f we want?
04:34:29<scutigera>copumpki: are you doing some work with it currently ?
04:34:43<copumpki>scutigera: yeah, a bit
04:35:10<rzezeski>Cale: yes! I think it just hit me
04:35:16<scutigera>copumpki: I was under the impression you were helping with (re)construction
04:35:40<copumpki>scutigera: yeah, haven't had much time to work on it recently, am just cleaning up my patches before I send them to dons
04:36:01<Cale>rzezeski: You can regard foldTree e n as recursively replacing each Empty with e and each Node with n
04:36:39<Cale>for example, we could write our own showTree like:
04:37:05<centrinia>rzezeski, an analogy would be to consider (foldr f g) as replacing (:) with f and [] with g. ;)
04:37:16<Cale>foldTree "Empty" (\x l r -> concat ["(Node ",show x," ",l," ",r,")"])
04:37:58<Cale>or, to give more of a feel for what expression it will give when we apply an arbitrary foldTree to a tree, we could make that:
04:38:11<Cale>foldTree "e" (\x l r -> concat ["(n ",show x," ",l," ",r,")"])
04:38:39<Cale>(try it on some tree)
04:38:53<centrinia>mapTree f = foldTree Empty (\x l r -> Node (f x) l r)
04:38:56<scutigera>copumpki: nods sympathetically. attempting to work on blas. very slow progress, bogged down in learning haskell details.
04:42:52<rzezeski>Cale & centrinia: Thx for all the insight guys, I'm overwhelmed but appreciative
04:43:25<rzezeski>Cale: The last two foldTree are giving me parse errors (incorrect indentation)
04:43:32<Cale>oh...
04:43:44<copumpki>scutigera: oh, are you the developer of blas?
04:44:21<Cale>rzezeski: Where are you putting them? They're not complete function definitions
04:44:27<scutigera>copumpki: NO! but _very_ intereted in using it and trying to help out. Pat Perry is the dev.
04:44:31<Cale>showTree = foldTree "Empty" (\x l r -> concat ["(Node ",show x," ",l," ",r,")"])
04:44:41<Cale>showFoldTree = foldTree "e" (\x l r -> concat ["(n ",show x," ",l," ",r,")"])
04:44:47<rzezeski>I just put them in my source file and called :load in ghci
04:44:56<rzezeski>you must forgive me it's late and I'm tired
04:45:09<Cale>rzezeski: You can copy and paste those instead :)
04:45:42<scutigera>copumpki: just verified that other install does the right thing, it does :-)
04:46:37<scutigera>copumpki: blas is a pretty sticky wicket to start you haskell education. lots of monads + ffi...
04:47:02<rzezeski>Cale: ch03/Tree.hs:44:56:
04:47:02<rzezeski> Ambiguous type variable `t' in the constraint:
04:47:02<rzezeski> `Show t' arising from a use of `show' at ch03/Tree.hs:44:56-61
04:47:03<rzezeski> Possible cause: the monomorphism restriction applied to the following:
04:47:03<rzezeski> showTree :: Tree t -> [Char] (bound at ch03/Tree.hs:44:0)
04:47:03<rzezeski> Probable fix: give these definition(s) an explicit type signature
04:47:05<rzezeski> or use -fno-monomorphism-restriction
04:47:07<rzezeski>ch03/Tree.hs:45:53:
04:47:09<rzezeski> Ambiguous type variable `t1' in the constraint:
04:47:11<rzezeski> `Show t1' arising from a use of `show' at ch03/Tree.hs:45:53-58
04:47:13<rzezeski> Possible cause: the monomorphism restriction applied to the following:
04:47:14<Cale>rzezeski: ah, sorry
04:47:15<rzezeski> showFoldTree :: Tree t1 -> [Char] (bound at ch03/Tree.hs:45:0)
04:47:17<rzezeski> Probable fix: give these definition(s) an explicit type signature
04:47:19<rzezeski> or use -fno-monomorphism-restriction
04:47:21<rzezeski>Failed, modules loaded: none.
04:47:23<rzezeski>thats cool
04:47:52<Cale>rzezeski: I forget that I have ":set -XNoMonomorphismRestriction" in my .ghci file
04:47:54<rzezeski>I'll give you one more shot, then I must go to bed :)
04:47:59<rzezeski>ah
04:48:16<Cale>rzezeski: If you add an extra parameter or type signature, it won't complain
04:48:33<Cale>Or you can add {-# LANGUAGE NoMonomorphismRestriction #-} to the top of the file
04:48:44<scutigera>glad I'm not the only one who keeps running into that :-)
04:48:46<hatds>or define the functions with a full binding
04:48:56<hatds>like f = g becomes f x y z = g x y z
04:50:10<Cale>rzezeski: the extra parameter way would be:
04:50:15<rzezeski>Cale: well they ran, but unfortunately I'm too tired to go any further, hopefully some of what I learned tonight will sink in :)
04:50:17<Cale>showTree t = foldTree "Empty" (\x l r -> concat ["(Node ",show x," ",l," ",r,")"]) t
04:50:46<Cale>rzezeski: get some good sleep and have a look in the morning or something :)
04:51:00<rzezeski>will do, later guys
04:51:05<Cale>rzezeski: This sort of technique is sort of one of the things at the heart of functional programming :)
04:57:51<lament>my neural network doesn't learn stuff :(
04:58:50<copumpki>lament: maybe it's just a stupid simulated brain? :P
04:59:56<centrinia>Maybe it has brain damage. :(
05:00:30<lament>possibly :(
05:00:50<lament>does anyone know whether Oliver Boudry, author of hfann, exists on IRC?
05:06:57<copumpki>you could try /who Boudry
05:07:01<copumpki>with some asterisks
05:07:09<copumpki>but my client ignores responses to /who so I can't tell you
05:13:24<scutigera>what's AEq?
05:15:47<solrize>does every consistent first order theory have a proof theoretic ordinal
05:15:49<solrize>?
05:18:23<copumpki>scutigera: approximately equal?
05:18:25<copumpki>I think
05:22:05<scutigera>copumpki: There is a memory trying to resurface...of course. AEq is compliments of Mr. Perry. I thought it was a built-in.
05:22:44<scutigera>implements +/- epsilon checking
05:23:26<copumpki>yup
05:23:35<copumpki>but errors can build up that are larger than epislon can't they?
05:23:55<copumpki>> sum $ replicate 1000000 (0.3 :: Float)
05:23:57<lambdabot> * Exception: stack overflow
05:24:04<copumpki>> foldl1' (+) $ replicate 1000000 (0.3 :: Float)
05:24:05<lambdabot> 299546.7
05:24:20<lament>ugh
05:24:25<lament>this is why computers shouldn't do math
05:24:42<copumpki>it'd be nice if there was an elegant way of keeping track of how much error could potentially build up
05:24:46<copumpki>and using that in comparisons
05:24:51<copumpki>I guess it is still possible
05:24:56<lament>nullity to the rescue!
05:24:59<scutigera>HA ! Don't do that :-) I used lots of integer based loops that generate the real on the fly...
05:25:10<copumpki>> foldl1' (+) $ replicate 1000000 (0.3 :: Double)
05:25:11<lambdabot> 299999.99999434233
05:25:16<copumpki>that's much better, at least
05:25:25<copumpki>not many people use floats these days
05:25:41<copumpki>I used them because I needed the memory
05:25:59<scutigera>aeq is really more for checking residual error after you, for example, have just solved a matrix
05:26:27<scutigera>i used floats generically to talk about floating point. do all the actual math in doubles , of course.
05:27:48<scutigera>the really sneaky problem is subtracting to close numbers and ending up with a value close to zero. that's a problem in something as simple as complex division.
05:28:15<adu>hi
05:28:38<scutigera>there are some crazed maniacs out there writing numerical code using intervals to maintain accuracy...
05:29:08<adu>RIA
05:29:12<centrinia>I'm a crazed maniac? :(
05:29:26<adu>or what Sage calls RIF
05:29:33<scutigera>crazed maniac, in a _good_ way :-)
05:29:34<adu>= Real Interval Field
05:29:42<scutigera>that's the one
05:29:59<centrinia>I sometimes augment my doubles to make them quads. :)
05:30:13<adu>anyways, I just made a blog post about representing Haskell lists in RDF
05:30:25<scutigera>linky ?
05:30:33<adu>http://straymindcough.blogspot.com/
05:31:42<scutigera>merci
05:31:49<adu>yw
05:33:03<scutigera>water, water, everwhere, and not a drop to spare.
05:36:37<scutigera>centrinia: what kind of numerical code do you work on ?
05:36:55<ray>copumpki: if i rewrite haskell, there will be no more Floats and Doubles, just second-class IEEEFloat and IEEEDouble that you have to go out of your way to use :)
05:37:10<centrinia>I haven't done much numerical work recently.
05:37:28<ray>this is either why i should never rewrite haskell, or why i should
05:38:23<roconnor>ray: I was thinking the same thing
05:38:35<roconnor>ray: Removing Float and Double from Num
05:38:44<ray>i think some arbitrary-precision decimals would be nice
05:38:51<scutigera>fixed point !
05:38:53<roconnor>ray: until they learn to be associative.
05:39:07<roconnor>ray: CReal!
05:39:16<roconnor>> tan (10^100) :: CReal
05:39:17<lambdabot> 0.4012319619908143541857543436532949583239
05:39:28<centrinia>> 4*tan 1 :: CReal
05:39:30<lambdabot> 6.229630898619608922027899229833440692349
05:39:32<centrinia>> 4*arctan 1 :: CReal
05:39:33<lambdabot> Not in scope: `arctan'
05:39:39<roconnor>atan
05:39:40<ray>yeah, something like CReal
05:39:42<centrinia>> 4*atan 1 :: CReal
05:39:44<lambdabot> 3.1415926535897932384626433832795028841972
05:39:47<adu>ray: in that case use (IEEESingleFloat) and (IEEEDouble IEEESingleFloat) as the type names :)
05:39:53<roconnor>> pi :: CReal
05:39:54<lambdabot> 3.1415926535897932384626433832795028841972
05:39:57<ray>defaulting to floats when you type something like 4.4 is madness
05:39:58<centrinia>> sin (4*atan 1) :: CReal
05:39:59<lambdabot> 0.0
05:40:15<adu>whats CReal?
05:40:19<copumpki>computable reals
05:40:45<roconnor>adu: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers
05:41:05<scutigera>and an incomputable real ? 1.0/0.0 ?
05:41:23<adu>oh, so its really real!
05:41:31<mercury^>One whose digits you cannot compute.
05:41:39<mercury^>Like the Chaitin constant.
05:41:43<roconnor>adu: yes
05:41:51<adu>did you know that real numbers are equivalent to the type (Int -> Int)?
05:42:05<centrinia>Isomorphic. ;)
05:42:06<roconnor>adu: modulo an equivalence relation
05:42:10<copumpki>Integer -> Int ?
05:42:18<adu>oh hehehe
05:42:18<bd_>Integer -> Boolean
05:42:19<centrinia>Integer -> Bool
05:42:20<mercury^>Integer -> Integer.
05:42:24<copumpki>there are only finite functions Int -> Int
05:42:33<scutigera>a Chaitin constant or halting probability is a real number that informally represents the probability that a randomly-chosen program will halt
05:42:42<copumpki>mercury^: you could do it with a lot less than Integer in the range
05:42:48<scutigera>http://en.wikipedia.org/wiki/Chaitin%27s_constant
05:42:58<adu>I meant Integer -> Integer, but yes, Integer -> Bool has the same cardinality
05:43:01<bd_>[()] -> Bool
05:43:03<mercury^>copumpki: still has the same size.
05:43:08<centrinia>The real numbers are also isomorphic to the type [(Integer,Integer)] modulo two equivalence relations. ;)
05:43:12<copumpki>mercury^: sure :P
05:43:37<s11d>is it possible to set up tooltips for each cell of treeview in gtk2hs?
05:46:05<ray>using floats should never be the default in any language, it should be something programmers freely and knowingly choose as a concession to speed
05:46:15<copumpki>I agree
05:46:34<vegai>hey
05:46:49<vegai>anyone have a solution for my little socket-related dilemma...
05:46:57<adu>Are there any matrix libraries in Haskell I can use CReal as matrix elements with?
05:47:09<copumpki>adu: not that I know of
05:47:15<vegai>I launch a thread for each new incoming socket
05:47:21<adu>:(
05:47:29<centrinia>You could make your own.
05:47:41<vegai>th thread listens to a Chan and writes to that socket every time something's in there
05:47:52<adu>i only need Gaussian elim.
05:48:07<adu>and determinant
05:48:11<vegai>dilemma: if the socket dies, the thread writes to the socket at least twice before it notices the socket died
05:48:23<vegai>and I make log messages for each of those writes
05:48:24<adu>I don't know any optimizations for determinants
05:48:35<aavogt>adu: vec looks like it could work, since its elements are Num a => a
05:48:39<vegai>any way to detect death of a socket?
05:48:45<scutigera>adu: worth writing on your own as long as you are dot trying to solve ill-conditioned matrix. just use partial pivoting
05:48:48<adu>aavogt: cool
05:48:58<Cale>ray: It's too bad that CReal performs really poorly in anything but the most trivial of calculations.
05:49:21<copumpki>yeah, I'm sure it could be optimized a bit at least?
05:50:10<adu>vegai: if you see socket-blood everywhere
05:50:15<Cale>It's possible that the approach has to be different somehow. I'm not sure what it is, but even just adding up a moderate sized list of numbers gets really slow.
05:50:40<ray>binding libgmp or something would probably be cheating
05:50:54<vegai>adu: ayeee.....
05:51:01<Cale>Well, gmp has something a little different from CReal
05:51:29<scutigera>copumpki: arbitrary precision is never better than n log2 n, so quite the penalty when solving real problems.
05:51:30<adu>ray: I tried using gmp for the stuff I want to do, and it's algorithms for converting rationals to bigfloats broke everything
05:51:32<vegai>unix socket manuals state that a send to a dead socket is supposed to return 0
05:51:32<Cale>But it would be nice to have that too. (It has arbitrary precision floating point)
05:51:41<mercury^>mpfr is better than the gmp lib
05:52:14<adu>then I read that the rational->bigfloat conversion was "not for production use"
05:52:35<ray>sounds pretty open source to me, if you'll pardon the expression
05:52:35<adu>lol
05:53:03<adu>mpq->mpf to be precise
05:53:47<scutigera>mercury^: you know this from personal experience ?
05:54:14<mercury^>Yes.
05:54:42<scutigera>interesting. had not heard of mpfr until now. C lib, so a haskell ffi is in its future :-)
05:58:28<mercury^>Using it via the FFI will be difficult with GHC.
05:59:13<scutigera>how so ?
05:59:27<adu>I always wanted to write an arbitrary-precision library from scratch someday
05:59:51<scutigera>adu: quite non-trivial. learn to love fft's !
05:59:58<ray>do it in haskell, and i'll include it in my rewritten haskell
06:01:30<adu>ray: it would be internally base-10^9 (close to 2^30), and use the extra 2 bits for other stuff
06:02:19<deech>Hi all,
06:03:37<adu>scutigera: I've written an arbitrary-precision library for bigints, thats relatively easy, but floats are harder
06:03:56<deech>I am trying to do 'Maybe' operations in the IO Monad, something like this: {do x <- something; y <- somethingThatReturnsMaybe; liftIO print y}
06:04:50<deech>I think this needs the MaybeT monad transformer but I am not sure how to use it.
06:05:10<adu>deech: yes it does, and neither do I
06:05:58<scutigera>adu: cool...
06:06:05<adu>deech: you could always do case Nothing -> ... Just x -> ...
06:06:51<deech>adu: yes, I was trying to do this idiomatically.
06:09:21<adu>ray: have I talked to you about my rewritten Haskell?
06:09:35<ray>nope, what's in it
06:09:54<adu>ray: http://tetration.itgo.com/up/index.html
06:09:58<adu>ray: kinda like Agda
06:12:42<ray>hagda :)
06:13:39<adu>ray: the things I'm most concerned about is bringing together HList, NumericPrelude, and ByteString
06:17:04<ray>yeah, interesting
06:17:52<adu>I also which Parsec would work with ByteStrings...
06:18:01<adu>wish
06:20:22<adu>for example, I think (+) should be msum from Monoid, so you can do ("hello " + "world") instead of (++)
06:20:36<copumpki>mappend?
06:20:44<adu>hmm, yes mappend
06:21:03<Hunner>What is a function to return the biggest of [Int]?
06:21:08<copumpki>maximum
06:21:12<dobblego>@type maximum
06:21:13<lambdabot>forall a. (Ord a) => [a] -> a
06:21:17<adu>:t msum
06:21:18<lambdabot>forall (m :: * -> *) a. (MonadPlus m) => [m a] -> m a
06:21:30<Hunner>Ah thanks, was like "biggest, largest... no not it"
06:21:50<sjanssen>adu: but then we'd need a Monoid instance for every Num
06:21:59<adu>so?
06:22:01<sjanssen>(it's also not clear that addition is the best choice)
06:22:15<copumpki>multiplication works with many of them
06:22:37<copumpki>in fact, all of the built-in ones I can think of
06:23:23<sjanssen>except for usual caveats with floating point precision, of course
06:24:16<sjanssen>adu: is this language implemented?
06:24:19<adu>I've thought a lot about the numerical hierarchy, and I think that it really comes down to the Ring structure, which I think could most easily be defined as: class Group a => Ring a where (*) ... one ...
06:24:22<adu>nope
06:24:45<adu>where Group is an additive group
06:25:06<copumpki>how would you express that it depends on two structures?
06:27:15<adu>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5030#a5030
06:27:31<adu>that was my last notes on the subject
06:27:50<copumpki>I've done something quite similar to that :)
06:28:11<ray>yay, another numeric prelude!
06:28:12<sjanssen>adu: doesn't that Monoid class make a list instance impossible?
06:28:22<kyevan_>Is GHC's module/filename matching case sensitive? :(
06:28:42<sjanssen>kyevan_: on case sensitive filesystems, yes
06:28:59<adu>sjanssen: nope, how so?
06:29:08<copumpki>adu: what is sum1?
06:29:26<ray>preface, hehe
06:29:29<adu>copumpki: that would be concat
06:29:33<sjanssen>adu: oh, nevermind
06:29:47<copumpki>adu: how does it differ from sum?
06:30:34<adu>(+) = (++), (*+) = flip replicate, sum1 = concat, sum = concat, zero = []
06:30:35<sjanssen>copumpki: _|_ on empty lists, presumably
06:30:43<copumpki>hmm
06:30:43<sjanssen>personally, I'd remove it
06:30:51<adu>copumpki: sum1 is for lists with 1 or more elements
06:30:59<adu>and has no default for empty lists
06:31:03<copumpki>oh, Semi === Pointed?
06:31:10<adu>sum words for lists with 0 or more elements
06:31:21<sjanssen>adu: (*+) = concat . flip replicate
06:31:32<adu>Semi = SemiGroup
06:32:13<adu>supposedly associative
06:32:50<copumpki>ah
06:33:33<adu>sjanssen: oh, yes
06:33:40<copumpki>adu: don't abbreviate so much! :P and write quickcheck tests for each class :P
06:33:51<ski>adu : then why not remove `sum1' and place `sum' in `Semi', together with the condition that instances of `Monoid' define `sum zero' ?
06:34:20<ski>er, define `sum [] = zero'
06:34:24<ray>yeah, no abbreviation
06:34:28<adu>ski: that sounds complicated
06:34:30<hatds>what do we see as a use for a numeric prelude like this? (I enjoy this stuff just for mathematics sake, but I'm wonderin' about everyone else...)
06:34:32<sjanssen>adu: personally, I'd remove the redundant methods in each class
06:34:43<adu>so no sum1?
06:34:48<sjanssen>adu: sum1, *+ are good candidates
06:35:01<copumpki>hatds: not getting screwed when someone wants to define numeric types that the author of the classes didn't foresee, I guess
06:35:26<copumpki>hatds: the standard numeric typeclasses are fine for the built-in numeric types, but are uncomfortable for things that they didn't foresee
06:35:27<ski>adu : since it appears that for instances of `Monoid' your `sum1' and your `sum' will be the same, with the possible exception that `sum1' needn't (but could) be defined for the empty list
06:35:48<adu>but (*+) serves the purpose Prelude.^ does
06:35:52<ski>(s/could/might/)
06:36:09<copumpki>what algebraic structure covers matrix multiplication, by the way?
06:36:22<sjanssen>adu: I note that (^) is not a class method in the Prelude
06:36:23<copumpki>is there such a thing?
06:36:40<hatds>how many useful functions are there based on the current numeric prelude that aren't part of the prelude typeclasses themselves (like square :: Num a => a -> a or something)
06:36:42<adu>copumpki: depends, in the general sense Ring, in the case for square invertible matrices, Group
06:37:11<copumpki>not all marices can be multiplied together though, can that be captured?
06:37:13<adu>matrices can also be viewed as a vector space
06:37:23<copumpki>yeah, I've played with that
06:37:34<ski>*transformations* between vector spaces
06:37:40<Cale>hatds: infinitely many?
06:37:41<hatds>:)
06:38:13<hatds>that's not the answer I was looking for
06:38:26<ray>you mean functions that are in the preulde but aren't typeclass methods?
06:38:31<ray>prelude :/
06:38:42<hatds>no, not just those
06:38:56<hatds>but ones you wished you could reuse with your new numeric classes but couldn't
06:39:08<hatds>*new numeric types
06:39:30<ray>ah, you want to make stuff more general
06:39:41<Lemonator>say I have two patterns to match against, and the first one has a guard.
06:39:52<ray>i know those when i see them
06:39:55<Lemonator>if the first's guard fails, does it fall through to the second pattern?
06:40:08<sjanssen>Lemonator: correct
06:40:16<Lemonator>k
06:41:46<hatds>I think if we had convincing examples where the current prelude doesn't work well there would be more interest in using a better one, otherwise we'll only interest people who just like mathematically beautiful things :)
06:42:32<ray>not being able to define monads using join is somewhat annoying
06:42:33<copumpki>oh crap
06:42:35<sjanssen>hatds: a classic example are symbolic expressions, which can't have a reasonable Eq instance
06:42:37<copumpki>someone's started spamming hpaste
06:42:40<copumpki>*sigh*
06:42:42<ray>:(
06:43:13<hatds>sjanssen: yea, but what functions do you want to reuse?
06:43:18<adu>copumpki: at least they left their name
06:43:21<hatds>(I'm curious myself)
06:43:56<sjanssen>hatds: I want to reuse the usual math symbols (*, +, etc.)
06:44:10<hatds>you don't get a cookie :)
06:44:25<hatds>typeclasses aren't for using the name over again eh?
06:44:26<sjanssen>hatds: sum and (^) also
06:44:43<copumpki>(^) :: (Num a, Integral b) => a -> b -> a
06:44:44<copumpki>yeah
06:45:02<hatds>hm
06:45:03<copumpki>gdc and lcm might be applicable to some things
06:45:21<hatds>probably
06:45:27<copumpki>gcd, that is :)
06:45:29<wli>foldr gcd 0
06:45:29<ski>euler's totient function ?
06:45:43<Lemonator>What should I do if my lines get too long?
06:45:56<copumpki>Lemonator: just erase everything beyond column 80
06:46:13<ray>haha
06:46:21<hatds>Lemonator: if it is an expression like x = ... then I'd give names to subexpressions
06:46:39<adu>ski: that could theoretically be defined on any ring...
06:46:48<ray>haskell only needs 80 characters, it can infer the rest with pumpkin-zucchini expression inference
06:46:50<hatds>you need primes and ordering, agu
06:46:52<hatds>*adu
06:46:56<copumpki>lol
06:47:29<copumpki>also, having Num require Eq and Show is a pain
06:47:36<hatds>well I guess coprime is used for any commutative ring too
06:47:41<adu>but there are many functional equations that could be used to extend it to another ring
06:47:52<copumpki>so even if we don't use a full stack of algebraic structures, a bit of rearranging would be nice :)
06:47:59<adu>like phi(m^n) = phi(m)m^(n-1)
06:48:02<ray>i'm all for a full stack
06:48:05<copumpki>me too :P
06:48:17<copumpki>with provided quickcheck properties
06:48:29<copumpki>to help you check your law-abiding instances!
06:48:32<copumpki>:P
06:48:34<adu>quickcheck++
06:49:30<adu>but ya, Monoid, Ring, and Field are essential, must haves...
06:49:46<copumpki>and Magma ;)
06:49:50<jn>hello all. does anyone know if it is possible to get ghc to reliably throw exceptions in the event of a stack overflow nowadays? i know that Control.Exception lists StackOverflow as a case of AsyncException, but i'm not sure if it's used...
06:49:53<copumpki>the most important one of all!
06:49:53<ray>i'm all for doing similar things to functor et al
06:50:07<adu>copumpki: ok, but also kinda silly
06:50:09<Lemonator>is there a Haskell pretty printer like GNU indent?
06:50:30<adu>Lemonator: Yi?
06:50:43<sjanssen>Lemonator: Language.Haskell has one
06:50:57<Saizan>Lemonator: btw, you can split a line at any point, you just need to indent the second part appropriately
06:51:02<copumpki>adu: !!!
06:51:24<copumpki>holy crap
06:51:28<copumpki>the prelude has a lot of Ord instances
06:51:55<ski>@instances Ord
06:51:56<lambdabot>(), All, Any, Bool, Char, Double, Dual a, Either a b, First a, Float, Int, Integer, Last a, Maybe a, Ordering, Product a, Sum a, [a]
06:52:13<copumpki>http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html
06:52:13<sjanssen>copumpki: every Prelude type but functions, IIRC
06:52:25<hatds>and IO, IOError
06:52:31<sjanssen>ah, right
06:52:36<hatds>(has report open atm >.> <.<)
06:52:46<copumpki>how do you compare IOs?
06:52:51<ski>no
06:52:52<hatds>except them
06:52:57<copumpki>oh :)
06:53:17<adu>copumpki: what?
06:53:29<copumpki>I thought hatds meant that IO had an Ord instance
06:53:47<copumpki>but I missed the negation :)
06:53:48<hatds>yea, I meant the opposite.. have we confused everyone yet?
06:54:26<adu>but anyways, typeclasses are supposed to say things
06:54:54<adu>and all Magma says is that there's a binary operation, is that saying much?
06:55:05<copumpki>I was being stupid :)
06:55:09<adu>oh
06:55:22<copumpki>it can't hurt though
06:55:38<hatds>it doesn't even say stuff important in mathematics, so no it doesn't mean much for programming
06:55:40<adu>what would the operator me?
06:55:50<copumpki>\cdot
06:56:02<adu>(•)
06:59:35<adu>oh, I also think (!) should be in the Gettable class
07:00:10<hatds>generalizing lists?
07:00:21<adu>yes
07:00:35<adu>that always seemed very odd to me
07:01:33<adu>that arrays were used to rarely and has a short operator (!), and lists were used frequently, and have a long operator (!!)
07:01:44<copumpki>I agree
07:01:51<hatds>you use ! more with arrays
07:01:52<copumpki>the name is odd though
07:02:05<copumpki>(Int)Map could be an instance too, I guess
07:02:11<adu>i don't mind the name so much as its length
07:02:30<copumpki>IntMap might be more difficult
07:02:35<copumpki>adu: I mean, Gettable
07:02:42<adu>copumpki: :)
07:03:27<ray>ix is the oddest typeclass name ever
07:03:36<hatds>yea
07:03:46<adu>ray: thats my favorite class!
07:05:08<adu>why didn't they name it Index?
07:05:26<Cale>It's been largely forgotten that it was only named after the number of its definition in an ancient numbering system.
07:05:49<copumpki>seems like it could be a class with an associated type
07:05:50<Cale>;)
07:05:52<ray>yeah, i always think of dune
07:05:54<copumpki>for Key
07:06:05<copumpki>in the case of lists, you'd have Nat
07:06:15<copumpki>for arrays, you'd have a bunch of different Ixes
07:06:21<copumpki>and for Map you could have the map key
07:06:47<copumpki>a but like GMap I guess
07:07:13<adu>what was another big Prelude issue... Set!
07:07:23<hatds>?
07:07:27<copumpki>set! always bothered me in scheme
07:07:34<Lemonator>this pretty-printing business is harder than I thought.
07:07:38<adu>there was a big fiasco about the Set class
07:07:42<adu>or type
07:07:44<Lemonator>what's it going to take to have
07:07:47<copumpki>I want RMonad as the default Monad type :P
07:07:52<Lemonator>makePretty :: String -> String
07:07:53<Lemonator>?
07:08:05<copumpki>Lemonator: what are you pretty printing?
07:08:09<Lemonator>my own code.
07:08:13<copumpki>haskell?
07:08:17<Lemonator>yeah
07:08:22<copumpki>parse it with haskell-src-exts, pretty print it using that?
07:08:29<copumpki>not sure how good its pretty printer is though
07:08:40<hatds>RMonad?
07:08:44<hatds>reader?
07:08:47<ray>i just want the default monad to be definable using join
07:08:48<adu>or was it (Monad Set) that was impossible...
07:08:50<ray>restricted monad
07:09:00<Lemonator>It looks ugly to me, and I don't know how to manually give it good-looking indenting.
07:09:10<hatds>what are useful restricted monad instances?
07:09:17<copumpki>Set, for example
07:09:21<ray>RMonad Set, i guess
07:09:49<copumpki>it also comes with restricted functors
07:09:56<ray>fancy
07:10:07<copumpki>it would also allow us to make things like uvector into a (restricted) functor
07:10:15<adu>(Monad Set) i think was blocked by a lack of (Ord a =>) in front of Monad?
07:10:26<ray>i see it doesn't come with join as a method, though
07:10:28<copumpki>adu: yup, RMonad compensates for that
07:10:32<adu>oh ok
07:10:52<copumpki>ray: the regular Monad doesn't either does it?
07:10:53<copumpki>@src Monad
07:10:53<lambdabot>class Monad m where
07:10:53<lambdabot> (>>=) :: forall a b. m a -> (a -> m b) -> m b
07:10:53<lambdabot> (>>) :: forall a b. m a -> m b -> m b
07:10:53<lambdabot> return :: a -> m a
07:10:54<lambdabot> fail :: String -> m a
07:11:00<ray>nope
07:11:26<ray>i wan tit
07:11:31<ray>i want it
07:11:32<hatds>it doesn't seem like the two classes can be unified though
07:11:34<ray>no typos
07:11:36<hatds>RMonad and Monad
07:11:55<copumpki>hatds: no, but I don't see why you couldn't just remove Monad altogether?
07:12:02<copumpki>and replace it with RMonad
07:12:17<copumpki>same with Array, I guess
07:12:22<hatds>but then you don't have polymorphic bind/return
07:12:25<hatds>?
07:12:45<ski>@where RMonad
07:12:46<lambdabot>I know nothing about rmonad.
07:12:51<copumpki>http://hackage.haskell.org/packages/archive/rmonad/0.4.1/doc/html/Control-RMonad.html
07:13:05<jn>can anyone explain to me why i seem unable to catch async exceptions?
07:13:31<copumpki>jn: what would you do if you caught an "out of stack" exception?
07:13:38<adu>ray: another reason I want HList-like abilities builtin is that if heterogeneous lists were also linked, then you could implement zipWith# with fst, and snd
07:13:49<PetRat>I'm working through Typeclassopedia. Is this a proper implementation of Applicative for Maybe? http://www.mibbit.com/pb/pEDXaH
07:13:51<Saizan>jn: are you using Control.Exception.catch?
07:14:16<jn>Saizan: yes.. well, Control.Exception.try
07:14:24<copumpki>hatds: I think you do with FlexibleInstances
07:14:30<copumpki>unless I've misunderstood what you meant
07:14:46<Beelsebob1>copumpki: perhaps go "oh, shit, I'd better free up some resources, then display a dialog to the user, because I'm writing a GUI app, not a CLI app"
07:14:49<hatds>looks right to me, PetRat
07:15:01<PetRat>It obeys the one applicative law he mentions.. since that law involves pure, by necessity things are constructed with Maybe.
07:15:06<Saizan>jn: then the exception must be raised otuside of its scope
07:15:17<copumpki>Beelsebob1: but in many instances you don't have enough control to free up some resources do you?
07:15:32<ray>petrat: yeah, ((->) e) is the hard one
07:15:35<Beelsebob1>copumpki: why not?
07:16:03<Beelsebob1>copumpki: I would imagine 99% of stack overflows are caused by 1 enormous computation that couldn't quite fit... you let that stack unravel and catch it at the bottom
07:16:34<ski>PetRat : i think so
07:16:40<PetRat>Actually I screwed that up.. I was trying to say that in working on the applicative law, only the main case of <*> is exercised (the one in which both arguments are Just _)
07:16:50<copumpki>yeah, but how does that happen? say I stack overflow from evaluating foldl1 (+) [1..1000000000] and catch the exception... what do I do to recover?
07:17:25<ski> pure f <*> ia = fmap f ia
07:17:46<jn>Saizan: i'm likely doing something stupid. can you take a look? http://paste.lisp.org/display/80482
07:17:48<ski> if <*> pure a = fmap ($ a) if
07:18:06<ski>(well, renaming `if' to a non-keyword identifier, i suppose)
07:18:46<hatds>in C you would (supposedly, I've never done it) have saved memory before hand to execute your functions to recover from a stack overflow
07:18:46<Saizan>jn: (f 5) gets evaluated only after try returns, because of laziness
07:18:49<hatds>not sure how that works
07:19:03<Beelsebob1>copumpki: not much, except the knowledge that it happened
07:19:05<Saizan>jn: you've to use seq or $! to force evaluation
07:19:08<Beelsebob1>... now you can display a dialog
07:19:09<hatds>I guess you can reserve some emergency stack space in C?
07:19:11<Beelsebob1>rather than just crashing
07:19:12<Saizan>jn: or use evaluate instead of return
07:19:18<copumpki>Beelsebob1: wouldn't displaying a dialog require more stack space?
07:19:31<jn>Saizan: ah obviously.. thanks. been in ocaml land too long.
07:19:34<Beelsebob1>copumpki: stack space freed up by the fact that we're no longer computing 1000000000000 additions
07:19:51<Saizan>the exception surely frees that stack, yeah
07:19:52<ski> (if <*> ia) <*> ib = (fmap uncurry if) <*> (pure (,) <*> ia <*> ib)
07:19:56<copumpki>oh, so dumping it all
07:19:59<copumpki>fair enough
07:20:15<Beelsebob1>copumpki: it's normal to unwind the stack as exceptions are propogated down it, no?
07:20:25<Beelsebob1>just don't stick the catch in (+)
07:21:23<Cale>But what result do you return? The program can't continue, can it?
07:21:28<Beelsebob1>no
07:21:45<Beelsebob1>so you return the IO action that displays a dialog box on the screen saying "oh fuck"
07:21:52<Beelsebob1>and possibly an explanation that the operation the user was doing failed
07:21:57<Cale>Oh, you can do that currently.
07:21:58<Beelsebob1>rather than just bombing out
07:22:34<Beelsebob1>ah, woot, so maybe that answers the original question
07:22:40<Beelsebob1>ACTION goes looking for who asked about it
07:22:59<Beelsebob1>jn aparently
07:23:04<hatds>indeed
07:23:06<PetRat>ski: are these other laws of applicative.. fundamental, or derivable from pure g <*> x = fmap g x
07:23:12<PetRat>?
07:24:53<Cale>Prelude Control.Exception> Control.Exception.catch (do x <- evaluate (sum [1..1000000]); print x) (\(SomeException e) -> print "Oops!")
07:24:53<Cale>"Oops!"
07:25:41<Cale>But you have to know which computation is going to stack overflow ahead of time.
07:25:50<Cale>So that you know to force its evaluation.
07:26:16<hatds>doesn't sound that bad of a restriction
07:26:58<hatds>couldn't you just catch it really far down?
07:27:11<Cale>Well, you have to catch it from IO
07:27:34<ski>PetRat : iirc, those three i mentioned above is the applicative functor laws
07:28:14<ski>(you can replace `pure (,) <*> ia' with `fmap (,) ia')
07:28:58<EnglishGent>hello all :)
07:29:02<Cale>hello
07:29:10<EnglishGent>hi Cale :)
07:29:51<EnglishGent>can someone help me? I'm trying to follow a Haskell tutorial - but it tells me to use the line "import Text.Regex"
07:30:09<Cale>and you don't have the regex package installed?
07:30:10<EnglishGent>and that gives me the error "Failed to load interface for `Text.Regex'"
07:30:14<Cale>mhm
07:30:25<EnglishGent>I'm using ghc on Debian
07:30:32<EnglishGent>I just apt-getted it
07:30:43<Zao>There's a whole slew of packages in Debian.
07:30:45<Cale>Yeah, Debian's packages are really minimalist and split into a million pieces
07:30:49<EnglishGent>if it's not a standard library, the tutorial doesnt say how to get it
07:30:52<Zao>You most probably need one of the bazillion "optional" ones.
07:31:09<ray>a haskell-platform metapackage would be cool
07:31:15<Saizan>libghc6-regex-dev or something
07:31:39<Cale>libghc6-regex-base-dev, libghc6-regex-compat-dev, libghc6-regex-posix-dev
07:31:47<ray>i'm all for that package minimalism as long as they include nice metapackages
07:31:48<Zao>ray: Baby steps with a proper GHC package would be good first though.
07:32:04<EnglishGent>it's kinda confusing having a tutorial that fails on line 2
07:32:04<Cale>Debian is still shipping 6.8.2
07:32:12<Cale>(as is Ubuntu)
07:32:12<EnglishGent>but I'll try apt-getting all that stuff
07:32:17<EnglishGent>thanks all :)
07:32:37<Cale>EnglishGent: That stuff normally comes with ghc
07:32:39<ray>i've resigned myself to being stuck with the previous ghc
07:32:46<Zao>EnglishGent: Or you could always just install a nice binary GHC from the site.
07:32:52<Cale>EnglishGent: The Debian guys decided to split it all up into separate packages.
07:33:04<Zao>What could a major version and several minor versions ever add :)
07:34:02<EnglishGent>indeed Zao! :)
07:34:19<Cale>ACTION guesses that the people maintaining the Haskell-related packages in Debian and Ubuntu are not Haskell users.
07:34:43<copumpki>:o
07:35:46<ray>maybe i should do it, but i'm not nearly qualified
07:36:12<Zao>When you look into the Apt, the Apt looks back at you.
07:36:13<Cale>Well, maybe they are, but I'd sort of expect to see them around here at least occasionally...
07:36:37<EnglishGent>ACTION waits for extra packages to finish installing.... :)
07:36:57<ray>maintaining freebsd ports is super easy and i still managed to fail at that
07:37:14<Zao>ray: Well, you have to maintain boot files for that, won't you?
07:37:31<Zao>Last I checked, GHC only installs on i386 and amd64 :(
07:37:41<ray>boot files?
07:38:06<Zao>As far as I understand it, the ports port for GHC on FreeBSD downloads a mini-binary GHC that it uses to build the real deal.
07:38:24<ray>yeah, i don't know anything about that, i only maintained simple stuff
07:38:50<boegel>ACTION feels like his spamming haskell-cafe by replying to don and claus' responses
07:39:00<EnglishGent>ah... that changes my error message to the (more confusing) "tutorial.o: In function `s1j9_info':
07:39:00<EnglishGent>(.text+0x2711): undefined reference to `__stginit_regexzmcompatzm0zi92_TextziRegex_'
07:39:00<EnglishGent>collect2: ld returned 1 exit status
07:39:02<EnglishGent>"
07:39:05<ski>ACTION seems to recall twb maintained some haskell package in debian ..
07:39:11<EnglishGent>:/
07:39:30<Cale>EnglishGent: compile with --make
07:39:40<ray>i lost the domain i was using for email at the time, and never bothered to update it with the freebsd people
07:39:48<Cale>EnglishGent: (this is generally a good policy regardless :)
07:39:49<Zao>ray: Which disappointed me a lot on my fine sparc64 FreeBSD :(
07:40:46<EnglishGent>ah that works!
07:40:49<EnglishGent>ty! :D
07:41:13<EnglishGent>(what difference does --make make? I'm kinda new to Haskell...)
07:41:40<ray>basically, it links stuff
07:41:50<koeien>EnglishGent: finds -packages that are necessary automagically
07:42:02<koeien>in this case, something like regex
07:42:18<EnglishGent>ah - but surprised that isnt the default then...
07:42:45<koeien>if automated programs compile stuff, you don't want to do it with --make
07:43:05<koeien>because you may want to know precisely what the dependencies are
07:43:07<ray>make itself will replace --make in that case
07:43:20<EnglishGent>I'm trying to go through the tutorial at: http://www.lisperati.com/haskell/
07:43:27<koeien>i don't know why it isn't the defualt. it's a pretty frequently AQ
07:43:35<EnglishGent>it would be nice if it mentioned all this! :)
07:44:06<koeien>yes
07:45:14<EnglishGent>ACTION is fairly comfortable with Lisp & ML -- but had the advantage that the enviroments for them was already set up
07:45:16<EnglishGent>:)
07:45:42<koeien>aptitude install ghc6 on my machine :)
07:46:41<ray>i like those illustrations though
07:46:47<ray>lyah has some competition
07:47:41<EnglishGent>lyah?
07:47:49<koeien>learn you a haskell
07:47:53<koeien>@where learn you a haskell
07:47:53<lambdabot>I know nothing about learn.
07:47:59<koeien>@go learn you a haskell
07:48:00<lambdabot>http://learnyouahaskell.com/
07:48:00<lambdabot>Title: Learn You a Haskell for Great Good!
07:48:01<Saizan>@where LYAH
07:48:01<lambdabot>www.learnyouahaskell.com
07:48:04<EnglishGent>oh - if anyone knows any other good tutorials I'd love to hear :)
07:49:01<EnglishGent>this one looked good becuase it dealt with I/O right from the word go - and I'd like to be able to use Haskell for real world stuff - not just comp-sci lab illustrations
07:49:02<ski>@where YAHT
07:49:02<lambdabot>PDF: http://darcs.haskell.org/yaht/yaht.pdf Wikibook: http://en.wikibooks.org/wiki/Haskell/YAHT
07:49:09<ski>@where RWH
07:49:10<lambdabot>is http://www.realworldhaskell.org/blog/
07:49:16<mux>http://twitter.com/gvanrossum/status/1838308947
07:49:20<mux>ACTION nearly died laughing
07:49:29<koeien>i must say i dislike the final example of the lisperati tutorial
07:50:04<copumpki>:)
07:50:09<ski>(: mux
07:50:23<copumpki>anyone in here on twitter and not on the haskellwiki twitter page?
07:50:25<EnglishGent>why koeien?
07:50:38<copumpki>van rossum doesn't have that many followers on twitter, really
07:51:09<koeien>EnglishGent: lots of i/o :)
07:51:31<koeien>EnglishGent: i like more, smaller pure functions
07:52:00<boegel>mux: what's SICP?
07:52:06<copumpki>structure and interpretation of computer programs
07:52:09<mux>structure and interpretation of computer programs
07:52:11<mux>an MIT tetxbook
07:52:16<Gilly>i guess this: http://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs
07:52:17<koeien>for example, the writePoint functions should be defined outside
07:52:26<copumpki>boegel: isn't there some sort of duff's device that we can write in haskell, for streams?
07:52:30<EnglishGent>koeien - from a mathematical pov so do I .. but as a programmer - I'm of the opinion that if I cant write pacman in a language it's not a real-world tool :)
07:52:30<koeien>yes, i guess the reason for it was that MIT switched to python for that course
07:52:34<copumpki>boegel: about your email on -cafe
07:53:12<koeien>EnglishGent: yes, i am not questioning the example per se
07:53:14<boegel>copumpki: I don't know what a duff's device is... I'm guessing you're not talking about the beer brand in the Simpsons :)
07:53:35<koeien>this code makes it hard to debug & test from the GHCi command prompt
07:53:36<copumpki>boegel: something like http://en.wikipedia.org/wiki/Duff's_device for manually unrolling loops
07:53:56<copumpki>it could be done with a big tower of case statements in haskell
07:54:07<ray>it's a terrible yet compelling c idiom
07:54:25<ray>you manually partially unroll your loop
07:54:26<Saizan>EnglishGent: the point is on style and organization of code, haskell let's you document the use of side-effects in the type, but you cram everything in a big IO function you lose some of the advantages
07:54:42<Saizan>s/let's/let/
07:55:09<Saizan>"if you cram"
07:55:16<Saizan>ACTION needs more tea
07:55:18<boegel>ray: if it results in better performance, then I'm ok with it, I guess
07:55:29<boegel>ray: although I'd prefer getting good performance with 'clean' code
07:55:32<ray>i don't care about performance
07:55:38<ray>but i like duff's device
07:55:48<ray>it's very clever
07:56:20<copumpki>boegel: it might be possible to express such a thing as a stream function, so that front-end programs on uvector use it transparently
07:56:26<copumpki>boegel: needs more thought though :)
08:00:43<EnglishGent>ok I see that point Saizan - I'm only just learning how to I/O in Haskell _at all_ though :)
08:00:55<boegel>ray: it is kind of cool
08:01:09<koeien>EnglishGent: sure :) but this large example is perhaps not the best
08:02:22<ttwwii>Hello :D How to prove the equation: "map (f . g) = map f . map g" for infinite lists?
08:02:46<koeien>ttwwii: prove it for [], (x:xs) and, (x:_|_) iirc (not 100% sure)
08:03:16<ttwwii>ok thx :)
08:03:43<Saizan>ttwwii: have you read the "theorems for free" paper?
08:03:46<ski>ACTION would assume something with bi-simulation
08:04:22<ski>(forall n. take n as0 = take n as1) => as0 = as1
08:04:46<Saizan>at the end it has a simple criteria for telling when it's safe to extend it to corecursive values, iirc
08:10:39<zoran119>hey, i'm looking through xmonad config file which is written i haskell and i'm trying to understand it. there is a line that says ppTitle = \ _ -> ""
08:10:50<zoran119>now i think that it sets ppTitle to ""
08:10:56<koeien>zoran119: almost
08:11:02<zoran119>but can someone explaing the syntax
08:11:20<koeien>it is a function that, for every argument you give it, it returns "" (the empty string)
08:12:25<zoran119>_ matches every parameter, right?
08:12:29<koeien>yes
08:12:41<zoran119>what's \
08:12:43<ski>> let ppTitle = \_ -> "" in (ppTitle False,ppTitle 42,ppTitle "foo")
08:12:45<lambdabot> ("","","")
08:12:48<koeien>makes anonymous function
08:12:49<ski>> let ppTitle _ = "" in (ppTitle False,ppTitle 42,ppTitle "foo")
08:12:50<lambdabot> ("","","")
08:12:58<ski>> let ppTitle x = "" in (ppTitle False,ppTitle 42,ppTitle "foo")
08:12:59<lambdabot> ("","","")
08:13:07<ray>const "" would be prettier
08:13:13<koeien>ray: yes
08:13:42<ski>`\x -> ..x..' is the function that when given an argument, call it `x', returns the value of `..x..'
08:13:55<ski>> let f = \x -> x*x + 1 in f 10
08:13:57<lambdabot> 101
08:14:04<ski>> (\x -> x*x + 1) 10
08:14:05<lambdabot> 101
08:14:17<ski>> map (\x -> x*x + 1) [0..10]
08:14:19<lambdabot> [1,2,5,10,17,26,37,50,65,82,101]
08:15:22<ski>zoran119 : the `\' is the syntax that starts a function value (aka "anonymous function") .. it is supposed to be an ascii version of minuscle greek letter lambda
08:15:23<zoran119>i'm so lost, i don't even know if u are talking to me
08:15:31<koeien>:)
08:15:47<koeien>zoran119: there is an #xmonad channel afaik
08:15:58<koeien>zoran119: they might be able to answer how to change this setting
08:16:06<koeien>we would need some more context
08:16:37<ski>zoran119 : those lambdabot examples just above were meant to show a few different, but equivalent, ways of defining `ppTitle'
08:16:39<zoran119>koeien: i know... they helped me with the config by saying type this and type that
08:16:56<zoran119>i want to know the haskell part of it
08:17:01<koeien>oh
08:17:37<koeien>ppTitle = \_ -> "" means that the function for every argument (e.g., a window) gives ""
08:17:54<ski>zoran119 : generally, `foo = ..' names the (value of the) expression `..' with the name `foo'
08:18:23<ski>in this case, `ppTitle' is a name given to the (anonymous) function `\_ -> ""'
08:19:32<zoran119>ski: ah, i get it
08:19:48<EnglishGent>ok - gotta go irl... thanks for the help all - see everyone later :)
08:19:51<ski>instead of defining
08:19:53<ski> ppTitle = \_ -> ""
08:19:56<ski>you could do
08:20:01<ski> ppTitle _ = ""
08:20:02<copumpki>polyparse looks nice
08:20:12<ski>to define the same `ppTitle' with equivalent definition
08:20:16<zoran119>so by using \ you are omitting the name of the function, but still assigning its return value to ppTitle
08:20:26<ski>no
08:20:37<ski>the function itself is "assigned" to `ppTitle'
08:20:49<zoran119>ok ok
08:20:55<koeien>zoran119: sorta. not completely. the anonymous function gets then the name `ppTitle'
08:21:00<ski>iow `ppTitle' is the name that is here given to the (nameless) function `\_ -> ""'
08:21:35<ski>zoran119 : by using `\' we *can* omit naming the function, yes
08:21:37<ski>e.g.
08:21:47<ski>> map (\_ -> "") [1,2,3]
08:21:49<lambdabot> ["","",""]
08:21:57<joeally>i am trying to make a function that takes the mean from a list of numbers this is what i came up with" average (x:xs) = div x length (x:xs) + average xs"
08:22:19<ski>but in this case, the writer of the code directly gave the name `ppTitle' to the function *value* `\_ -> ""'
08:22:20<koeien>joeally: that is not correct
08:22:24<dcoutts>@seen aavogt
08:22:24<lambdabot>aavogt is in #arch-haskell, #haskell and #xmonad. I last heard aavogt speak 2h 33m 48s ago.
08:22:26<joeally>yes
08:22:32<joeally> i get a type error
08:22:42<koeien>joeally: even if you fix the types it's not the mean :)
08:22:43<copumpki>joeally: even apart from that
08:22:58<koeien>joeally: how do you define the mean normally?
08:23:01<ski>joeally : first, you must use more brackets
08:23:05<joeally>yes
08:23:20<joeally> i know what mean is
08:23:28<ski>`div x length (x:xs)' is parsed as `((div x) length) (x:xs)'
08:23:41<joeally>oh okay
08:23:42<koeien>joeally: how did you define it ? sum of the values divided by the number of values ?
08:23:45<joeally>yes
08:23:51<ski>whereas you (presumably) meant `div x (length (x:xs))'
08:23:57<joeally>yes ski thankyou
08:24:03<copumpki>it still isnt correct though
08:24:05<ski>that can also be written as
08:24:10<koeien>that doesn't mean that it's correct
08:24:12<ski> x `div` length (x:xs)
08:24:22<joeally>okay thanks ski
08:24:48<koeien>1. there is no base case. 2. the definition does not correspond to the mathematical definition of mean.
08:24:51<ski>> average [] where average (x:xs) = x `div` length (x:xs) + average xs
08:24:53<lambdabot> * Exception: /tmp/1880350984201788398:71:51-101: Non-exhaustive patterns in...
08:25:03<joeally>(x1 + x2 +x3)/3 is mean right
08:25:06<ski>> average [42] where average (x:xs) = x `div` length (x:xs) + average xs
08:25:07<koeien>joeally: yes. correct
08:25:08<lambdabot> * Exception: /tmp/6901507667190146830:71:61-111: Non-exhaustive patterns in...
08:25:17<joeally>that means x1/3 + x2/3 + x4/3
08:25:22<koeien>joeally: yep.
08:25:28<copumpki>> average [1, 2, 3] here average (x:xs) = x `div` length (x:xs) + average xs
08:25:29<lambdabot> <no location info>: parse error on input `='
08:25:31<copumpki>> average [1, 2, 3] where average (x:xs) = x `div` length (x:xs) + average xs
08:25:32<lambdabot> * Exception: /tmp/4174601387898950114:71:69-119: Non-exhaustive patterns in...
08:25:33<joeally>isnt that what i'm doin
08:25:45<koeien>joeally: no. the value of "length (x:xs)" changes while recursing.
08:25:58<joeally>oh
08:26:05<joeally>thanks compumpki
08:26:05<koeien>joeally: so when you go to the end of the list "length (x:xs)" becomes smaller
08:26:11<joeally>yes i know
08:26:15<copumpki>mostly koeien :) I just failed a couple of times
08:26:18<joeally>the whole function is this
08:26:25<joeally>average [] = 0
08:26:25<joeally>average [x] = x
08:26:25<joeally>average (x:xs) = div x (length (x:xs)) + average xs
08:26:36<copumpki>I'd hesitate to do [] = 0
08:26:42<koeien>average [] = 0 doesn't make sense
08:26:46<joeally>oh
08:26:47<koeien>you cannot divide by zero
08:26:51<ski>> average [1,2,3] where average [] = 0; average [x] = x; average (x:xs) = x `div` length (x:xs) + average xs
08:26:53<lambdabot> 4
08:26:56<copumpki>but you can leave [x] as a base case
08:27:00<joeally>yes but i have to put something
08:27:01<koeien>yes, in fact you should
08:27:18<koeien>joeally: no you don't ;) otherwise i would say error "the average of the empty list is undefined"
08:27:22<copumpki>joeally: one option is to make average return Maybe a (for Fractional a)
08:27:28<joeally>okay
08:27:41<copumpki>that's only if you're obsessed with having total functions though
08:27:55<ski>> average [1,2,3] :: Expr where average [] = 0; average [x] = x; average (x:xs) = x `div` fromIntegral (length (x:xs)) + average xs
08:27:56<lambdabot> 1 `div` 3 + (2 `div` 2 + 3)
08:28:04<ski>> average [1,4,2,8,4,7] :: Expr where average [] = 0; average [x] = x; average (x:xs) = x `div` fromIntegral (length (x:xs)) + average xs
08:28:05<lambdabot> 1 `div` 6 + (4 `div` 5 + (2 `div` 4 + (8 `div` 3 + (4 `div` 2 + 7))))
08:28:11<koeien>yes, you see the problem here.
08:28:30<joeally>yes
08:28:41<koeien>you can do this with some trickery. it helps if you have some scratch paper
08:28:50<joeally>okay
08:28:53<joeally>thankyou
08:28:59<ski>joeally : one solution is to make a local function that does the recursion, and compute the length once, for the "top" input list
08:29:02<joeally>i'll try the from intergral fucntion
08:29:13<copumpki>ski: that can cause space leaks though
08:29:23<ski>joeally : i just used `fromIntegral' there to appease `Expr' .. you need not pay that any heed
08:29:30<koeien>@let avg2 [x] = x; avg2 (x:xs) = x `div` (fromIntegral (length (x:xs)) + (length xs / length (x:xs)) * average xs -- something like this
08:29:30<lambdabot> Parse error
08:29:37<koeien>but this is needlessly complex :)
08:29:45<joeally>okay
08:29:53<koeien>the best way is to define two functions. one for the sum. one for the length. then say average xs = sum xs / length xs
08:29:55<dqd>> let avg x = fromIntegral (sum x) / fromIntegral (length x) in avg [1,2,3]
08:29:56<lambdabot> 2.0
08:30:01<ski>copumpkin : for otherwise incremental lists, sure
08:30:03<joeally>I'm new to haskell and just getting used to reocorrursion
08:30:05<pumpkin>koeien: I'm not sure I'd call that the best way :P
08:30:09<joeally>okay thats a good way koein
08:30:13<koeien>[you will have some space leak -- but for a beginner it's the best]
08:30:19<koeien>pumpkin: sure
08:30:20<pumpkin>unless you have the magic fold combinators!!
08:30:20<pumpkin>:P
08:30:21<koeien>;)
08:30:37<dobblego>@type uncurry div . (length &&& sum)
08:30:38<lambdabot>[Int] -> Int
08:30:39<ski>(joeally : hehe .. is "reocorrursion" supposed to be a mixture of "recursion" and "corecursion" ?)
08:30:46<pumpkin>then you can write sumF <^(/)^> lengthF
08:30:52<koeien>i had this in my introductory haskell class by the way, using tupling
08:31:03<pumpkin>koeien: you teach?
08:31:08<koeien>no, i am teached :)
08:31:12<pumpkin>oh :)
08:31:23<koeien>and i preach :)
08:31:45<pumpkin>:)
08:32:02<ski>(koeien : you could use `genericLength' as well, instead of `fromIntegral' .. except that meant i got the lengths in `Expr' too :)
08:32:32<joeally>is this a good function for sum :
08:32:33<joeally>sum (x:xs) = x + sum xs
08:32:47<koeien>ski: yes. but i was suggesting defining your own 'sum' and 'length' as an exercise.
08:32:47<ski>joeally : you're missing a base case there, as well
08:32:50<joeally>obviously with sum[x] = x
08:32:51<koeien>joeally: what is sum [] ?
08:32:52<ski>> average [1,2,4,9,6] :: Expr where average [] = 0; average [x] = x; average (x:xs) = x `div` genericLength (x:xs) + average xs
08:32:53<lambdabot> 1 `div` (1 + (1 + (1 + (1 + (1 + 0))))) + (2 `div` (1 + (1 + (1 + (1 + 0)))...
08:33:03<koeien>joeally: ok! fine.
08:33:15<koeien>joeally: you could make sum [] = 0 because the sum of zero elements is zero
08:33:27<joeally>i suppose
08:33:35<pumpkin>joeally: not sure how far along you are, but there are some nice higher order functions that allow you to avoid recursing manually
08:33:50<joeally>yeah but i'm learning
08:33:53<pumpkin>okay :)
08:33:55<koeien>(for averages, it is ok; but if you want to use this function elsewhere, it's nice to make it total :)
08:33:57<joeally>so i want to be able to implement them
08:34:11<ttwwii>I have a problem with prove for infiniti list for example map f (xs + ys) = map f xs + map f ys. + +
08:34:18<joeally>okay koeien
08:34:32<pumpkin>ttwwii: you mean ++ ?
08:34:36<ttwwii>yes :P
08:34:53<ski>@let avg2 [x] = x; avg2 (x:xs) = x `div` fromIntegral (length (x:xs)) + (length xs / length (x:xs)) * average xs -- something like this
08:34:54<lambdabot> <local>:1:97: Not in scope: `average'
08:34:54<ttwwii>have do it for (x:_|_ ++ ys)?
08:35:06<koeien>joeally: if you have this in a file, you might want to add the line import Prelude hiding (length, sum)
08:35:38<joeally>yeah i changed it to sum
08:35:42<joeally>sum1*
08:35:44<koeien>ok
08:35:56<joeally>because it seemed to clash wit some inbuilt fucntion
08:36:03<koeien>yep :)
08:36:32<koeien>so, you have sum1. and now length1 :)
08:36:43<ski>ttwwii : have you tried my suggestion ?
08:36:55<joeally>i'm just about to write lenght1
08:37:02<joeally>length1*
08:37:16<ski>my_length
08:37:29<ttwwii>ski: yes but i dont know excatly how to do it if i have (xs++ys)
08:38:06<mreh>is cabal very similar to apt-get on debian flavour *nix?
08:38:22<mreh>does pattern matching on the name i supply
08:38:42<ski>ttwwii : me neither .. but i'd try showing all approximations of the output lists are equal assuming all approximations of the input lists are equal
08:38:43<dcoutts>mreh: it's not nearly as mature, and it's source based.
08:38:43<lambdabot>dcoutts: You have 1 new message. '/msg lambdabot @messages' to read it.
08:38:57<joeally>koeien this is my length function
08:38:58<joeally>length1 [] = 0
08:38:58<joeally>length1 [x] = 1
08:38:58<joeally>length1 (x:xs) = 1 + length1 xs
08:39:10<koeien>joeally: correct. you don't need the second case though
08:39:15<joeally>okay
08:39:20<joeally>thanks :)
08:39:24<koeien>since it's covered by the last one :) do you see why?
08:39:27<mreh>dcoutts: the documentation is little thin, i'll try fully qualified package names
08:39:30<joeally>yes
08:39:33<joeally>i do now
08:39:44<mreh>dcoutts: it uses hackage as the package server does it not?
08:39:51<dcoutts>mreh: "fully qualified" ?
08:39:55<ski>(ttwwii : or maybe divide into cases : (a) infinite lists (`(forall n. as0 !! n = as1 !! n) => as0 = as1') ; (b) et.c. (partial, finite) .. but i'd prefer not to have to do this)
08:40:04<koeien>joeally: if you're starting out, it helps to give an explicit type signature for your functions
08:40:11<dcoutts>mreh: yes, that's the default sever set in the ~/.cabal/config file
08:40:21<mreh>superpackage.parentpackage.packagename
08:40:25<joeally>yeah i looked at that but it balffled me somewwat
08:40:28<mreh>that sort of thing
08:40:32<ttwwii>ski: ok thanks :P
08:40:32<joeally>somewhat*
08:40:47<koeien>joeally: you can ask ghci (or hugs, if that's what you're using) for the type sig of your functions.
08:40:54<joeally>okay
08:41:01<joeally>thankyou
08:41:14<koeien>i can understand that, because in this case you might get pretty strange type signatures (using (Num a) => ) and so on
08:41:20<magical_1ony>:t funcName
08:41:20<ski>(ttwwii : the reason for not liking the latter approach being that i'm not really convinced every list is infinite or not)
08:41:21<lambdabot>Not in scope: `funcName'
08:41:43<magical_1ony>:t length
08:41:44<koeien>ski: is 1:_|_ infinite?
08:41:44<lambdabot>forall a. [a] -> Int
08:41:45<joeally>thanks magical
08:41:57<dcoutts>mreh: the package namespace is flat, there is no super package or parent package
08:41:59<ski>koeien : that would be a partial list, in this terminology
08:42:00<joeally>:)
08:42:11<magical_1ony>no problem
08:42:25<joeally>so i would just put "average :: (Fractional t) => [t] -> t"
08:42:30<joeally> before average
08:42:35<ski>yes
08:42:38<koeien>joeally: yes.
08:42:45<ski>you may drop the brackets, if you wish
08:42:52<joeally>thankyou ski koeien
08:42:54<koeien>ski: that's style :) i like 'em
08:43:01<ski> average :: Fractional t => [t] -> t
08:43:17<joeally>thank you people
08:43:19<ski>koeien : sorry ?
08:43:36<koeien>ski: i like the parentheses there, in type sigs
08:43:48<joeally>ghci gives it with brackets
08:43:49<koeien>but it's a style thing. don't know what the consensus is
08:43:52<ski>you mean in constraints ?
08:43:54<koeien>ski: yes
08:44:21<ski>ACTION usually prefers the bare minimum that the syntax allows
08:45:07<mreh>Graphics/HGL/Key.hs:57:7:
08:45:07<mreh> Could not find module `Graphics.Win32':
08:45:07<mreh> it is a member of package Win32-2.1.1.1, which is hidden
08:45:07<mreh>cabal: Error: some packages failed to install:
08:45:07<mreh>HGL-3.2.0.0 failed during the building phase. The exception was:
08:45:07<mreh>exit: ExitFailure 1
08:45:29<mreh>hidden?!
08:45:32<joeally>get linux bro
08:45:33<dcoutts>that's borked
08:45:48<ivanm>what's borked?
08:45:53<magical_pony>bork bork bork
08:45:54<dcoutts>mreh: http://haskell.org/cabal/FAQ.html#hidden-packages-a
08:45:56<koeien>the cabal file :)
08:46:12<koeien>some build-depends missing probably
08:46:13<mreh>define: borked
08:46:24<koeien>(for your platform)
08:46:48<dcoutts>mreh: the package couldn;t possibly have been tested, it's missing important information in the .cabal file, the dependency on the Win32 package
08:47:05<mreh>thanks, dcoutts
08:47:34<dcoutts>mreh: HGL has no maintainer anymore afaik, I'd use a different graphics lib
08:47:43<mreh>which one?
08:47:57<mreh>dcoutts: which one?
08:48:10<dcoutts>depends what you're trying to do, if you wanted HGL for the SOE stuff then there are two other SOE implementations
08:49:07<mreh>dcoutts: i'm easy
08:49:24<mreh>SOE is so paltry though
08:49:45<mreh>i thought HGL was necessary for things like user input
08:49:49<dcoutts>mreh: I mean are you trying to draw simple 2d graphics, 3d, or GUI's with windows, buttons, menues etc
08:49:59<mreh>yes
08:50:11<ivanm>heh
08:50:14<koeien>:(
08:51:02<dcoutts>mreh: then you need a serious gui lib like gtk2hs or wxhaskell
08:51:35<dcoutts>gtk2hs does gui stuff and has a powerful 2d vector graphics api (cairo) and allows embedding 3d OpenGL drawing areas
08:52:11<trez>is there any easy way to know which array caused index out of range exception or do I need to catch this exception?
08:53:35<ivanm>trez: you're better of either not using !, or ensuring that you don't go out of range
08:53:44<mreh>dcoutts: I'll stick to HGL for my asteroids game for now, but thanks for the tips
08:54:06<mreh>hey, it's raining! yey!
08:54:08<ivanm>@hoogle Ix i => i -> Array i e -> e
08:54:08<lambdabot>Data.Array.Base (!) :: (IArray a e, Ix i) => a i e -> i -> e
08:54:08<lambdabot>Data.Array.IArray (!) :: (IArray a e, Ix i) => a i e -> i -> e
08:54:08<lambdabot>Data.Array.Base unsafeAt :: (IArray a e, Ix i) => a i e -> Int -> e
08:54:14<dcoutts>mreh: ok, but I wouldn't recommend HGL on windows, I don't think it works (even when it compiles)
08:54:27<ivanm>trez: hmmm... there's a lookup or something function in Data.Array.IArray IIRC
08:54:34<mreh>dcoutts: i'll test it
08:54:37<trez>ivanm: yea but to find the bug I need to know in what array it goes out of bounds
08:54:37<dcoutts>mreh: I think you may be letting yourself in for a lot of frustration, trying to use HGL
08:54:50<magical_pony>get a linuxes. make a small partition with ubuntu and go nuts.
08:55:12<mreh>sounds like a good idea, i have yet to do so on my laptop
08:55:27<trez>'run: Error in array index'
08:55:28<mreh>i prefer debian
08:55:41<trez>that does not say a lot..
08:55:42<ski>(mreh : raining lambdas ?)
08:55:49<dcoutts>mreh: http://hackage.haskell.org/trac/ghc/ticket/742
08:56:03<magical_pony>i'm running arch, it's an interesting distro
08:57:29<mreh>can anyone think how it might be possible to develop as3 games in haskell
08:58:56<zoran119>nope, .xinitrc doesn't work
08:59:08<zoran119>sorry, wrong forum
09:02:01<boegel>zoran119: you do realize you'll have to write 1,000 of lines of C now to make up for that?
09:03:46<zoran119>boegel: 46 lines to go!
09:06:08<Hunner>`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
09:06:14<Hunner>cat
09:06:22<Hunner>ugh, she's all wet too
09:07:28<Lemmih>?where ops
09:07:28<lambdabot>shapr Cale glguy dons sjanssen sorear dcoutts Saizan allbery_b dibblego conal Phillipa bos arjanb psnl lispy xerox vincenz davidhouse Heffalump kosmikus wli Pseudonym Igloo musasabi quicksilver
09:07:28<lambdabot>mauke
09:08:28<Saizan>Lemmih: you are an op too, btw
09:08:30<dcoutts>Hunner: or was I too quick? did you really mean your cat walked over your keyboard? :-)
09:08:36<pumpkin>I thought he meant that the cat walked on it :P
09:08:50<Hunner>uh, yeah, my cat walked on my keyboard
09:08:52<dcoutts>Hunner: apologies
09:09:27<Peaker>Who's D.A turner? Is he in #haskell?
09:09:59<mreh>Hunner: raining in London
09:10:14<Peaker>I'm reading the "Total Functional Programming" paper, and it seems very nice so far (written by him) :)
09:10:33<Lemmih>Oh my.
09:10:54<pumpkin>feel the power!
09:12:58<pejo>Peaker, "David Turner", the Miranda guy?
09:13:02<ski>Peaker : isn't Turner the one who invented Miranda ?
09:13:09<Baughn>@index unamb
09:13:09<lambdabot>bzzt
09:13:28<Peaker>pejo, ski: Possibly, I have no idea
09:13:55<dolio>Yes, that's him.
09:14:22<mreh>:t return
09:14:23<lambdabot>forall a (m :: * -> *). (Monad m) => a -> m a
09:14:32<mreh>:t return ()
09:14:33<lambdabot>forall (m :: * -> *). (Monad m) => m ()
09:15:12<quicksilver>Peaker: yes, that is David Turner who wrote Miranda. He doesn't IRC, as far as I know (I'd be surprised)
09:15:47<mreh>he wanted to keep all the lambdas to himself
09:16:10<osfameron>ACTION chants "Who ate all the lambdas?"
09:18:41<mreh>is "do" like a series of nested ">>"s but with a return () at the end?
09:19:04<mreh>IO, IO, It's off to work we go
09:19:42<mreh>>putChar '!'
09:19:44<Baughn>mreh: It's a series of nested >>=s, rather
09:19:51<Zao>do { a <- x; b x; c x } desugars to a >>= \x -> b x >>= c x
09:19:53<Zao>Or so.
09:19:54<Baughn>mreh: return would only be there if you put it there
09:19:54<mreh>> putChar '!'
09:19:56<lambdabot> <IO ()>
09:20:13<doserj>@undo do a; b; c
09:20:13<lambdabot>a >> b >> c
09:20:14<Zao>Err, x <- a
09:20:20<doserj>@undo do x <- a; y <- b; f x y
09:20:21<lambdabot>a >>= \ x -> b >>= \ y -> f x y
09:20:22<mreh>> putChar 'h' >> putChar 'e' >> return ()
09:20:24<Peaker>mreh: "do" doesn't add "return" anywhere. "do" puts >> and >>= and calls to "fail" when you use simple statements, name bindings for effect results, and pattern matches, respecitively
09:20:24<lambdabot> <IO ()>
09:20:54<mreh>ACTION brane asplode
09:21:04<mreh>didnt understand most of that
09:21:12<mreh>i'll come back when i've finished this lecture
09:21:31<Botje>long time no brane asplosions here
09:21:32<Botje>yay!
09:21:53<mreh>hurray!
09:25:05<Baughn>Botje: No, mine exploded yesterday, learning reactive
09:25:27<Peaker>Baughn: its surprisingly simple, IMO :)
09:25:42<Baughn>Peaker: Yes, well, I had to deal with bugs in reactive at the same time
09:25:49<Baughn>Peaker: ..wound up giving up. How does anyone /use/ that?
09:25:56<Peaker>Baughn: does it still have bugs in ghc>=6.10.2 ?
09:26:02<Baughn>Peaker: Yes
09:26:14<Peaker>Baughn: I don't think Reactive is in real use yet.. what bugs did you find in ghc>=6.10.2?
09:26:19<Peaker>(Reactive with that ghc, that is)
09:26:35<Baughn>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5018#a5018 <-- This just crashes
09:26:50<Baughn>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5020 <-- This.. stutters
09:28:05<Baughn>Peaker: I tried to learn FRP by using it. That was apparently my mistake. :/
09:29:34<HugoDaniel>hello
09:29:52<Peaker>Baughn: Interesting to debug it then
09:30:11<Baughn>Peaker: No, just impossible, but you're welcome.
09:31:12<alinp>hi
09:31:17<alinp>I'm missing something in haskell
09:31:22<alinp>I have a Main module
09:31:28<alinp>and ofc, a main function
09:31:36<Baughn>alinp: You're allowed to write longer lines
09:31:49<alinp>ok Baughn :)
09:32:05<alinp>and I want to call just a function, but without display something
09:32:08<Zao>Baughn: I feel limited by the 512 byte message size.
09:32:28<Baughn>Zao: So do I, especially as irssi doesn't split lines automatically - it just truncates
09:32:44<alinp>for instance, I don't want to print fib 35
09:32:50<alinp>I just want to call fib 35
09:32:54<Zao>let f35 = fib 35
09:33:05<Baughn>alinp: *Why* do you want to do that?
09:33:12<ray>but if you call it and don't do anything with the result, you might as well not call it
09:33:12<benign_failure>Hi. Visual Haskell, does it work with VS2008 (http://www.haskell.org/visualhaskell/ says "need VS2003 or VS2005") and is it a good ide for haskell on win32?
09:33:12<Zao>It'll probably not be evaluated unless the result is needed though.
09:33:15<alinp>testing purpose
09:33:37<ray>if you're testing it, you want to see the result, right?
09:33:44<Zao>> let x = undefined + 3 in 5
09:33:45<lambdabot> 5
09:33:46<ray>you probably want to load it in ghci and play with the function there
09:33:46<Baughn>alinp: Look in Control.Exception/Control.Parallel.Strategies
09:33:57<Baughn>alinp: evaluate . rnf to force evaluation at a specific poin
09:33:58<Baughn>t
09:33:59<alinp>no, I want to see how much is taking a function to run
09:34:08<Zao>alinp: The point is, it will not need to run.
09:34:08<ray>ah, profiling
09:34:11<Zao>As the result is not needed.
09:34:16<ray>you can profile it
09:34:41<HugoDaniel>benign_failure: i would try eclise haskell plugin instead
09:34:49<ray>i can't really tell you *how*, because i've never done it
09:34:55<HugoDaniel>s/eclise/eclipse
09:35:06<ray>are you using ghc?
09:35:20<benign_failure><- not an eclipse fan. But I will just try both ;)
09:36:14<HugoDaniel>benign_failure: personally i use vim (even on windows), and make sure eclipse or vs allow you to replace tabs by 4 space characters, it helps out in indentation
09:36:36<alinp>Zao: I want to run the function in a binary file
09:36:48<alinp>for instance, I want to compile the file and after that, to execute it
09:36:52<mreh>:t (>>)
09:36:53<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> m b -> m b
09:37:01<ray>benign_failure: since that website doesn't seem to have any recent updates, i expect visual studio 2008 wasn't out yet when they wrote that
09:37:07<alinp>and afaik this can be done when using main function
09:37:12<ray>yes
09:38:31<benign_failure>ray: aye, and I just found http://stackoverflow.com/questions/395828/visual-haskell-2008 doesn't seem to work with vs2008 :( okok, eclipse it is then
09:40:54<ray>alinp: you want to find out how long a function takes to run?
09:41:12<alinp>yes, but having a binary for it
09:41:25<ray>if you're using ghc, see http://www.haskell.org/ghc/docs/latest/html/users_guide/profiling.html
09:41:27<alinp>without using internal haskell libraries
09:41:36<Zao>benign_failure: EclipseFP works decently.
09:41:43<Zao>benign_failure: I prefer just using vim though.
09:41:50<alinp>I don't want to display anything
09:41:55<alinp>I just want to call a function :)
09:42:13<ray>if you call it and then don't do anything with the value, though, the compiler will optimize it out of existence
09:42:16<alinp>can't this be done in haskell ? I mean, I'm sure it can be done, but I don't know how
09:42:38<Baughn>alinp: I told you already. evaluate . rnf
09:42:49<ray>yes, that will work
09:42:55<alinp>oh, sorry, didn't saw that
09:42:55<ray>but printing it is probably a lot simpler
09:43:00<alinp>thanks guys
09:43:04<Baughn>Yes, but printing also affects the runtime
09:43:07<Baughn>Sometimes a lot
09:43:17<benign_failure>Zao: maybe vim is worth a look, too. Every 10 years I _could_ give it a shot :)
09:43:35<Baughn>Anyway, evaluate introduces an artificial external dependency, namely on the outermost constructor of what you pass to it
09:43:41<ray>last time i gave vim a shot, i installed nvi
09:43:47<Baughn>rnf collapses whatever value you pass to /that/ to a single ()
09:43:55<Baughn>So a combination will fully evaluate whatever
09:44:45<ray>i'll have to remember that one if i ever profile something
09:45:01<ray>or really, just remember those modules in general
09:45:26<Baughn>Control.Parallel.Strategies is absolutely crucial.. in general, really
09:45:29<Zao>benign_failure: http://www.cs.kent.ac.uk/people/staff/cr3/toolbox/haskell/Vim/
09:45:49<Zao>> let a = [0..] in Control.Parallel.Strategies.rnf a
09:46:02<Zao>ACTION rolls thumbs
09:46:05<lambdabot> thread killed
09:46:05<Baughn>Zao: ..yes, okay, that won't work
09:46:48<ray>makes sense
09:47:12<benign_failure>Zao: ty, I'll try it
09:47:18<Baughn>There are strategies meant to work on infinite lists. That isn't one of them. :P
09:51:49<Peaker>Cool, the "Total Functional Programming" paper just gave me an example of when Turing Completeness is a must for real-world programs: When writing an interpreter for your total language (You can write it in another total language, but at the end of the interpreters' tower, there's going to have to be a Turing Complete interpreter)
09:53:22<randomity>Peaker: yeah, that's also the easiest way to prove a language is turing-complete (write an interpreter for some trivial but known-to-be-complete language such as Unlambda or Brainfuck)
09:54:18<Peaker>randomity: Yeah, but you could say that's not a "real-world-interesting program" if you're assuming that turing-completeness is not necessary for interesting things
09:54:48<Peaker>randomity: but even an interpreter for a total (non-turing-complete) language requires turing completeness (or defers that requirement to the next interpreter)
09:55:16<Peaker>though I like the idea of putting turing completeness in a monad, like side-effects
09:55:56<quicksilver>Peaker: consider the language "Hello", in which programs are always precisely one instruction.
09:56:03<quicksilver>Peaker: that instruction is "World".
09:56:22<quicksilver>(the effect of executing 'World' is to print the text "Hello World")
09:56:37<Reiv>ACTION pokes his nose in inquisitively
09:56:41<quicksilver>the program "World" - which, in fact, is the only valid program - is also a perfect interpreter.
09:56:44<Badger>ACTION follows suit.
09:56:54<quicksilver>it interprets the only possible program, correctly.
09:57:05<Reiv>Any fans of parsers here? I have some Very Noobish Questions, as I'm having some trouble getting my head around the starting stages.
09:57:06<quicksilver>Obviously, Hello is a total programming language.
09:57:21<quicksilver>and yet, it contains its own interpreter.
09:58:02<Peaker>quicksilver: I'm sure you can add some prerequisites to what interpretation must be able to do to avoid the uninteresting trivial interpreters
09:58:12<ray>reiv: the only noobish thing is asking to ask :)
09:58:21<Peaker>Baughn: your Reactive program WorksForMe(TM)
09:58:32<quicksilver>Peaker: which prerequisites, though? :)
09:58:47<Baughn>Peaker: What ghc version?
09:59:09<Peaker>Baughn: 6.10.3
09:59:33<Peaker>Baughn: the latter program does have weird behavior :)
09:59:44<Peaker>Baughn: the former seems to function as you'd expect (the "fails" part)
10:00:30<Baughn>Peaker: Ah. Yes, 10.3 fixed that one, apparently
10:00:35<Baughn>It fails in 10.2 at least
10:00:57<Baughn>Peaker: Oh, but if you compile with -threaded, it fails
10:01:28<Peaker>Baughn: put {-# OPTIONS -O2 -Wall -threaded #-} at the top?
10:01:31<Baughn>Peaker: Unless you run it with +RTS -I0, in which case it doesn't
10:01:56<Baughn>ACTION shrugs. 'twas a throwaway test
10:02:57<Peaker>Baughn: I see, the former crashes with "thread blocked indefinitely", the latter "mostly works" but sometimes accumulates
10:03:52<Peaker>Baughn: something seems to be indeed buggy, not necessarily Reactive itself (as the ghc 6.10.1 bug has shown)
10:04:03<Peaker>Haskell needs better debugging tools, IMO
10:04:35<Baughn>Peaker: Conal believes it's reactive.. I think
10:05:08<Peaker>Baughn: I guess adding prints everywhere could help ;)
10:08:18<Baughn>Peaker: Or, rather, it's reactive /and/ GHC
10:08:44<Baughn>Peaker: There are still subtle bugs in the implementation of unamb (as you see with the spurious thread-lock thing), but mainly they're in reactive
10:08:48<Baughn>Hm..
10:09:11<quicksilver>ACTION notes that Reactive is an unusual case, insofar as it creates a need for debugging tools by going *beyond* haskell.
10:09:21<quicksilver>Reactive is partly code, partly compiler extension.
10:09:35<quicksilver>still, that doesn't mean the tools wouldn't be nice to have.
10:10:10<Peaker>why is it a "compiler extension"?
10:10:21<quicksilver>because it uses unsafePerformIO
10:10:28<quicksilver>that's a tool to extend the language/compiler/runtime.
10:11:04<Peaker>you can write a debugger that handles that
10:11:15<Peaker>at least for the "safe perform IO" case :-)
10:11:37<quicksilver>I didn't say, or suggest you couldn't.
10:11:53<quicksilver>I was just pointing out that reactive stresses things more than a pure haskell app.
10:11:57<quicksilver>because it's trying to hook into the RTS.
10:13:00<pozic>Is replicateM lazy for some monads?
10:13:17<Peaker>@src replicateM
10:13:17<lambdabot>replicateM n x = sequence (replicate n x)
10:13:29<Peaker>pozic: sequence is lazy for some monads, so yeah
10:13:34<tetha>heh, that program is efficient enough to break the exercise. "plot the runtimes for more threads and examine the speedup". The problem's: I cannot cram more input into the memory, and the runtime is still below any easy measurement
10:13:46<Peaker>> replicateM 99999999 [1]
10:13:48<lambdabot> * Exception: stack overflow
10:13:48<Baughn>> take 1 $ replicateM 999999999999999999 [1]
10:13:50<lambdabot> * Exception: stack overflow
10:14:04<Peaker>> replicateM 99999999 []
10:14:04<quicksilver>pozic: replicateM behaves like lots of >>s
10:14:05<lambdabot> []
10:14:23<pozic> fmap head $ replicateM 999999999 (Just 1) gives me a stack overflow
10:15:06<Berengal>> fmap head $ replicateM 100 (Just 1)
10:15:07<lambdabot> Just 1
10:15:33<Peaker>> replicate 9999999999 (Just 1)
10:15:34<Berengal>@src sequence
10:15:34<lambdabot>sequence [] = return []
10:15:34<lambdabot>sequence (x:xs) = do v <- x; vs <- sequence xs; return (v:vs)
10:15:34<lambdabot>--OR
10:15:34<lambdabot>sequence xs = foldr (liftM2 (:)) (return []) xs
10:15:34<lambdabot> [Just 1,Just 1,Just 1,Just 1,Just 1,Just 1,Just 1,Just 1,Just 1,Just 1,Just...
10:16:07<Peaker>> Identity 1
10:16:08<lambdabot> No instance for (Show (Identity t))
10:16:08<lambdabot> arising from a use of `show'...
10:16:19<Peaker>> getIdentity . Identity $ 1
10:16:19<lambdabot> Not in scope: `getIdentity'
10:16:20<Peaker>> unIdentity . Identity $ 1
10:16:21<lambdabot> Not in scope: `unIdentity'
10:16:32<Peaker>@hoogle Identity a -> a
10:16:33<lambdabot>Control.Monad.Identity runIdentity :: Identity a -> a
10:16:33<lambdabot>Prelude id :: a -> a
10:16:33<lambdabot>Data.Function id :: a -> a
10:16:45<pozic>That is not lazy enough for my needs.
10:16:52<Peaker>> runIdentity (replicateM 999999999999 (Identity 1))
10:16:53<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
10:17:11<Peaker>pozic: replicateM is lazy, Maybe and []'s monad instance seems to be the problem here
10:17:25<quicksilver>it's not a laziness issue.
10:17:28<quicksilver>it's semantics.
10:17:39<quicksilver>it has to get to the end of the list to check there isn't a Nothing.
10:17:55<quicksilver>> sequence [Just 1, Just 1, Just 1, Just 1, Just 1, Nothing]
10:17:56<lambdabot> Nothing
10:17:58<Berengal>> runIdentity $ fmap head $ replicateM 999999999999999 (Identity 1)
10:17:59<lambdabot> 1
10:18:21<quicksilver>sequence can't possibly return the 'Just' constructor until it's got to the end of the list?
10:19:18<Peaker>> sequence [[1],[1],[1],[1],[]]
10:19:19<lambdabot> []
10:19:25<Peaker>(ditto for lists)
10:19:47<Berengal>replicateM for Maybe is useless anyway
10:20:00<pozic>quicksilver: Ok
10:21:02<quicksilver>Berengal: sure, but the issue is the same for [] where it's not useless ;)
10:21:29<quicksilver>> sequence [[1],[1],[1],[1],[2]]
10:21:30<lambdabot> [[1,1,1,1,2]]
10:22:02<Berengal>quicksilver: Well, yes, but if you should happen to find yourself in the Maybe monad and need to replicateM, (fmap.).replicate will work just the same
10:22:14<Berengal>Except it won't die on you
10:23:07<quicksilver>> sequence [[1],[1],[1,1],[1],[2]]
10:23:08<lambdabot> [[1,1,1,1,2],[1,1,1,1,2]]
10:28:09<Peaker>Can a rewrite rule convert replicateM to (fmap.).replicate for Maybe's?
10:29:22<quicksilver>yes.
10:29:26<quicksilver>sounds like a stupid thing to do though :)
10:30:11<Peaker>quicksilver: why?
10:30:25<quicksilver>because replicateM isn't useful, in Maybe
10:30:34<Peaker>yeah, but maybe somebody's using it in polymorphic code
10:30:45<quicksilver>then a rewrite rule won't spot it.
10:30:46<quicksilver>;)
10:31:17<Peaker>quicksilver: not even when it could statically?
10:31:34<quicksilver>only if the polymorphic code gets inlined and hence specialised.
10:31:34<Berengal>Peaker: Separate compilation
10:37:32<lilac>i'm slightly surprised that GHC isn't smart enough to notice that forcing replicateM n (Just x) will always terminate, and with a Just constructor
10:39:51<quicksilver>lilac: are you also suprised it doesn't know sum [0,0...] is 0 ?
10:40:42<lilac>quicksilver: that's an excellent point, thanks ;-)
10:41:10<lilac>ACTION is grateful for being struck with a padded cluebat
10:41:55<doserj>sum [0,0...] = undefined is fine, but it could handle sum (replicate 1000000 0) better
10:42:04<tetha>who knows what kind of type hackery we are going to see.. so maybe somewhen such things as sum [0,0...] might be seen :)
10:42:37<tetha>er, there's a =0 missing
10:42:56<lilac>doserj: i think this all reduces to: GHC could optimize better if it could prove totality
10:43:41<lilac>that said, in cases such as replicateM n (Just x) and sum (replicate 1000000 0), proving totality seems pretty easy
10:44:19<tetha>you also need that 0 is a neutral element for the addition
10:44:45<lilac>tetha: specifically for +#
10:51:47<lilac>i've looked through the core; it's not fusing the sequence and the replicate together. optimizing further looks pretty hard.
10:58:25<pejo>lilac, I don't think you need totality for some of the stuff you want. I'm guessing Supero would do some of the things you want, and that even works without types.
10:59:00<quicksilver>static optimisations which reduce complexity classes are a two-edged sword.
10:59:22<quicksilver>static optimisations are by nature fragile, and it's annoying when your code suddenly jumps up a complexity class.
10:59:54<Peaker>quicksilver: could be nice to have a "suggestion" or so: "Can possibly reduce complexity/optimize blah blah"
11:00:14<Peaker>quicksilver: if these optimizations were explicit and not implicit (say, integrated in the editor, offering to optimize explicitly in the code), it'd be nicer still
11:00:38<quicksilver>But they apply to transformed code, not source code.
11:00:45<quicksilver>during the transformation, code gets duplicated and mvoed around.
11:00:56<quicksilver>there may not be sensible place in the source code to make the offer :)
11:01:08<pejo>Peaker, that's a whole lot of worrying about operational behaviour that is hard to predict.
11:01:18<quicksilver>ACTION likes to worry.
11:01:32<pejo>I prefer to worry when there's a reason.
11:02:28<pejo>I still can't tell what the result of fusing/specializing more than 2 or 3 functions will be, and that is far less than most pipelines people write in this channel.
11:06:24<ray>pipelines.. maybe flip (.) should be called (|)
11:06:29<ray>it's probably taken though
11:06:53<EvilTerran>| is reserved syntax for guards
11:06:54<Peaker>ray: (>>>)
11:07:13<Peaker>> ((+1) >>> (*2)) 5
11:07:15<lambdabot> 12
11:07:18<ray>i know, i'm thinking unix pipes
11:07:19<idnar>flip (.) should be (..), right? (except that's also reserved)
11:07:34<EvilTerran>unix (|) strikes me as more like flip ($) than flip (.)
11:08:05<Peaker>Maybe operator names should only be palindromes if they are cummutative
11:08:17<augustss_>yes!
11:08:17<lambdabot>augustss_: You have 1 new message. '/msg lambdabot @messages' to read it.
11:08:19<idnar>EvilTerran: depends on whether the first command needs input on stdin or not :P
11:08:23<Peaker>(.) is a palindrome so should be reserved for a cumutative function
11:08:31<idnar>*commutative
11:08:32<ray>yeah, except commutative
11:08:57<Peaker>(.) can be reserved for module attributes
11:09:32<ray><<< works and is asymmetrical, plus more general
11:09:36<idnar><<< is pretty unwieldy for function composition
11:09:45<ray>`fmap`
11:10:03<Peaker>maybe if all the arrow stuff was 2 instead of 3 (though && and || and ** are taken)
11:10:06<ray>personally, i like composition as dot, but there's good arguments for the other side
11:10:22<augustss_>I would exclude single character operators from the commutativity thing
11:10:22<idnar>presumably << and >> are also taken?
11:10:35<ray>augustss_: same
11:10:40<boegel>idnar: yeah
11:10:43<boegel>@type (<<)
11:10:45<lambdabot>Not in scope: `<<'
11:10:45<ray>consider (-) and (/) too
11:10:47<EvilTerran>>> is, by Monad; oddly, i don't think << is
11:10:52<EvilTerran>?hoogle (<<)
11:10:52<lambdabot>Text.XHtml.Frameset (<<) :: HTML a => Html -> b -> a -> b
11:10:53<lambdabot>Text.XHtml.Strict (<<) :: HTML a => Html -> b -> a -> b
11:10:53<lambdabot>Text.XHtml.Transitional (<<) :: HTML a => Html -> b -> a -> b
11:10:56<idnar>even (+) and (-) aren't necessarily commutative
11:11:03<Peaker>idnar: (+) better be
11:11:08<augustss_>Especially not -
11:11:17<idnar>er, heh
11:11:19<boegel>> (+) 1 2
11:11:20<lambdabot> 3
11:11:22<boegel>> (+) 2 1
11:11:23<lambdabot> 3
11:11:30<idnar>I meant (+) and (*), but I can't think of an example for (+)
11:11:36<augustss_>+ on Nat isn't commutative
11:11:38<ray>(+) is either required to be commutative or should be
11:11:44<Peaker>augustss_: why?
11:11:48<boegel>augustss_: ?
11:11:51<augustss_>_|_
11:11:57<idnar>ray: why?
11:11:57<Peaker>augustss_: in a total language :)
11:12:05<ray>hrm, _|_
11:12:09<augustss_>Ah, in the dream world. :)
11:12:11<boegel>ray: ass! :)
11:12:20<ray>the polite term is bottom
11:12:21<idnar>Peaker: this isn't #peakerlang :P
11:12:26<boegel>ray: same thing
11:12:33<Peaker>augustss_: you don't believe total languages will succeed as much as Haskell has already, in the next 15 years?
11:12:40<boegel>is it called bottom because it looks like an ass?
11:12:51<ray>that's just a happy coincidence
11:13:01<augustss_>Peaker: I think they might, because Haskell isn't really much of a success. :)
11:13:08<tetha>I think the proper term would be 'divergent computation', but thats unwieldy
11:13:19<Peaker>augustss_: successful enough to get real world work done with it :)
11:13:23<idnar>Peaker: if after 15 years they can't even match Haskell's success, they might as well give up
11:13:47<augustss_>Peaker: absolutely. There are already total languages used in the real world.
11:13:59<augustss_>Like SQL
11:14:36<idnar>SQL is total?
11:14:54<augustss_>idnar: yes, unless you have some weird extensions
11:14:57<blackh>It's total garbage. Does that count?
11:15:00<quicksilver>except for the most recent standard with the weird recurrence stuff.
11:15:13<idnar>blackh: hahaha
11:15:21<augustss_>blackh: In an argument to our advantage even garbage can be used.
11:15:22<quicksilver>xpath is probably total, isn't it? on a similar vein
11:15:29<idnar>maybe I don't understand what that means, then
11:15:34<quicksilver>it's quite a desirable property for a query language.
11:18:30<tetha>hm, unless the queried structure is mean and total queries cannot reach everything, I think
11:19:07<pozic>SQL as used in the real world is not total, some standard is, though.
11:19:44<quicksilver>ACTION thinks the vast majority of SQL uses in the real world are in the total subset.
11:19:47<Peaker>@hoogle catches
11:19:48<lambdabot>No results found
11:20:28<quicksilver>tetha: things like transitive closure are not generally expressible in total languages.
11:25:21<Peaker>is it safe to try to kill dead threads? Do thread IDs get reused?
11:25:45<roderyk>In my cabal file, I have under the executable " ghc-options: -threaded"; is there anything else I need to do? my executable is being run with a single thread (if I ghc --make -threaded .. ; myself, everything works fine)
11:26:31<Peaker>in umamb's source: (myThreadId >>= killThread) >> unblock (race a b) -- doesn't unblock (race a b) die immediately because of the killThread?
11:27:37<roderyk>oops, nevermind. I needed to clean dist/
11:29:18<Peaker>myThreadId >>= killThread will only continue execution until unblock, no?
11:31:30<Peaker>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5031#a5031
11:31:37<Peaker>doesn't killThread send an async exception?
11:33:26<tetha>ah, beautiful, my copy of "To mock a mockingbird" arrived
11:36:44<Peaker>weird! Control.Exception.block does not seem successful at blocking ThreadTermination
11:37:33<Peaker>or at least, when that termination is self-served
11:38:08<Peaker>ok, it does block thread terminations from other threads, but not from own thread...?
11:39:48<Peaker>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5032#a5032 -- prints haha1 only
11:40:01<Peaker>it should also print "haha". Is ghc's thread system very buggy? :(
11:41:06<blackh>Peaker: Threads aren't buggy but it doesn't seem to tolerate several threads writing to the console at the same time. It'll work if you put locks around the print's.
11:41:29<Peaker>blackh: same behavior if there's just one thread printing
11:41:44<blackh>Peaker: Actually the main thread is probably exiting too soon. Put a delay in the main thread.
11:42:38<Peaker>blackh: same
11:43:09<Zao>Or use mvars or suchlike to wait for worker threads to be done with work.
11:43:27<Peaker>blackh: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5033#a5033 -- no haha printed
11:44:58<blackh>Peaker: I have never looked at what 'block' does
11:45:41<blackh>But judging by the documentation, it looks like it doesn't block thread death. You might have to read the code.
11:45:55<blackh>Well, judging by your code and the documentation.
11:46:23<quicksilver>Peaker: maybe killThread blocks in that case?
11:46:58<quicksilver>Peaker: I.e. how do you know that that thread dies, rather than is just never reaching print "haha" ?
11:47:20<dibblego>do other Arrow instances often arise besides (->) and Kleisli m ?
11:48:15<Peaker>quicksilver: interesting proposition :)
11:48:40<quicksilver>dibblego: the only interesting arrow instances which are not kleisli arrows I'm aware of are the S-D parsers
11:48:56<Peaker>quicksilver: how can I know whether a thread is alive?
11:49:28<Peaker>Why are Kleisli arrows interesting and normal functions aren't?
11:49:29<quicksilver>I don't know.
11:49:42<quicksilver>Peaker: normal functions are kleisli arrows too.
11:49:48<Peaker>quicksilver: okay, so its probably a bug to (myThreadId >>= killThread) anyway, which conal uses in unamb
11:50:01<Peaker>quicksilver: of the identity monad?
11:50:07<quicksilver>right.
11:51:52<Peaker>@tell conal "myThreadId >>= killThread" appears in Unamb.hs and is probably a bug, because even when blocked, it probably blocks forever to deliver the exception
11:51:53<lambdabot>Consider it noted.
11:53:33<Peaker>I wonder why Unamb re-races stuff if it gets a thread termination
11:53:48<Peaker>Can anyone look at Unamb.hs:97?
11:54:02<Peaker>(unamb package: src/Data/unamb.hs)
11:54:37<Peaker>http://hackage.haskell.org/packages/archive/unamb/latest/doc/html/src/Data-Unamb.html
11:54:41<dibblego>what is S-D parser?
11:55:00<Peaker>I don't understand why the "Just ThreadKilled" handling makes any sense
12:02:26<quicksilver>dibblego: swierstra duponcheel
12:03:21<dibblego>is there a data structure declaration for such a parser?
12:03:25<Peaker>can evaluation cause execution of a killed thread to continue?
12:04:45<Xen0x>swierstra duponcheel?
12:04:56<Xen0x>never mind :)
12:05:00<Peaker>what happens to exceptions inside forkIO'd threads?
12:05:05<Peaker>the threads simply die?
12:05:07<Xen0x>it's Doaitses parsers I suppose
12:05:11<Peaker>(pure exceptions)
12:08:53<Peaker>a thread dying on an exception generates a message to stderr but otherwise execution continues?
12:09:33<Saizan>execution of other threads continue, yes
12:10:59<Peaker>how do you catch a pure exception in IO?
12:11:02<Peaker>@hoogle catch
12:11:02<lambdabot>package catch
12:11:02<lambdabot>Prelude catch :: IO a -> (IOError -> IO a) -> IO a
12:11:02<lambdabot>Control.Exception catch :: IO a -> Exception -> IO a -> IO a
12:11:22<Peaker>Prelude.catch does not seem to do it. Control.Exception.catch does?
12:11:29<Saizan>yes
12:12:11<Peaker>thanks
12:13:06<quicksilver>different versions of C.E.catch depending on your base version.
12:13:13<quicksilver>and Im' not sure what you mean by 'pure exception'
12:13:14<quicksilver>but, yes :)
12:13:45<Peaker>how do I use C.E.catch to catch all exceptions?
12:13:48<Peaker>base >=4
12:14:08<Peaker>const handlers leave ambiguous exception type variables
12:14:55<Peaker>ah, can catch (SomeException _)
12:15:48<Peaker>does catching SomeException catch all exceptions?
12:15:53<Saizan>yes
12:17:06<Peaker>weird way to handle exceptions right there :)
12:19:30<Saizan>it's like on java, so i guess it is :)
12:27:51<ivanm>is there a non-negative integer type?
12:28:07<koeien>no.
12:28:14<koeien>(not unbounded, anyway)
12:29:01<koeien>if you want the same size as "Int", use "Word" instead
12:29:27<ivanm>that's all I care about
12:29:31<ivanm>not having negatives
12:29:44<koeien>> 2^64 :: Word
12:29:45<lambdabot> 0
12:29:54<ivanm>how about one that only has positive integers? ;-)
12:30:11<ivanm>> fromInteger (-1) :: Word
12:30:13<lambdabot> 18446744073709551615
12:30:18<ivanm>:o
12:30:25<koeien>all arithmetic is mod 2^n
12:30:37<koeien>for some n, machine-dependent in the case of Word
12:31:06<ivanm>true
12:31:11<ivanm>> fromInteger (-2) :: Word
12:31:12<lambdabot> 18446744073709551614
12:32:30<Peaker>> -1 :: Word
12:32:31<lambdabot> 18446744073709551615
12:32:42<Peaker>ivanm: literals are already fromInteger'd
12:32:54<ivanm>oh, yeah... duh :s
12:34:21<quicksilver>koeien: Integer isn't mod 2^n
12:34:30<koeien>quicksilver: no. I was referring to Word
12:34:32<quicksilver>koeien: it just blows up your computer if you exceed the implicit bound.
12:34:47<koeien>i should have made this more explicit
12:34:51<quicksilver>*nod* ah, you said "all" :)
12:35:01<Peaker>stay away from the computer when it blows up
12:35:11<frwmanners>anyone know if there's a state of the art on automatic stack space analysis?
12:36:01<ivanm>@index Word
12:36:01<lambdabot>Data.Word, Foreign, GHC.Exts
12:49:25<xenoblitz>Hi people, I am sort of experimenting with GADTs
12:49:32<xenoblitz>I wrote this simple implementation here: http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5034
12:49:43<xenoblitz>but I have some problems... any input is greatly appreciated
12:50:13<koeien>xenoblitz: you need 'Wire Bool -> Wire Bool -> Wire Bool' for the And constructor
12:50:17<koeien>i guess
12:50:26<koeien>instead of Wire a -> Wire a -> Wire a
12:51:25<xenoblitz>koeien: I would actually like to interpret And for both types differently if possible... sort of overloading it for integers ( = max function) and booleans ( = conjunction function)
12:51:41<koeien>that is fine. but in that case you cannot use &&
12:51:55<koeien>:t (&&)
12:51:56<lambdabot>Bool -> Bool -> Bool
12:51:57<xenoblitz>koeien: ouch you are right
12:52:16<koeien>so i suggest to use a typeclass for this
12:52:39<xenoblitz>koeien: is there no other way that introducing a typeclass?
12:52:41<koeien>or use Ord
12:53:06<koeien>the only functions of type a -> a are id and _|_ :)
12:53:18<mmorrow>xenoblitz: : http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5035
12:53:33<koeien>so if you want to apply some "combinator" function, you will need a typeclass or a specific type
12:54:09<koeien>:t max
12:54:10<lambdabot>forall a. (Ord a) => a -> a -> a
12:54:15<koeien>> True `max` False
12:54:16<lambdabot> True
12:54:19<mmorrow>or you can use another GADT
12:54:42<xenoblitz>mmorrow, koeien: thanks for your input
12:57:09<xenoblitz>mmorrow, koeien: introducing the Ord a => to the and case and using the max function, and Eq to the equality case works like a charm :)
12:57:18<joeally>how do you pick the pivot in quicksort i forgot
12:57:57<joeally>do you just pick the term that is in the middle of the list?
12:58:04<koeien>xenoblitz: yep, but note that max for Bool is not (&&)
12:58:09<koeien>which is a bit painful
12:58:15<p_l>joeally: arbitrarily? There are different strategies, which, depending on the data, give different performance...
12:58:21<koeien>joeally: in quicksort, any pivot is good enough normally.
12:58:23<xenoblitz>koeien: yeah i just checked... its actually min :)
12:58:27<joeally>fair enough
12:58:33<joeally>thanks guys
12:58:43<joeally>i'm goin for the middle term in the list
12:58:44<koeien>in the canonical quicksort implementation in Haskell for lists, we pick the first element
12:58:52<joeally>oh
12:58:56<koeien>but you could equally well choose the last
12:59:01<joeally>really
12:59:04<ivanm>what's the minimum implementation of Show and Read? show and readsPrec respectively?
12:59:06<koeien>performance suffers a bit
12:59:11<joeally>i thought you chose one in the middle
12:59:32<koeien>joeally: Haskell's focus on lists makes the first element more convenient.
12:59:33<ivanm>joeally: it's arbitrary
12:59:39<koeien>joeally: but you can pick any
12:59:40<joeally>okay
12:59:49<p_l>joeally: the optimal selection depends on data distribution...
12:59:54<ivanm>then again, it isn't real quicksort, since it's meant to be in-place... >_>
12:59:59<joeally>yeah i suppose
13:00:08<ivanm>p_l: yeah, you use the middle one if it's already sorted :p
13:00:10<koeien>p_l: yes. to avoid ddos, sometimes a random pivot is chosen :P
13:00:27<koeien>DoS*
13:00:28<pozic>Does Foo{..}{a = b} work in record construction?
13:00:37<joeally>no i mean elemnt 4 if there is 8 in the list
13:00:39<ivanm>pozic: I think it would...
13:00:47<koeien>perhaps with additional parentheses
13:00:58<joeally>but first seems easier
13:01:03<joeally>so i'll go with that
13:01:40<koeien>pozic: yes it works
13:02:22<joeally>actually would using the mean as pivot be faster (in most cases) in quicksort
13:03:06<p_l>joeally: it would be, but you need to know the mean
13:03:15<koeien>joeally: how do you find the mean? you'll need O(n)
13:03:19<joeally>yeah i written a function for that eralier
13:03:28<joeally>earlier
13:03:41<p_l>joeally: it all breaks down to what is more efficient for the type of data you have to sort
13:03:46<pozic>koeien: there is no problem is using O(n)
13:04:00<pozic>koeien: in using O(n), is there?
13:04:06<koeien>hmm
13:04:06<mmorrow>xenoblitz: you can do stuff like this too http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5036
13:04:21<joeally>i am just doing a general one... i'm just writing it for learning
13:04:35<frwmanners>if you use first then [1..n] becomes O(n^2) no?
13:05:02<koeien>frwmanners: yes
13:05:16<pozic>frwmanners: if you use any fixed index, yes.
13:05:18<koeien>pozic: you would always get a O(n log n) algo that way, or am i wrong here?
13:05:36<koeien>although with a perhaps horrible constant, since finding the median is a bit tricky
13:05:51<pozic>koeien: ? median != mean
13:06:39<koeien>i am confused, how can you ever use the mean as pivot? or did you mean the "middle element" ?
13:06:51<mmorrow>xenoblitz: heh, i just realized that with that `Func', you have:
13:06:53<mmorrow>apply :: Wire (Wire a -> b) -> Wire a -> b
13:06:53<mmorrow>apply = simulate
13:06:56<joeally>no i meant find the mean of the whole list
13:07:01<mmorrow>xenoblitz: which seems interesting somehow
13:07:10<koeien>joeally: yes, but the mean of say [1,2,3,4] is not in the list
13:07:14<pozic>koeien: I thought the interesting piece of this discussion was the use of the mean. The behaviour of the median is well-known for quicksort.
13:07:16<joeally>so
13:07:20<joeally>it doesnt need to be
13:07:36<koeien>depends on the distribution of the numbers
13:07:41<ivanm>should Show and Read be prettified-output and parsing of same? or just using the constructors (i.e. deriving) ?
13:07:54<koeien>ivanm: you may choose.
13:08:06<frwmanners>qsort [2^(2^n) | n <- [1..10000]]
13:08:09<pozic>koeien: but there are probably inputs for which it doesn't work with the mean.
13:08:13<EvilTerran>pivoting is splitting into (<p), (==p), and (>p) - any one of those three lists can be empty
13:08:27<ivanm>"It contains only the constructor names defined in the data type, parentheses, and spaces."
13:08:28<joeally>pozic how
13:08:32<ivanm>^^ documentation from show
13:08:38<joeally>how can there be inputs for which it wont work
13:08:46<frwmanners>joeally: the one I just gave
13:08:47<pozic>joeally: by does not work, I mean O(n^2)
13:08:52<xenoblitz>mmorrow: hehe you fully blew the language up xD
13:09:00<joeally>oh
13:09:13<joeally>fair enough
13:09:32<joeally>it would be slower for large lists aswell
13:09:59<mmorrow>xenoblitz: :)
13:10:40<EvilTerran>using the mean should always terminate, seeing as forall xs. all (==mean) xs || (any (<mean) xs && any (>mean) xs)
13:11:14<koeien>in an ordered field
13:12:07<pozic>Emacs should insert a do when one uses <- in the code, when it is not there. I always forget those. I am probably not the only one who does that.
13:12:16<EvilTerran>well, yes. the statement's undefined unless mean and < have meanings.
13:12:18<koeien>it's in a certain sense ugly, because you need + and /, behaving nicely wrt <, while this is not necessary.
13:12:33<ivanm>pozic: ummm.... you can use <- in non-monadic code
13:12:45<EvilTerran>ivanm, you can?
13:12:48<pozic>ivanm: list comprehensions, what else?
13:12:53<pozic>ivanm: view patterns?
13:12:59<pozic>ivanm: I don't use view patterns
13:12:59<EvilTerran>pattern guards
13:13:06<EvilTerran>view patterns use ->
13:13:10<koeien>pozic: view patterns are -> aren't they?
13:13:26<ivanm>pozic: I meant list comprehensions
13:13:28<pozic>koeien: I don't use them. Obviously, I don't know.
13:13:41<pozic>ivanm: it is easy to see the difference between the two uses.
13:13:59<ivanm>pozic: if it is so "easy", then submit a patch to haskell-mode
13:14:06<pozic>ivanm: I was not outlining a complete and correct algorithm.
13:14:40<ivanm>ACTION hates it when people trivialise something as being "easy" to do, and complain that no-one has done so since it's so "easy"
13:14:56<ivanm>*despite it being so "easy"
13:15:04<pozic>ivanm: by easy, I mean that writing down a correct algorithm is not difficult. It might be that Emacs intricacies make things difficult.
13:15:20<ivanm>pozic: yes, I was hinting at things like that
13:15:30<pozic>Of course, it still remains a hack, like the rest of Emacs.
13:15:42<ivanm>even still, I'd be wary of something that inserted code it's "obvious" I want
13:15:50<ivanm>pozic: how is emacs a hack?
13:15:58<ivanm>elisp and how it's used might be a hack
13:16:03<ivanm>but I wouldn't say emacs itself is a hack
13:16:14<pozic>ivanm: I was mostly referring to all the modes.
13:16:35<ivanm>how they're implemented? or the fact that it uses modes?
13:16:42<Badger> * Endless formatting fixes
13:16:43<pozic>ivanm: how they are implemented
13:16:51<ivanm>class Mode m where... ;-)
13:16:55<Badger>...
13:16:59<pozic>ivanm: the fact that it uses modes is brilliant.
13:16:59<ivanm>pozic: yeah, so elisp is a hack ;-)
13:17:07<Badger>how did that happen.
13:17:09<EvilTerran>Badger, mispaste?
13:17:22<Badger>apparently I pressed up. :)
13:17:29<Badger>lots
13:17:32<Badger>oh well.
13:17:57<ivanm>so is there an "official" verdict on whether Show/Read should use pretty output/input as opposed to dedicated functions for printing/parsing?
13:19:59<bremner>ACTION wonders what pretty input is
13:20:18<ivanm>bremner: s/pretty/human readable/
13:21:14<ivanm>seems the wiki asks the same question ;-) http://haskell.org/haskellwiki/Show_and_Read_instance
13:22:05<pozic>ivanm: if you distribute your code, it might be nice to have (show .read) x == x
13:22:24<ivanm>pozic: well, yes, that's a given
13:22:31<doserj>*cough* the other way round *cough*
13:22:39<pozic>doserj: right
13:23:13<ivanm>but should I also have say write and parse that have (write . parse) x == x , and leave show and read for deriving whilst write and parse deal with more human-readable stuff?
13:23:41<Saizan>i'd say so
13:23:47<Twey>I'd do that, aye
13:24:00<ivanm>*nod*
13:24:03<Saizan>Show/Read should have valid haskell code as format
13:24:17<Twey>Well, parse is really only necessary if the format it uses is externally useful
13:24:28<bremner>ivanm: there is the general principle of be generous in what you accept and careful what you emit.
13:24:46<ivanm>bremner: hmmmm....
13:24:47<kpreid>Saizan: so the instance for Data.Set is wrong?
13:25:07<Saizan>bremner: that gets us the mess with HTML and browsers!
13:25:22<Saizan>kpreid: should it use Data.Set.fromList ?
13:25:22<joeally>I've written a quicksort function (kind of) but i'm not sure if this covers all bases :
13:25:25<joeally>qsort [] = []
13:25:25<joeally>qsort [x] = [x]
13:25:25<joeally>qsort (x:xs) = ((lthan x xs)++[x])++(gthan x xs)
13:25:25<joeally>quicksort x = iterate qsort x !! 2
13:26:03<Twey>ACTION tilts his head.
13:26:07<kpreid>iterate?!
13:26:09<ivanm>kpreid: I think the issue there is not to show internal details
13:26:09<Twey>Weird code
13:26:15<kpreid>I'm pretty sure that's not the right answer
13:26:16<Twey>Yeah, iterate on qsort? O.O
13:26:24<ivanm>but to still let people use Show and Read
13:26:31<bremner>Saizan: not at all, it just means web page "designers" are not following the principle
13:26:32<kpreid>Have you tried it on lists larger than 7?
13:26:36<joeally>as far as I can tell it should work on every thing
13:26:37<joeally>yes
13:26:40<koeien>joeally: how did you define lthan ?
13:26:45<joeally>wieght no i havent
13:26:48<joeally>yup
13:26:57<joeally>lthan n [] = []
13:26:57<joeally>lthan n [x] = if x<=n then [x] else []
13:26:57<joeally>lthan n (x:xs)
13:26:57<joeally> | x<=n = x:lthan n xs
13:26:57<joeally> | otherwise = lthan n xs
13:27:04<koeien>if it's just a filter, then it's not ok (use kpreid's suggestion) :)
13:27:12<Twey>joeally: The traditional Haskell qsort is qsort [] = []; qsort (x:xs) = filter (< x) xs ++ [x] ++ filter (>= x) xs
13:27:26<kpreid>Twey: ...it is?
13:27:27<joeally>yes it doesnt work kpreid
13:27:30<Saizan>bremner: my point is that if consumers don't enforce correctness then producers won't follow it
13:27:33<koeien>Twey: do not forget to call qsort on the left and right parts
13:27:37<joeally>twey : oh
13:27:38<Twey>Did I?
13:27:39<Twey>Oops
13:27:40<Twey>Yah
13:27:42<kpreid>joeally: you need to sort your left and right sublists
13:27:43<Twey>Yeah**
13:27:52<kpreid>rather than repeating the whole algorithm
13:28:00<Twey>qsort [] = []; qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
13:28:02<joeally>okay thanks no
13:28:10<joeally>no more clues
13:28:16<joeally>i wanna figure this out
13:28:27<Twey>joeally: Well, that's evidently not what you're doing. There are other ways.
13:28:37<joeally>i no
13:28:45<joeally>back to square one
13:28:46<Twey>ACTION winces.
13:30:52<joeally>got it
13:30:52<joeally>qsort [] = []
13:30:53<joeally>qsort [x] = [x]
13:30:53<joeally>qsort (x:xs) = qsort(((lthan x xs)++[x])) ++ qsort((gthan x xs))
13:31:05<joeally>is that right
13:31:23<Twey>Why did you put extra brackets around everything?
13:31:38<Twey>I think that's non-terminating
13:31:48<joeally>i come from python java etc
13:31:51<joeally>yes it is tweu
13:31:55<joeally>twey
13:32:01<joeally>i'll be back
13:32:07<Twey>You don't want to include x in the stuff that's getting sorted again
13:32:26<Twey>joeally: Ah, in Python you write ((func(arg, arg)))? :-P
13:32:31<joeally>yeah
13:32:42<Twey>That's not standard practice :) Stop it :-P
13:32:56<joeally>no muahah
13:33:01<stroan>also joeally no need to make the distinction between [x] amd x:xs cases
13:33:07<Twey>The Python folks will laugh at you too :-P
13:33:16<endojelly>so, how would I go about specifying different warning flags for ghc for one particular source file? when using --make? separately compiling the files doesn't work either, because they depend on other files which I would like to compile with the normal warning settings
13:33:24<joeally>okay stroan thanks
13:33:25<Twey>Yeah — you never use xs, so it's perfectly all right if xs is []
13:33:41<endojelly>alternative would be to not let ghc care about depending sources and let make do that job
13:33:45<endojelly>but I somehow like ghc --make
13:33:47<Twey>It'll just get caught by the empty case on the next recursion
13:33:49<endojelly>it makes Makefiles cleaner
13:34:31<endojelly>joeally, don't use func(...), that's rather confusing
13:34:39<endojelly>joeally, use (func ...) if you must
13:34:41<joeally>okat
13:34:43<joeally>okay
13:34:45<joeally>sorry
13:34:49<Twey>Especially when you get to multiple arguments
13:34:58<endojelly>joeally, heh, no problem, I don't really care, but it may save you a lot of trouble %)
13:35:02<Saizan>endojelly: you can put the flags in a {-# OPTIONS_GHC .. #-} pragma on the top of the file
13:35:07<Twey>func(foo bar baz) does not mean func foo bar baz
13:35:39<juhp>ACTION tries HipmunkPlayground
13:35:43<juhp>pretty cool!
13:35:46<joeally>yes i know tweu
13:35:53<joeally>twey
13:36:04<joeally>the brackets are evaluated first
13:36:18<endojelly>Saizan, ah, nice idea. now, the problem is: the files which should have different warning flags are generated by alex and happy. so unless I find a way to make it stick pragmas at the beginning (which may very well exist), I have to include the normal flags on *every* non-generated source file
13:36:22<Twey>jeu
13:36:28<deech>Hi all,I am trying to do 'Maybe' operations in the IO Monad, something like this: {do x <- something; y <- somethingThatReturnsMaybe; liftIO print y}
13:36:36<Twey>joeally**: Errr, that's a very confusing statement in Haskell
13:36:37<deech>I think this needs the MaybeT monad transformer but I am not sure how to use it.
13:36:38<endojelly>Saizan, but of course, if I can make alex and happy generate sources with those pragmas, this will work... thanks...
13:36:40<Peaker>Saizan: OPTIONS_GHC=OPTIONS? both fail to accept -threaded
13:36:51<Twey>They're not evaluated first, but they are evaluated separately
13:37:02<Twey>i.e. it will attempt to apply the function foo to bar and baz
13:37:19<Peaker>deech: something that returns maybe, you mean: IO (Maybe ...) ?
13:37:19<joeally>this workds
13:37:21<Twey>When foo, being an argument, might not even be a function
13:37:26<joeally>this works yay
13:37:28<joeally>qsort [] = []
13:37:29<joeally>qsort [x] = [x]
13:37:29<joeally>qsort (x:xs) = qsort ((lthan x xs)++[x]) ++ qsort (gthan
13:37:33<Peaker>deech: you'll need to transform IO (Maybe a) to MaybeT IO a
13:37:35<joeally>)
13:37:41<Peaker>@hoogle maybeT
13:37:41<lambdabot>package MaybeT
13:37:41<Twey>joeally: Good; now clean up the mess
13:37:41<lambdabot>Data.Maybe maybeToList :: Maybe a -> [a]
13:37:48<joeally>qsort [] = []
13:37:49<joeally>qsort [x] = [x]
13:37:49<joeally>qsort (x:xs) = qsort ((lthan x xs)++[x]) ++ qsort (gthan x xs)
13:38:19<Twey>As mentioned, the [x] case is unnecessary; additionally, you don't need brackets around any of that except the lthan/gthan expressions (++ is associative)
13:38:22<joeally>yeah
13:38:30<joeally>it is
13:38:36<Peaker>deech: MaybeT is pretty trivial, you don't "need" it except for convenience -- if your thing is that simple, you can handle the maybe cases explicitly
13:38:52<joeally>i do need qsort [x] = [x]
13:38:56<Saizan>Peaker: that's because -threaded is a link time option, it doesn't really make sense for a single module
13:38:59<joeally>other wise i get stack overflow
13:39:10<Peaker>Saizan: oh
13:39:12<deech>Peaker: Do you mean that my somethingThatReturnsMaybe should be a somethingThatReturnsAMaybeT?
13:39:17<Berengal>joeally: That's because your inductive case is wrong
13:39:18<Twey>joeally: Only because you forgot to handle the case where x == head xs
13:39:23<endojelly>joeally, this might be even easier to read: qsort (x:xs) = qsort ((x `lthan` xs) ++ [x]) ++ qsort (x `gthan` xs)
13:39:27<deech>Peaker: I'm trying to learn to use monad transformers
13:39:28<Saizan>Peaker: except for Main, maybe
13:39:30<Twey>lthan x xs = filter (< x) xs, and gthan x xs = filter (> x) xs
13:39:37<joeally>yeah i supose
13:39:42<Peaker>deech: if you want to use MaybeT, yeah. Or you can just convert an IO (Maybe a) to MaybeT IO a with the MaybeT data constructor
13:39:45<Twey>But it should be either <= or >=
13:39:54<joeally>na my lthan is rather more convoluted
13:39:55<Twey>You need to include the elements that are equal to x somewhere
13:39:59<Saizan>endojelly: i think if you put them in the .x and .y files they might get copied into the final .hs
13:40:06<joeally>lthan n [] = []
13:40:06<joeally>lthan n [x] = if x<=n then [x] else []
13:40:06<joeally>lthan n (x:xs)
13:40:06<joeally> | x<=n = x:lthan n xs
13:40:06<joeally> | otherwise = lthan n xs
13:40:07<Peaker>deech: MaybeT :: Monad m => m (Maybe a) -> MaybeT m a
13:40:11<Twey>joeally: For no good reason
13:40:17<Twey>You've just reimplemented filter
13:40:17<joeally>yes
13:40:22<Twey>Square
13:40:25<joeally>or list comprehension
13:40:29<xenoblitz>koeien, mmorrow: do you think its possible to create the same effect using phantom types rather than GADTs? I am finding problems with defining simulate
13:40:39<joeally>i forgot about those though
13:40:48<Peaker>joeally: why do you handle the [x] case specially?
13:41:07<endojelly>Saizan, there's ways to include arbitrary stuff, I just have too hope that the pragmas don't come too late (e.g. language pragmas need to come *before* the module declaration), but yeah, I think it'll work
13:41:11<endojelly>I'll try right now
13:41:12<joeally>i thought it wouldnt work otherwise
13:41:14<deech>Peaker: Can I use lifting to convert a function that returns to one that returns MaybeT?
13:41:21<Peaker>joeally: think about what happens if you remove it
13:41:34<joeally>in lthan or qsort
13:41:40<Peaker>deech: lift would convert an IO a to a (MaybeT IO a)
13:41:42<deech>Peaker: rephrase, Can I use lifting to convert a function that returns Maybe to one that returns MaybeT?
13:41:42<stroan>either
13:41:52<stroan>think what would happen if xs was []
13:42:08<joeally>oh yeah
13:42:17<Peaker>deech: I *think* that lift is just (fmap return) in many monad transformers, but I'm not sure. Its the case in MaybeT, at least
13:42:33<joeally>i get stack overflow in qsort though
13:42:39<mmorrow>xenoblitz: you can kinda get the same effect with phantom types, but you lose the ability to just not handle cases which the GADT's types don't allow, whereas with phantom types it's possible to build those cases if you have the constructors available
13:42:44<Peaker>deech: By "returns..", do you mean "evaluates to a value of type.."?
13:42:55<Peaker>deech: or "evaluates to a value of type (Monad m => m ...)" ?
13:43:09<stroan>joeally: you don't want n to be included in the output of lthan
13:43:15<mmorrow>castPtr :: Ptr a -> Ptr b; castPtr (Ptr addr#) = Ptr addr#
13:43:26<stroan>because you have lthan ++ x ++ gthan
13:43:30<mmorrow>(data Ptr a = Ptr Addr)
13:43:38<mmorrow>err
13:43:40<mmorrow>(data Ptr a = Ptr Addr#)
13:43:57<xenoblitz>mmorrow: I don't understand what you mean unfortunately... let me show you my implementation so far
13:44:25<deech>Peaker: the former, I already have a somethingThatReturnsAMaybe function and I'd like to reuse it in my example.
13:44:38<endojelly>Saizan, hmm. the options in that pragma are actually *pre*pended
13:44:59<xenoblitz>mmorrow: http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5038
13:45:06<Peaker>deech: lift is a bit like return -- it puts a value in a monadic shell that has no effect -- thereby "lifting it" from some internal monadic value to a bigger/outer monadic value
13:45:16<xenoblitz>mmorrow: i am getting an error with the second casen ow
13:45:18<xenoblitz>*now
13:45:39<mmorrow>xenoblitz: so for instance, i can do:
13:45:52<mmorrow>W (ConstI 42) :: W Bool
13:46:09<Peaker>deech: your function that returns IO (Maybe a) -- if it returns Nothing -- does it indicate a failure/exception that should stop further execution unless caught?
13:46:18<endojelly>Saizan, well, okay, disabling all warnings (-w) works... guess that's okay right now
13:46:19<mmorrow>xenoblitz: so you lose the guarantee that if you get passed a (W Bool), it really is what it claims to be
13:46:35<mmorrow>xenoblitz: but you can guard against that by not exporting the constructors
13:47:00<mmorrow>(whereas in the GADT case, (W (ConstI 42) :: W Bool) wouldn't typecheck
13:47:00<xenoblitz>I was going to export just the functions shown in the above hpaste
13:47:05<endojelly>make 2>&1|wc -l
13:47:05<endojelly>506
13:47:05<endojelly>make 2>&1 7,02s user 0,66s system 94% cpu 8,078 total
13:47:07<xenoblitz>I understand
13:47:08<endojelly>I have a lot to do :/
13:47:09<xenoblitz>that's good to know
13:47:37<deech>Peaker: Hmmm, I'll have to think about it a little more .... thanks for your help.
13:47:56<deech>Peaker: yea
13:48:02<deech>Peaker: yes
13:48:25<Peaker>deech: then it should probably use MaybeT IO a instead of IO (Maybe a)
13:48:55<Peaker>deech: MaybeT IO a is basically the same as IO (Maybe a) that stops binding new IO actions if actions so far evaluated to Nothing
13:49:05<lilac>@wiki New monads/MaybeT
13:49:06<lambdabot>http://www.haskell.org/haskellwiki/New_monads/MaybeT
13:49:19<lilac>^^ MaybeT
13:49:28<xenoblitz>mmorrow: do you think that I can still write the simulate function using phantom types though or it is not possible?
13:53:05<Peaker>when is lift /= wrap . fmap return ?
13:53:23<Peaker>I don't know ContT very well, sounds like the craziest monad - is it not true there?
13:53:26<ivanm>@hoogle wrap
13:53:26<lambdabot>Control.Applicative WrapArrow :: a b c -> WrappedArrow a b c
13:53:26<lambdabot>Distribution.Simple.Utils wrapLine :: Int -> [String] -> [[String]]
13:53:26<lambdabot>Control.Applicative WrapMonad :: m a -> WrappedMonad m a
13:53:32<ivanm>what's wrap?
13:53:35<ivanm>@hoogle lift
13:53:36<lambdabot>Control.Monad.Trans lift :: (MonadTrans t, Monad m) => m a -> t m a
13:53:36<lambdabot>Text.ParserCombinators.ReadPrec lift :: ReadP a -> ReadPrec a
13:53:36<lambdabot>Language.Haskell.TH.Syntax lift :: Lift t => t -> Q Exp
13:53:48<Peaker>ivanm: wrap is the monad transformer's constructor
13:53:56<Peaker>@src ContT
13:53:56<lambdabot>newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }
13:54:16<Peaker>@src ContT lift
13:54:16<lambdabot>Source not found. There are some things that I just don't know.
13:54:24<Peaker>@src ContT return
13:54:24<lambdabot>return a = ContT ($ a)
13:54:33<ivanm>Peaker: so should it be Wrap? or is it a function that applies the constructor?
13:54:45<Peaker>ivanm: its just the constructor itself, but there's no way to generalize it
13:54:52<Peaker>for example, MaybeT's lift is: MaybeT . fmap return
13:54:56<ivanm>so shouldn't it be Wrap?
13:55:03<Peaker>what's Wrap?
13:55:06<Peaker>oh
13:55:09<ivanm>oh, you're using it as a generic constructor?
13:55:12<Peaker>yeah
13:55:28<Peaker>I am thinking maybe one could even generalize all monad transformers?
13:55:30<Peaker>but probably not
13:57:13<ivanm>@seen byorgey
13:57:14<lambdabot>byorgey is in #haskell, #xmonad, #haskell-blah, #haskell-overflow and #haskell-in-depth. I last heard byorgey speak 19h 11m 33s ago.
13:57:34<ivanm>@ask byorgey OK, was that "strange dream" blog post of yours meant to make sense? :s
13:57:35<lambdabot>Consider it noted.
13:57:52<Peaker>you could maybe generalize a bunch of them: data MonadT t m a = MonadT { runMonadT :: m (t a) } instance MonadTrans MonadT where lift = MonadT . fmap return instance (Monad m, Monad t) => Monad (MonadT t m a) where return = MonadT . return . return ; x >>= f = ??
13:58:39<Peaker>Might need a sub-class of Monad restriction on the "t" that can do only the bind for us (we can do everything else)
13:58:45<xenoblitz>Can someone help me with this error? http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5039
13:59:06<Peaker>so defining a monad transformer would only require defining the transformer's bind. The lift and return would be the same as the monad's normal ones
13:59:52<lilac>ivanm: i assumed it was his subconscious mind reeling at the notion of a fixed-but-unspecified-precision Int ;-)
14:01:05<Peaker>xenoblitz: can you remove all irrelevant code that is not necessary to reproduce your problem?
14:01:26<xenoblitz>Peaker: yes sorry I shall
14:02:06<xenoblitz>http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5040
14:02:40<lilac>xenoblitz: your function 'simulate' is not of type 'W a -> a'
14:03:16<lilac>xenoblitz: since it's not of type 'W String -> String', for instance.
14:03:34<Peaker>simulate (W (ConstB True) :: W Int) -- boom
14:04:02<lilac>xenoblitz: you need W Int to have different constructors from W Bool if you want that sort of thing to work
14:04:11<xenoblitz>Peaker: yeah I am starting to understand better what mmorrow meant sorry... some things are still a bit hazy about phantom type
14:04:13<lilac>ACTION suggests using a GADT
14:04:24<Peaker>ACTION has never needed a GADT yet
14:04:31<xenoblitz>lilac: if you see before that there is a GADT implementation
14:04:46<xenoblitz>Peaker: see the hpaste on the same page
14:05:08<xenoblitz>I am just wondering if it is possible to achieve the simulate function using phantom types but my guess is that its not possible at all?
14:06:05<lilac>xenoblitz: well, you could say 'data W a = Const a | Not (W a) | ...'
14:06:09<xenoblitz>Peaker, lilac: http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5035 ... I am trying to see if it is possible to achieve the same effect using phantom types
14:06:22<lilac>but that'd not be a phantom type any more
14:06:35<Peaker>xenoblitz: I think maybe you want an open type sum here rather than a closed-one?
14:06:52<Peaker>xenoblitz: I think Phantom types typically go hand-in-hand with GADT's?
14:07:31<xenoblitz>Peaker: if you refering the Sum, that was added by mmorrow :P I don't know what he had in mind
14:07:42<xenoblitz>Peaker: I am told that they are orthogonal
14:07:51<lilac>xenoblitz: the trouble with not using a GADT is that non-generalized ADTs are ambivalent of the contained type in some sense
14:08:14<lilac>so if W Bool has a ConstB Bool constructor then either W Int has a ConstB Int constructor or a ConstB Bool constructor
14:08:19<lilac>and you don't want either of those possibilities
14:08:42<Peaker>xenoblitz: no, I'm referring to your use of an ADT -- when you might be better off using a type-class/function-record and an open type world
14:08:55<lilac>xenoblitz: it's possible you can do this with a type class constraint
14:09:05<Peaker>I think OO sometimes wrongfully encourages open type sums, and that ADT's sometimes wrongfully encourage closed-type-sums
14:09:21<xenoblitz>Peaker, lilac: yeah that I know... I'm experimenting with phantom types for my work
14:09:44<joeally>okay guys this is my final quicksort
14:09:46<joeally>qsort [] = []
14:09:46<joeally>qsort [x] = [x]
14:09:46<joeally>qsort (x:xs) = qsort ([z |z<-xs ,z<=x]++[x]) ++ qsort [z |z<-xs ,z>x]
14:09:50<joeally>hows that
14:09:56<lilac>xenoblitz: for what it's worth, in keeping with your design metaphor here, i'd rename Ifte to Mux and Equ to XNor...
14:10:21<lilac>joeally: do you need to include [x] in the first qsort?
14:10:34<joeally>i tried taking it out
14:10:38<joeally>but i got stack overflow
14:10:48<zachk>check it out http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5041#a5041 debrujin cycles . now is there a way to do them in like 2 lines of haskell using lambdabot? :-D
14:10:53<lilac>joeally: i mean in the third line
14:11:02<Peaker>xenoblitz: http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5034#a5042
14:11:10<joeally>oh
14:11:14<xenoblitz>Peaker, lilac: so the bottom line is that given phantom types its not really possible to obtain the function I need like I did when implementing the same function using GADTs?
14:11:19<joeally>then the pivot would be excluded
14:11:20<xenoblitz>Peaker: let me see
14:11:26<lilac>joeally: you know that x is between the first partition and the second, so you could rewrite as ... = qsort (...) ++ [x] ++ qsort (...)
14:11:39<joeally>oh yeah
14:11:39<xenoblitz>joeally: its "sorted" so you don't need to resort it
14:11:50<Peaker>xenoblitz: I think you need to prove to the compiler the relationship between the data constructor (ConstB vs ConstI) and the phantom type (Bool vs Int)
14:11:54<joeally>chears lilac
14:11:55<lilac>xenoblitz: if it's possible, i think you'd need some type class hackery and it wouldn't be pretty
14:12:02<zachk>whats a phantom type?
14:12:18<lilac>zachk: a type that doesn't appear on the RHS of the type definition
14:12:37<lilac>zachk: type ST s a = (... something not involving s ...)
14:12:58<xenoblitz>Peaker: yeah that's essentially part of the definition I used earlier using GADTs
14:13:07<xenoblitz>Peaker, lilac: thanks for your help guys
14:13:22<Peaker>xenoblitz: why do you prefer the non-GADT?
14:13:36<xenoblitz>Peaker: its not a matter of prefer... I'm comparing and constrasting :)
14:13:54<xenoblitz>Peaker: I think the GADT is really elegant as things go
14:14:11<xenoblitz>Peaker: was just wondering: can I do it with phantom types?
14:14:14<lilac>joeally: with that change made, your second line is redundant, since the third line on a one element list reduces to "qsort (x:[]) = qsort [] ++ [x] ++ qsort []"
14:14:36<joeally>oh right
14:14:40<joeally>i'll try it
14:14:44<joeally>thanks lilac
14:14:45<Peaker>xenoblitz: the GADT is not a phantom type?
14:14:53<Peaker>xenoblitz: (the type variable of the GADT, that is)
14:15:09<lilac>joeally: one other thing you might want to consider is using 'partition' instead of a list comprehension, so you only walk the list once instead of twice
14:15:15<joeally>yup
14:15:24<xenoblitz>Peaker: well yes I guess it is
14:15:24<lilac>but you've already arrived at the "canonical" "quicksort" implementation in haskell
14:15:32<joeally>i have learned about partition yet
14:15:43<joeally>yeah i just read it now
14:15:56<joeally>it uses filter instead of a list comprehension
14:16:09<joeally>it is probably a bit easier to read
14:16:37<lilac>technically it's not a quicksort implementation because the quicksort algorithm is an in-place sorting algorithm on arrays and that is not, but...
14:16:57<joeally>oh
14:17:01<Berengal>> let qsort [] = []; qsort (x:xs) = let (l,g) = partition (<=x) xs in qsort l ++ [x] ++ qsort g in qsort [1,5,4,6,8,5,5,4,3,4,5,6,8,5,34,5,6,8]
14:17:03<lambdabot> [1,3,4,4,4,5,5,5,5,5,5,6,6,6,8,8,8,34]
14:17:19<lilac>nonetheless, lots of people call that algorithm quicksort, so you're in good company ;-)
14:17:48<xenoblitz>Peaker: I guess what Cheney and Hinze say in First-Class Phantom Types as the disadvantage of common phantom types to GADTs is this very case... but I am not sure I am making false connections: "while such encodings (phantom types) guarantee that only well-formed data can be constructed, they do not permit type-safe deconstruction without additional tagging and run-time checks
14:18:15<xenoblitz>if anyone can clarify it would be awesome :)
14:20:29<lilac>xenoblitz: sounds about right. i think they're saying, via encapsulation you can enforce (by construction) that W Int does not use W Bool, but the type system can't know that, so when you pattern match, it won't tell you that the ConstB constructor implies the type is W Bool
14:20:53<lilac>actually, the type system could know that in some cases, but it in practice does not ;-)
14:22:15<xenoblitz>so very very basically, common Phantom Types allow safe construction and guided deconstruction and GADTs allow safe construction and deconstruction
14:22:46<lukeo05>So, totally got my end of first year functional programming exam in an hour. What 1 thing do you think I should know?!
14:22:54<p_l>...
14:23:25<lilac>lukeo05: whichever one thing comes up most :)
14:23:57<lilac>(sadly computing that will take too long)
14:24:11<bremner>lukeo05: tail recursion, if using a strict language
14:25:13<lukeo05>awesome. all set now! :)
14:26:56<Berengal>I'd say lists, but that might just be me...
14:28:12<bremner>tail recursion on lists!
14:28:29<pozic>fib!
14:28:33<Botje>the monomorphism restriction!
14:30:09<bremner>strictness!
14:30:36<Botje>tying the knot!
14:31:09<pozic>Why functional programming is superior to everything else!
14:31:19<tetha>catamosphisms, clearly
14:31:29<pozic>That last one is totally a real academic question.
14:31:32<lukeo05>Right... better go. Hopefully I get modules next year with haskell so I can come back here. I'd of failed without this place!
14:34:19<tetha>why do you need courses to keep learning haskell?
14:35:36<demolithion>yeah you should skip courses to learn haskell :>
14:35:49<tetha>heh
14:35:58<tetha>depending on the course, you might learn more by learning haskell
14:36:02<tetha>:>
14:36:11<demolithion>i agree :)
14:36:59<fasta>My stack traces show that certain functions call each other, except in the source code they don't. I just parse in a value at some location. This location is the only place in the code which constructs the value. Then this value gets processed using a slightly complicated recursive function, but it is not mutually recursive in the multi-level way as the stack trace shows it. Moreover, I expect the function to terminate after one go, but in fact it goes into an
14:36:59<fasta>infinite loop (which is consistent with the stack trace). The function in question does go to the "end" (it's a monadic function), when I put in error "All ok", it does reach it and it does work before it.
14:37:12<fasta>So, in short, the impossible seems to be happening.
14:37:15<pejo>Is anyone else having problems pulling from code.haskell.org?
14:37:34<quicksilver>fasta: "stack" trace?
14:37:39<quicksilver>fasta: this is haskell, after all :)
14:37:41<fasta>quicksilver: the xc output
14:38:22<quicksilver>does it show where things are forced rather than where they are lexically evaluated?
14:38:30<quicksilver>ACTION has never tried it
14:38:34<quicksilver>so I may not be much heklp/
14:39:46<fasta>quicksilver: In all the examples until now it's the latter.
14:42:07<Axman6_>anyone have any recommendations for a text editor for windows that works well with haskell, and isn't hard to use? (i'm suggesting notepad++, but i don't know of anything else)
14:42:28<Jedai>Axman6_: emacs !
14:42:35<tetha>I'd argue that learning vim or emacs is one of the better decisions you can make in your programming career
14:42:36<Jedai>Axman6_: kidding...
14:42:40<tetha>even if it takes some time
14:42:42<Axman6_>i was going to say...
14:42:58<Axman6_>tetha: considering she doesn't want to be a programmer...
14:43:15<Jedai>Well really Emacs would be my choice but I understand those that don't want to bother
14:43:30<tetha>Axman6: doesnt editing haskell code make you a programmer?
14:43:40<Axman6>basically, anything with haskell syntax highlighting would be good
14:43:59<Axman6>tetha: not when it's only a requirement for a degree
14:44:28<Jedai>Notepad++ should be perfect then, it's really nice, easy to use from the beginning and not too lame for serious programming
14:44:44<blackh>Axman6: jEdit does do Haskell syntax highlighting but not indenting and it's really easy to use
14:45:09<Axman6>ok, i'll recommend that too, thanks blackh :)
14:45:10<Jedai>Axman6: What kind of degree require you to know Haskell but isn't a CS degree ?*
14:45:18<Axman6>a science one
14:45:25<Axman6>actually, and engineering one
14:45:50<mreh>:t (>>=)
14:45:51<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
14:45:54<DarthArachides>Jedai: I studied haskell in my math degree
14:46:27<Jedai>DarthArachides: Yeah but was it a required unit ?
14:46:37<DarthArachides>Jedai: yes
14:46:54<DarthArachides>Jedai: but to be fair, our course was a bit *interesting*
14:46:58<Jedai>DarthArachides: Wow, what was your school ?
14:46:59<alexsuraci>would Template Haskell be the best route to writing a compilier from a language to Haskell?
14:47:52<mreh>can someone give me an example of a function (a -> IO b)?
14:48:04<bremner>mreh: print
14:48:07<Jedai>mreh: putStr :: String -> IO ()
14:48:13<bremner>b=()
14:48:26<fasta>mreh: undefined
14:48:35<Jedai>fasta: ...
14:48:48<bremner>:t error
14:48:49<lambdabot>forall a. [Char] -> a
14:49:10<fasta>Jedai: ...
14:49:43<DarthArachides>Jedai: I studied in India, unlikely that you have heard of the place.
14:49:57<quicksilver>DarthArachides: I have heard of India :P
14:50:00<mreh>they have computers in India?
14:50:09<bremner>mreh: readFile is more interesting example.
14:50:14<bremner>:t readFile
14:50:15<lambdabot>FilePath -> IO String
14:50:22<mreh>thanks all
14:51:09<mreh>so (>>=) can only combine actions of the same monad type?
14:51:16<mreh>:t (>>=)
14:51:17<lambdabot>forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b
14:51:18<Jedai>mreh: Right
14:51:34<mreh>uhuh
14:52:01<Jedai>mreh: it combine an action from a monad m and a fonction that results in an action in m and returns a combined action in m
14:52:07<Peaker>@hoogle Bool -> IO () -> IO ()
14:52:36<lambdabot>Control.Monad unless :: Monad m => Bool -> m () -> m ()
14:52:37<lambdabot>Control.Monad when :: Monad m => Bool -> m () -> m ()
14:52:37<lambdabot>System.Mem.Weak addFinalizer :: key -> IO () -> IO ()
14:52:40<mreh>@src (>>=)
14:52:40<lambdabot>Source not found. The more you drive -- the dumber you get.
14:53:36<mreh>when = "if ..."
14:53:39<Peaker>mreh: Monads and Applicatives support "Sequencing" of computations. Monad sequencing does 2 things -- it allows the latter function to use the result[s] of the previous function (combines values), and it sequences together the effects, left-to-right (combines the actions)
14:53:40<mreh>and unless is the oposite
14:53:58<DarthArachides>mreh: yes! and amazingly, the also have internet these days.
14:54:15<Peaker>mreh: Applicative Sequencing is pretty much the same, except the latter action does not get to see the previous action result, only to feed its result function a result argument
14:54:20<mreh>I remember all those third world jokes
14:54:26<pejo>Igloo/dcoutts, do you have the power to kick the webserver for code.haskell.org?
14:54:39<mreh>@quote monads
14:54:39<lambdabot>lispy says: "monads are like condoms, without them, it's unsafePerformSex"
14:54:44<mreh>@quote monad
14:54:44<lambdabot>Dzlk says: you can make the Id monad somewhat better behaved by wrapping it in SuperegoT.
14:54:47<quicksilver>fasta: after doing some research and having a chat with some smart people, it's probably a bug destroying or moving annotations around.
14:54:59<quicksilver>fasta: you coudl submit a bug if oyu like.
14:55:13<fasta>quicksilver: thanks a lot for saying so!
14:55:17<Jedai>mreh: Note that (>>=) is different for each monad
14:55:39<fasta>quicksilver: at the same time: "I am sure my boss would like to hear exactly that."
14:56:03<quicksilver>fasta: the xc code relies on the cost centres being correct, a bug in the way the optimiser tries to preserve the cost centres can lead to odd looking traces.
14:56:38<fasta>quicksilver: oh, so, only the stack traces are odd. The code executes correctly, still?
14:56:56<pejo>quicksilver, are the cost centres guaranteed to stay in place if optimization is turned on?
14:57:04<quicksilver>pejo: you mean, turned off?
14:57:06<fasta>quicksilver: which still means there is another problem in my code. I still have some ideas where the issue might be lurking.
14:57:19<quicksilver>fasta: I think so, yes.
14:57:28<mreh>so all this "monads are like..." is all nonsense
14:57:34<pejo>quicksilver, if you turn the optimizer off it's not going to move them around, I hope.
14:57:43<quicksilver>pejo: right.
14:57:52<quicksilver>the optimizer can duplicate code and eliminate code.
14:58:03<quicksilver>in that case, obviously care has to be taken to keep the cost centres sane.
14:58:09<pejo>quicksilver, yeah, that was kind of my idea. case-of-case transformation for example.
14:58:15<quicksilver>see, for example, http://hackage.haskell.org/trac/ghc/ticket/948
14:59:41<Jedai>mreh: The explanations of monads by comparison are most of the time correct but partial, they only works for certains monads
15:00:00<mreh>@quote Gahhh
15:00:00<lambdabot>Gahhh says: monads are usually a personal experience.
15:00:18<mreh>I believe in a personal moand
15:01:16<tetha>I figured grasping monads is like learning to throw bo-shuriken. you try to and fail everyday for a year, and then eventually it will just click and seem so damn obvious you don't know how it was unclear somewhen
15:01:16<Jedai>mreh: Generally you have two different visions of the monads, as containers or as computations, they can help understand some monads but won't give you a definitive understanding of what a monad really is
15:02:02<stroan>Jedai: do you know of any particularly good description? irregardless of accessibility
15:02:02<mreh>haha, the more you explain it, the more is sounds like Nirvana
15:02:12<mreh>or Tao
15:02:33<tetha>if you want more confusion, my bachelor thesis mentor said: monads just allow you to override function composition and do crazy things in there
15:02:59<Berengal>Monads are like cars
15:03:04<mreh>hahaha
15:03:08<mreh>here we go again
15:03:10<C-Keen>monads are like buritos
15:03:22<tetha>very nice, car analogies :)
15:03:29<mreh>i am from England
15:03:31<tetha>so I just have to restart my monad to debug it
15:03:39<mreh>the Burito is alien to me
15:04:44<mreh>so in (a -> IO b), b is the type of the container
15:05:01<mreh>but not the result of the evaluation
15:05:15<Jedai>stroan: Generally I don't believe any description is better than the dry mathematic description with the triplet of (monadtype, return, bind) and monad rules
15:05:29<quicksilver>mreh: if you want the container analogy, IO is the container.
15:05:33<quicksilver>mreh: b is the contents.
15:05:52<stroan>Jedai: Yeah, but any particularly good description of that and its uses
15:06:12<Jedai>stroan: It don't give you any appreciation for what it's useful for though, so I supplement that with "All about monads" which is nothing but a catalog of the classic monads (and a bit about monad transformers)
15:07:11<Jedai>stroan: There is nothing fancy in the mathematic description (which is why I called it dry)
15:07:26<Peaker>Looking at Reactive's implementation, I wonder why conal put a serializer with a clock
15:07:59<Jedai>stroan: A monad is just a triplet of a type and two functions traditionally called return and bind, which follows three rules
15:08:46<mreh>is do a function or syntax?
15:08:54<gnuvince>syntax
15:09:01<tetha>even though the name 'return' tends to confuse imperative programmers
15:09:17<SamB_XP_>@undo do y <- f x; print y
15:09:17<lambdabot>f x >>= \ y -> print y
15:09:47<dcoutts_>ACTION notes that Prof Knuth is currently in the office opposite
15:09:48<mreh>a >> b = a >>= \_ -> b
15:09:50<dcoutts_>why don't people tell me these things in advance?
15:09:51<Jedai>1. (return x) >>= f == f x
15:09:51<Jedai> 2. m >>= return == m
15:09:51<Jedai> 3. (m >>= f) >>= g == m >>= (\x -> f x >>= g)
15:10:00<gnuvince>tetha: I'm not sure why "return" was selected when it has such a strong meaning in most other languages.
15:10:21<Berengal>@. pl undo do y <- f x; print y
15:10:21<lambdabot>print =<< f x
15:10:22<gnuvince>I think RWH suggests that "inject" would've been a better choice.
15:10:22<bremner>ACTION finds the Real World Haskell chapter on monads to be ok for an intro
15:10:41<mreh>that book is so large
15:11:25<athos>bremner: well, IIRC it heavily depends on previous chapters
15:11:25<Jedai>stroan: Once you know that, you know everything that makes a given triplet a monad, it just remains to learn about the classic monads, try to use them and learn (experience seems to be the only way) to recognize monads in your code
15:11:27<mreh>too large in proportion to content
15:11:32<bremner>mreh: yeah, but you don't need most of the intervening chapters to read the Monad one. Just typeclasses IIRC
15:12:19<athos>bremner: IMHO it's best to read the previous parser chapters to be enlightened by the monad chapter
15:12:23<bremner>athos: I made lecture notes for 6 hours of lectures, starting with types and syntax and ending with the monad chapter
15:13:00<Berengal>Writing a parser is a great way to understand monads
15:13:07<athos>yup
15:13:08<bremner>yeah, maybe
15:13:15<stroan>Jedai: thanks. I guess it's just going to be a case of writing application and try to figure out how to do these things
15:13:21<stroan>applications*
15:13:27<Berengal>Doesn't have to be complicated, just something simple like String -> (a, String)
15:14:34<stroan>Berengal: I was thinking that actually. I'm trying to find a minimal language to implement.
15:14:51<Berengal>stroan: A minimal lisp is fine
15:15:45<stroan>A very good idea. I took a course on compiler design last year, so the parsing and interpretting won't be the stumbling block, just haskell ;)
15:16:01<Berengal>stroan: Or a very simple functional-ish language: expr = letExpr | var | val | addOp | mulOp
15:16:27<Berengal>letExpr = "let" var "=" expr "in" expr
15:17:02<Peaker>I don't like monadic parsers
15:17:17<Peaker>I don't like parsers in general, though :-0
15:17:39<SamB_XP_>ACTION mumbles something about how cute pitbulls are
15:17:41<Peaker>niche problem that became so important because of a failure to create code editors :)
15:17:43<Berengal>Peaker: I used to not like parsers in general until I learned of monadic parsing...
15:18:05<Peaker>Berengal: I think parsing should be relegated back into the niche-problem territory where it belongs :)
15:18:28<stroan>Berengal: was thinking Godel System T
15:18:30<Berengal>Peaker: Well, they're not particularly _interesting_, I'll give you that
15:18:35<Botje>parsec makes parsing FUN(ctional) again
15:18:46<SamB_XP_>Botje: eh ...
15:18:51<SamB_XP_>it's kinda lousy!
15:18:59<Peaker>Hmm... type b :--> a = (Sink b, a) And Sink b = b -> IO () -- that's a weird type
15:19:19<SamB_XP_>you have to jump through hoops to keep it from going down the wrong alternative!
15:19:20<Peaker>the doc says: -- | An @a@ that's fed by a @b@ -- but it seems the a is not "fed" by anything
15:20:14<Botje>SamB_XP_: didn't notice much of it :)
15:20:34<Baughn>reactive? b would be an aaction to add an event occurence at the current time; a's the event.. yes?
15:21:05<SamB_XP_>ewww IO
15:21:20<Badger>ACTION inputs SamB_XP
15:21:23<Baughn>SamB_XP: It's LegacyAdapters. The module is specifically to interact with IO. ;)
15:21:31<Badger>ACTION outputs spaghetti
15:21:33<Baughn>*exists specifically to
15:21:40<SamB_XP>Baughn: oh
15:22:00<Baughn>I can't make it work, though
15:22:06<SamB_XP>sounds like it needs better docs
15:22:16<Baughn>First it needs to /work/
15:22:20<fasta>In foo = do undefined; let !a = trace "hi" ();undefined, why is "hi" being printed?
15:22:40<Baughn>There are ghc bugs (possibly), and reactor bugs (probably) preventing me from using this, and conal is a poor starving ex-student
15:22:47<Baughn>Someone should hire him to work on FRP
15:32:28<Jedai>fasta: That depends on the monad (on (>>=) strictness more precisely)
15:32:44<Peaker>Baughn: ex-MS-research guy, too
15:32:56<Peaker>Baughn: I'm reading Reactive's code to see what breaks your example
15:33:20<Peaker>Baughn: its built very elegantly in a layered manner, but that has the disadvantage that you actually have to understand many layers to understand just the part you want..
15:34:27<Baughn>Peaker: I noticed. :/
15:34:31<Baughn>Peaker: Currently doing the same thing
15:35:33<Baughn>Peaker: And, of course, chances are very good it's a ghc issue - given how it behaves differently under -threaded
15:35:45<Baughn>Peaker: I tried running it under GHC head, though. No difference.
15:36:00<Peaker>Baughn: btw, do you understand the code of race?
15:36:12<Baughn>Peaker: Oh, sure. Clever, but it's the simplest part.
15:36:29<Peaker>I don't understand the part that supposedly does this: "Importantly, it also sets itself up to be retried if the unamb value is accessed again after its computation is aborted."
15:36:44<Peaker>Baughn: I don't see how "myThreadId >>= killThread" could do anything desirable
15:36:59<Baughn>Peaker: myThreadId >>= killThread kills the current thread, obviously
15:37:11<Peaker>Baughn: look at the code in Unamb.hs/race
15:37:17<Baughn>I have
15:37:21<Baughn>Peaker: But it's an async. exception, so the kill doesn't go through until unblock is called
15:37:22<Peaker>Baughn: After that, it does: unblock (race a b)
15:37:51<Peaker>Baughn: I tested myThreadId >>= killThread and it seems it just hangs
15:37:56<Peaker>Baughn: (when you're blocked)
15:38:02<kyevan>Mmm.
15:38:08<Baughn>Peaker: You need to actually unblock it
15:38:09<Peaker>Baughn: OR it does kill the thread, which I guess that denotationally is equivalent
15:38:23<kyevan>One thing to be said for haskell, I think "map (\x -> chr ((ord x) `xor` 0xFF))" is the shorted mangle/demangle I've ever written :J
15:38:35<Peaker>Baughn: only a thread can unblock itself -- so block $ myThreadId >>= killThread -- is a deadlock because killThread waits
15:39:06<Peaker>@pl (\x -> chr ((ord x) `xor` 0xFF))
15:39:06<lambdabot>chr . (`xor` 255) . ord
15:39:20<Baughn>Peaker: Oh, right you are..
15:39:23<Peaker>chr . xor 255 . org will also work (xor is commutative)
15:39:27<Baughn>That's funny
15:39:52<Peaker>Baughn: so that puzzled me for a while -- but also, even if it did send an async exception - it would die immediately afterwards in the unblock, wouldn't it?
15:40:09<Peaker>kyevan: map (chr . xor whatever . ord)
15:40:25<Baughn>Peaker: Hang on, I need to do a few tests
15:40:51<Peaker>Baughn: Also, how would it accomplish:L "Importantly, it also sets itself up to be retried if the unamb value is accessed again after its computation is aborted."
15:41:14<kyevan>Hehe, I wrote this while being bounced around on a highway, give me some slack :P
15:41:28<Peaker>does takeMVar have an implicit unblock in it?
15:42:36<Baughn>Peaker: You really should ask conal about this. You're right that it's odd, but I'm just as befuddled as you
15:42:54<Baughn>Peaker: And I hadn't quite figured out the definition of unamb either. ;)
15:44:10<Peaker>Baughn: Assuming race works - I understand unamb
15:44:47<Peaker>Baughn: amb and unamb are equivalent, except unamb can unsafePerformIO on amb because its guaranteed that the actions have denotationally equivalent results
15:45:02<Baughn>Peaker: Mind you, a quick print shows that neither unamb nor (obviously) race are actually used in my troublemaker
15:46:11<Peaker>Baughn: yep, I think they're only used when multiplexing events
15:46:32<Peaker>ghc needs a proper debugger!
15:47:09<Baughn>Peaker: But.. okay. When race kills itself (never mind that that /fails/, deadlocking instead), it sets up a new invocation of race to be executed after the thread dies
15:47:36<Peaker>Baughn: I don't get that -- even if it didn't deadlock, it'd die in the unblock before it had a chance to do anything
15:47:43<Baughn>Peaker: When using unsafePerformIO to execute an action, killing one thread that's executing it does not necessarily mean the action's execution will never continue
15:50:41<Peaker>Baughn: it seems like takeMVar does an implicit unblock
15:50:46<Peaker>Baughn: that usleep, for example, doesn't
15:51:03<Peaker>oh wait, maybe usleep and the likes are not allowed in forkIO?
15:52:22<Baughn>They should be
15:52:46<Baughn>Mind you, using usleep instead of threadDelay is a bad idea, but.. still.
15:52:49<Peaker>hmm.. it appears that all "blocking" operations unblock?
15:52:58<TomMD>FWIW, my tests on takeMVar make me think its unblocking as well.
15:52:59<Peaker>blocking as in waiting, unblock as in Control.Exception.unblock
15:53:16<Peaker>threadDelay too seems like it unblocks
15:53:34<Peaker>I guess the idea is to force block sections to be atomic and avoid deadlocks
15:53:47<Peaker>but I don't think I saw this in the documentation
15:54:06<Peaker>Baughn: anyway, since its not in your thingie, I'll try to sprinkle prints over reactive instead
15:54:25<Baughn>Peaker: You do that. I'll.. do that too.
15:54:51<fasta>For a language designed for concurrency, having to guess the semantics of MVars is not a good thing.
15:55:03<Peaker>can darcs tell me if I have local unpushed changes easily?
15:55:09<Baughn>darcs whatsnew
15:55:14<Baughn>Or.. no
15:55:27<Baughn>Well, darcs send/push will prompt you
15:55:32<Peaker>fasta: I think its the semantics of block/unblock in general.. Everything that blocks execution unblocks exceptions, iiuc
15:56:02<Baughn>fasta: You're not really supposed to use block/unblock in application-level code, either
15:56:40<fasta>Baughn: I was referring to the exported public MVars API.
15:56:46<Peaker>Baughn: if you use forkIO in your application code, you're likely to need block/unblock too
15:57:05<fasta>Baughn: at least over a year ago it was impossible to figure out what it does, unless you experiment with it.
15:57:24<Baughn>Peaker: I've never had to, but I don't throw exceptions willy-nilly either
15:57:26<Peaker>fasta: at least experimenting is easy :)
15:57:36<Peaker>even killThread throws though
15:57:54<Baughn>Right, but then that's what finally/onError/bracket are for
15:59:31<quicksilver>I think the mvar semantics is pretty clear, excluding asynchronous exceptions.
15:59:42<quicksilver>I don't really use asynch exceptions so they don't really bother me often.
15:59:51<quicksilver>but definitely, they make everything gnarly.
16:00:20<fasta>Can any tool show why a certain function gets called more than once?
16:01:20<quicksilver>fasta: the profile will show you where it's called from most often
16:02:38<Peaker>Baughn: runE is not even calling runR
16:03:24<Baughn>Peaker: Yep. Do you happen to know where the Functor instance for Event is?
16:04:00<Peaker>Baughn: PrimReactive.hs:187
16:05:38<fasta>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/visual-graphrewrite looks interesting, and it even compiles, but how should one use it?
16:08:07<doserj>fasta: doesn't look finished: http://github.com/zsol/visual-graphrewrite/blob/c2047c227b6ccee1bf05b2a66c007e21c1bf3fd5/README
16:10:22<teolicy>Hi. What's the difference between an Array and a List?
16:10:40<kpreid>lots
16:10:47<kpreid>why do you ask?
16:11:03<kpreid>if you give some context I can perhaps tell you the relevant difference
16:11:16<kpreid>(assuming by List you mean [])
16:11:37<Peaker>Baughn: the thread block is in the forcing of the bt argument in runE, brb
16:12:44<fasta>quicksilver: I don't get a profile, because the program does not terminate and I do C-c C-c
16:13:52<frwmanners>fasta: ghci breakpoints help?
16:13:57<Peaker>fasta: windows?
16:14:12<fasta>Peaker: no, Linux.
16:14:31<fasta>frwmanners: usually the debugger does not help
16:14:47<frwmanners>true
16:14:55<Peaker>Baughn: oh, you're using the joinE
16:14:56<fasta>The debugger extensions written by Peter <???> seem quite nice, though.
16:16:14<Peaker>Baughn: If you avoid using the Monad instance of event then that resolves one problem
16:16:21<quicksilver>fasta: ah, and you dont' know how to make the program terminate because you don't know where it is getting stuck?
16:16:22<Peaker>Baughn: I think the Monad instance of events is knowingly broken
16:16:31<fasta>quicksilver: right
16:16:58<fasta>quicksilver: well, I can make it terminate after a gazillion iterations with unsafeperformio
16:17:09<quicksilver>fasta: it's a dirty hack, but how about running your program in a separate thread
16:17:25<quicksilver>and have the main thread just exit cleanly after a fixed time
16:17:30<quicksilver>that should get you a profile I believe.
16:17:35<Baughn>Peaker: I did get that feeling. Meanwhile, my other (more problematic) testcase does use race, so let me see..
16:17:48<fasta>quicksilver: I will try tomorrow. Thanks
16:18:31<Peaker>Baughn: well, your (>>=return) thing proves that event's monad instance is broken -- but that's ok, because it's not that useful
16:19:41<Baughn>Peaker: More, it proves that joinE is broken
16:21:17<frwmanners>Baughn: if you're playing with reactive, what structure of Time are you using?
16:22:12<quicksilver>Baughn: "broken" in what case?
16:22:31<quicksilver>Baughn: anything worse than non-determinism for simultaneous events?
16:22:45<quicksilver>because I don't care what order simultaneous events arrive in, mostly.
16:22:49<quicksilver>but anything worse than that, would be bad.
16:23:28<Baughn>frwmanners: TimeT
16:23:51<Baughn>quicksilver: It causes GHC to detect nonexistent deadlocks under the threaded runtime
16:24:03<Baughn>quicksilver: Or, in 6.10.2, just all the time
16:24:11<Baughn>quicksilver: Using +RTS -I0 "cures" it.
16:24:15<Baughn>I'd say it's bad.
16:24:28<Baughn>quicksilver: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5018 <-- Oh, and testcase
16:25:04<quicksilver>surely that's got to be a compiler/RTS bug
16:25:06<quicksilver>not a joinE bug
16:25:26<Baughn>quicksilver: It's hard to tell, considering how reactive is implemented
16:25:39<Baughn>quicksilver: I don't believe unsafePerformIO has semantics that can be considered buggy
16:25:55<Twey>U.
16:25:55<leimy>I'm a little confused by how a pure function like (unlines . lines) can force I/O to be sequenced linewise with interact.
16:26:15<leimy>I thought the only way to really sequence I/O was via the imperative "bindy" stuff inside the I/O monad.
16:26:17<Twey>leimy: Because it's lazy
16:26:49<Twey>It's not sequenced for sure, but every time you read an item from the list, you have to have read a corresponding line of input
16:27:08<leimy>hmmm
16:27:10<Twey>In current implementations, that means that it reads a line at a time
16:27:26<leimy>meaning I should not rely on the fact that that reads a line, and then joins that line back in with other lines...
16:27:38<Trowalts>I have a function that works but is teribly ineficient, I know what should be done to simplify it, but have no idea how to write it in haskell
16:28:15<Twey>leimy: Input doesn't really work like that, though it may seem to in a shell
16:28:22<Twey>Input and output are separate streams
16:28:38<leimy>well "interact" ties them to input and output streams
16:28:39<leimy>so
16:28:55<Trowalts>the function is, hasFactor p = take 1 [z | z <- [2..p-1], p `mod` z == 0] but it doesent have to go all the way to [2..p-1], it only needs to go until [2.. while z^2 < p]
16:28:57<leimy>interact (unlines . lines) -- basically an echo command
16:29:19<inimino>...both of which may be buffered
16:29:45<leimy>Well I guess it's that way with line buffering.
16:29:49<Peaker>leimy: lazy I/O indeed makes evaluation invisibly sequence IO actions -- but its considered "bending" rather than breaking the rules, because you're not supposed to be able to tell the difference between hGetContents getting the entire file now and it doing the getting line-by-line per evaluation
16:29:53<Trowalts>well thats how I'm trying to express what I need..
16:29:54<inimino>@type interact
16:29:55<lambdabot>(String -> String) -> IO ()
16:30:26<leimy>@src interact
16:30:26<lambdabot>interact f = do s <- getContents; putStr (f s)
16:31:18<leimy>So I guess my concern is, can I do things with interact that seem to force linewise input and expect it to work "portably" or reliably in future GHC releases? :-)
16:31:21<leimy>it sounds like "probably not"
16:31:22<Peaker>@. pl undo do s <- getContents; putStr (f s)
16:31:22<lambdabot>putStr . f =<< getContents
16:32:05<Trowalts>ie, I need to put a condition onto the range of [2..] so the list comprehension will brake, anyway this can be done
16:33:08<joeally>what does this mean
16:33:09<joeally>Couldn't match expected type `[a]'
16:33:09<joeally> against inferred type `[a1] -> [a1]'
16:34:01<leimy>it means that you're providing a function where it's expecting a list
16:34:26<MyCatVerbs>Trowalts: what condition? hpaste your code please?
16:34:31<Trowalts>kk
16:34:35<MyCatVerbs>@where hpaste
16:34:35<lambdabot>http://hpaste.org/
16:37:25<Trowalts>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5043#a5043
16:38:00<Trowalts>with ranfe-> range and why -> way, sorry about that
16:40:56<Trowalts>basicly I dont need to do the check for factors of p ( p `mod` z ) if z^2 is greater than p (cos then its imposible to find a factor in anycase)
16:41:03<doserj>z <- [2..isqrt p], where isqrt computes the integer square root, or z <- takeWhile (\n->n^2<p) [2..p].
16:41:16<Jedai>Trowalts: [ f | f <- takeWhile (\f -> f^2 < n) [2..], n `mod` f == 0 ]
16:41:22<joeally>cheers leimy
16:42:01<Jedai>Trowalts: besides I suggest to remove the take 1 from your function
16:42:30<lilac>Trowalts: i'd use '2:takeWhile (\n -> n^2 <= p) [3,5..]'
16:43:04<lilac>doserj's and Jedai's formulations will both say that the square of a prime is prime ;-)
16:43:29<Jedai>Trowalts: lazyness will ensure that no more than one factor will ever be calculated if you just test if the result is empty
16:43:34<Jedai>lilac: Ooops
16:43:37<lilac>:-D
16:44:19<doserj>lilac: the isqrt one will work, though
16:44:20<Trowalts>Jedai, lilac: alrighty then, thanks
16:44:23<lilac>or even 'takeWhile (\n -> n^2 <= p) (2:[3,4..])'
16:44:39<lilac>doserj: fair point ;-)
16:46:25<Jedai>> let hasFactor :: Int -> Bool; hasFactor n = not . null $ [ f | f <- takeWhile ((<= n) . (^2)) (2:[3,5..]), n `mod` f == 0] in hasFactor 11
16:46:26<lambdabot> False
16:49:13<Twey>> let hasFactor n = not . null . filter ((== 0) . (n `mod`)) . takeWhile ((<= n) . (^2)) $ 2 : [3, 5..] in hasFactor 11
16:49:14<lambdabot> False
16:51:16<Jedai>@hoogle (a -> Bool) -> [a] -> Bool
16:51:17<Jedai>> let hasFactor n = any ((== 0) . (n `mod`)) . takeWhile ((<= n) . (^2)) $ 2 : [3, 5..] in hasFactor 11
16:51:17<lambdabot>Prelude all :: (a -> Bool) -> [a] -> Bool
16:51:17<lambdabot>Prelude any :: (a -> Bool) -> [a] -> Bool
16:51:17<lambdabot>Data.List all :: (a -> Bool) -> [a] -> Bool
16:51:18<lambdabot> False
16:51:35<Jedai>> let hasFactor n = any ((== 0) . (n `mod`)) . takeWhile ((<= n) . (^2)) $ 2 : [3, 5..] in hasFactor 25
16:51:37<lambdabot> True
16:52:59<SamB>ACTION wonders what the heck "the git potty" is
16:55:48<mreh>Graphics/HGL/Key.hs:57:7:
16:55:48<mreh> Could not find module `Graphics.Win32':
16:55:48<mreh> it is a member of package Win32-2.1.1.1, which is hidden
16:55:48<mreh>cabal: Error: some packages failed to install:
16:55:48<mreh>HGL-3.2.0.0 failed during the building phase. The exception was:
16:55:49<mreh>exit: ExitFailure 1
16:56:10<dcoutts_>mreh: you asked that Q already :-)
16:56:21<mreh>yeah, i forgot the answer
16:56:33<mreh>add Graphics.Win32 to the dependancy list?
16:56:38<dcoutts_>the answer was: don't use HGL, use something that works and is maintained
16:57:02<mreh>unacceptable answer
16:57:09<FunctorSalad>how about adding "If you got this error message while trying to compile a cabal package, you might have to add the package to the build-depends field"?
16:57:19<FunctorSalad>adding it to the error message
16:57:32<dcoutts_>mreh: if you were crazy enough to want to try and fix HGL then you'd start by editing the .cabal file to list Win32 as a build dependency
16:58:04<mreh>thanks
16:58:13<dcoutts_>however the problems will quickly become harder, threading nightmares etc
16:58:23<FunctorSalad>:o
16:59:03<mreh>I'm making a game of asteroids
16:59:13<mreh>i dont see that really occuring
16:59:54<dcoutts_>mreh: I don't mean in the code you write, but in the guts of HGL. Some clever people have looked at it to try and fix it, and not been able to.
17:00:04<mreh>your advice is noted, you can say "I tol dyou so later"
17:00:39<dcoutts_>I don't want to gloat :-) I'd prefer to save your frustration by giving you good advice
17:01:17<mreh>getting more errors now
17:01:32<mreh>Graphics/HGL/Key.hs:57:7:
17:01:32<mreh> Could not find module `Graphics.Win32':
17:01:32<mreh> it is a member of package Win32-2.1.1.1, which is hidden