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
17:01:32<mreh>cabal: Error: some packages failed to install:
17:01:32<mreh>HGL-3.2.0.0 failed during the building phase. The exception was:
17:01:33<mux>so far, everything seems to happen as dcoutts_ predicted then :-P
17:01:33<mreh>exit: ExitFailure 1
17:01:37<mreh>wrong
17:01:38<mreh>hang on
17:02:18<mux>ACTION should upload the newest version of his System.BSD.Sysctl module that can handle sysctl "procedures" to hackage
17:02:35<mreh>Graphics/HGL/Internals/Types.hs:25:0:
17:02:35<mreh> Bad interface file: C:/ghc/ghc-6.8.3/lib\base-3.0.2.0/Data/Ix.hi
17:02:35<mreh> magic number mismatch: old/corrupt interface file?
17:02:38<lpjhjdh>for parsing is happy de facto? I wrote something quick with readp but adding error tracking is annoying.
17:03:00<mreh>Haskell interfaces?
17:03:00<mux>lpjhjdh: many of us use parser combinators libraries such as parsec or polyparse
17:03:08<mux>mreh: the .hi files
17:03:35<mreh>is that like a C header file?
17:03:46<lpjhjdh>hmm, haven't tried polyparse, parsec always seemed overarchitected compared to readp to me
17:04:03<dcoutts_>mux: for reference: http://hackage.haskell.org/trac/ghc/ticket/742
17:04:05<lpjhjdh>of course now I'm complaining about adding error tracking with readp :p
17:04:25<mreh>hehe, stop it dcoutts_!
17:04:25<mux>dcoutts_: I think you meant to send that to mreh
17:04:26<dcoutts_>lpjhjdh: right, readp has 0 in the way of parser error handling, you just get [] :-)
17:04:40<mreh>mux: he's advising you stay out of it
17:04:54<mux>I _am_ going to stay out of it for sure :-)
17:04:55<Saizan>uu-parsinglib is nice too, aside from the fact they define their own Applicative
17:05:03<dcoutts_>mux: I don't think mreh wants to hear the bad news :-)
17:05:09<mux>heh.
17:05:29<mux>dcoutts_: are you running OpenBSD?
17:05:37<dcoutts_>mux: gentoo
17:05:43<mux>damn.
17:06:03<dcoutts_>though I recently got kvm working, so should be able to run any of the BSDs easily
17:06:08<lpjhjdh>hmm, what would you all suggest then for a simple parser with error handling?
17:06:25<mux>both NetBSD and OpenBSD (latest versions) fail to run with qemu 0.10.4 (latest version)
17:06:35<mux>and this happens _just_ when I need to test stuff on those OSes
17:06:45<dcoutts_>mux: gah
17:06:47<dcoutts_>lpjhjdh: parsec or polyparse
17:07:12<lpjhjdh>dcoutts_: thanks
17:08:17<dcoutts_>mux: we need a haskell.org build farm with half a dozen different OSs
17:08:38<mux>dcoutts_: that would be great, though in my case I'd need to do some runtime tests as well
17:08:50<dcoutts_>mux: eg, upload to a test-only hackage and have bots test on different platforms
17:09:10<mux>if the bots can run the test suite then I guess it'd be fine
17:09:14<dcoutts_>mux: yes, we also need to upgrade cabal test
17:09:26<mux>although I would have to write different tests suites for some OSes
17:11:22<mux>dcoutts_: btw, the latest versions of cabal-install are truly great
17:11:27<mux>can't live without it!
17:11:32<dcoutts_>:-)
17:11:39<dcoutts_>ACTION wishes he had more time to hack on it
17:11:51<mux>if only to be able to type "cabal {configure|build|install}"
17:12:03<mux>but of course installing packages from hackage is cool too
17:12:17<dcoutts_>mux: do you use the bash command completion btw?
17:12:22<lpjhjdh>dcoutts_: so with polyparse will I need to write basic stuff to track position?
17:12:26<mux>dcoutts_: nope, I use zsh
17:12:49<dcoutts_>mux: oh, someone should port it, should be trivial since most of it is done by the cabal program itself
17:12:57<mux>dcoutts_: yup
17:13:07<dcoutts_>lpjhjdh: I'm not sure actually, check the docs
17:13:24<mux>I've had problems with PP exporting much less stuff than it should
17:13:34<mux>I found tons of useful unexported functions in the sources
17:13:49<mux>err, wait
17:13:59<mux>sorry I was thinking of HaXml actually
17:14:05<marcot>http://www.cs.york.ac.uk/fp/darcs/hscolour/hscolour.cabal
17:14:14<marcot>Should this .cabal file have a Library field?
17:14:27<mux>that and HaXml redefines maybe primitive parses already provided by PP
17:14:32<mux>s/maybe/many/
17:14:43<dcoutts_>marcot: it's an old style .cabal file, pre-Cabal-1.2, it still works
17:15:14<marcot>dcoutts_: Ok, thanks. It's not working with the Debian infra-structure. I'll check why latter.
17:16:36<mux>this is a bit surprising since both PP and HaXml are maintained by the same guy
17:17:08<mux>I guess since PP was extracted from HaXml, he didn't have time to clean it up
17:19:40<amgarching>hi, is there a primitive to split a list in two by a binary property?
17:20:23<mux>amgarching: span
17:20:29<skorpan>@src partition
17:20:29<lambdabot>partition p xs = foldr (select p) ([],[]) xs
17:20:30<lambdabot> where select p x ~(ts,fs) | p x = (x:ts,fs)
17:20:30<lambdabot> | otherwise = (ts, x:fs)
17:20:33<skorpan>:t partition
17:20:34<lambdabot>forall a. (a -> Bool) -> [a] -> ([a], [a])
17:20:47<mux>oh, I may have understood what you want the wrong way
17:20:58<mux>partition is the way to go in that case
17:21:12<skorpan>could be either one really
17:21:58<amgarching>skorpan: where is it? <interactive>:1:0: Not in scope: `partition'
17:22:04<skorpan>amgarching: Data.List
17:22:07<mux>@index partition
17:22:07<lambdabot>Data.IntMap, Data.IntSet, Data.List, Data.Map, Data.Set
17:22:31<skorpan>amgarching: hoogle is great for these kinds of questions
17:22:45<skorpan>@hoogle (a -> Bool) -> [a] -> ([a], [a])
17:22:45<lambdabot>Prelude break :: (a -> Bool) -> [a] -> ([a], [a])
17:22:45<lambdabot>Prelude span :: (a -> Bool) -> [a] -> ([a], [a])
17:22:45<lambdabot>Data.List break :: (a -> Bool) -> [a] -> ([a], [a])
17:23:57<joeally>how do i get this function to return a floating point number
17:23:59<joeally>variance x = div (sum (map (^2) x)) (length x)
17:24:08<joeally>its an incomplete variance function
17:25:01<mux>you want a floating point in the end even though you use integer division in your function?
17:25:22<mux>by the way, div is best used infix imho
17:25:28<joeally>okay#
17:25:40<joeally>but it gives an error if i use the infix one
17:25:49<mux>show us how you lrite it
17:25:59<joeally>okay
17:26:38<joeally>i get this when i use infix No instance for (Fractional Int)
17:26:38<joeally> arising from a use of `/' at funcs.hs:25:14-44
17:26:38<joeally> Possible fix: add an instance declaration for (Fractional Int)
17:26:38<joeally> In the expression: (sum (map ((^ 2)) x)) / (length x)
17:26:38<joeally> In the definition of `variance':
17:26:39<joeally> variance x = (sum (map ((^ 2)) x)) / (length x)
17:26:51<mux>is not the infix version of div
17:26:54<mux>err
17:26:59<mux> / is not the infix version of div
17:27:03<joeally>okay you mean x 'div' y
17:27:06<mux>`div` is
17:27:17<mux>div is integer division, (/) is FP division
17:27:42<mux>which one do you actually want? :-)
17:27:56<Zao>Not to forget quot :)
17:28:01<mux>heh.
17:28:11<joeally>i want one that will give me a a float
17:28:23<joeally>for example in the mean of [1,2,3] is 2
17:28:24<mux>then you want (/), but for that you need to supply it the correct types
17:28:28<mux>:t (/)
17:28:30<lambdabot>forall a. (Fractional a) => a -> a -> a
17:28:33<joeally>and the mean of [1,2] is 1.5
17:28:40<mux>this means both numbers have to be in the Fractional class
17:28:52<joeally>oh right
17:29:10<mux>so you really want fromIntegral (sum (map (^2) x)) / (fromIntegral (length x))
17:29:12<joeally>I'm reallly new to haskell
17:29:17<joeally>okay
17:29:21<joeally>thanks
17:29:22<mux>yeah, don't worry, we've all been through that
17:29:40<mux>next you'll discover haskell also has 3 different exponentiation operators :-)
17:29:57<joeally>i'm looking forward to tha
17:29:59<joeally>why
17:30:06<joeally>^ has worked fine for me
17:30:11<mux>:t (^)
17:30:12<lambdabot>forall a b. (Integral b, Num a) => a -> b -> a
17:30:14<mux>:t (**)
17:30:16<lambdabot>forall a. (Floating a) => a -> a -> a
17:30:19<mux>:t (^^)
17:30:19<joeally>okay
17:30:20<lambdabot>forall a b. (Integral b, Fractional a) => a -> b -> a
17:30:23<joeally>thanks lamdabot
17:30:25<mux>see? :-)
17:31:11<joeally>yes i do
17:31:17<joeally>one is for floating point
17:31:26<joeally>one is for intergers
17:31:34<mux>> 4 ** -1
17:31:35<lambdabot> precedence parsing error
17:31:35<lambdabot> cannot mix `(**)' [infixr 8] and pref...
17:31:36<joeally>its because it is statically typed
17:31:41<mux>> 4 ** (-1)
17:31:42<lambdabot> 0.25
17:31:46<mux>> 4 ** (-1.5)
17:31:48<lambdabot> 0.125
17:32:10<mux>joeally: this is because these functions have a different behaviour
17:32:23<joeally>oh
17:32:32<mux>static typing doesn't prevent any kind of polymorphism
17:32:44<mux>if there was really no use in providing 3 functions, haskell would only provide one
17:36:13<lilac>has anyone written a numeric prelude which provides the same style of interface as dynamic languages tend to?
17:36:55<lilac>(something like 'class Div a b where (/) :: a -> b -> Double' with instances for various pairs of numeric types)
17:38:01<lilac>maybe 'class Div a b c | a b -> c where ...' would be closer to what you get in, say, python
17:38:01<joeally>whats that for
17:40:34<mux>ACTION cabal sdist :-)
17:45:28<mux>ACTION wonders what would happen if he uploaded a package on hackage with a weird category... such as html code :-P
17:45:57<joeally>go on mux
17:45:59<joeally>do it
17:46:41<mux>no, I already uploaded my package and even though I'm curious about it I don't want to do any harm on the site :-)
17:46:51<joeally>oh
17:47:18<lilac>can someone with an account cabal upload something for me?
17:47:37<mux>though <span style="color: red; font-weight: bold">SomeCategory</span> would be funny.
17:47:39<joeally>mux how would I use a list comprehension to multiply to elements from 2 coresponding lists
17:47:40<dcoutts_>lilac: you mean hackage? you can ask for an account
17:47:50<joeally>ooh mux inline csss
17:47:54<joeally>css*
17:47:58<joeally>thats is not good
17:47:58<lilac>ACTION asks for an account :)
17:48:15<joeally>sorry lilac
17:48:16<mux>ACTION waves and leaves
17:48:22<joeally>bye
17:48:36<dcoutts_>mux: I expect that since it's using the html lib, that all strings are escaped
17:49:24<lilac>does ross@soi.city.ac.uk IRC?
17:50:52<lilac>what safeguards does hackage have to prevent some unscrupulous user from uploading a malicious version of a package?
17:51:13<Elly>I would guess "none"
17:51:52<SamB>lilac: well, you need to go through a human to get an account these days, don't you?
17:52:01<joeally>is there anyway to form a new list by multiplying corresponding elements of two lists using map or a list comprehension
17:52:14<SamB>so ... the threat of account suspension and shunnage ...
17:52:39<otto_s_>> zipWith (*) [1,2..] [10,20,30]
17:52:41<lambdabot> [10,40,90]
17:52:59<joeally>cheers otto
17:53:18<lilac>SamB: sure, but at the cost of account suspension etc., one could probably quite easily own a lot of machines by uploading an evil version of some library
17:53:30<lilac>i suspect this could only happen the once, but still, it concerns me
17:53:30<Berengal>joeally: There's also a parallell list-comprehension expension
17:53:39<joeally>oh
17:53:42<joeally>how do i do that
17:53:46<Elly>if you DNS poisoned you could get people to download arbitrary code too, since cabal doesn't check
17:53:55<Berengal>> [a*b | a <- [1..10] | b <- [1..10]]
17:53:56<lambdabot> [1,4,9,16,25,36,49,64,81,100]
17:54:04<joeally>thanks
17:54:07<Berengal>You need to enable the expension though
17:54:13<SamB>Elly: you think the hackage server should have a GPG key ?
17:54:18<Berengal>Bleh, extension
17:54:26<joeally>i think zipWith is a bit more elegant thougt
17:54:31<joeally>but thanks
17:54:34<SamB>or HTTPS or ... ?
17:54:53<Berengal>joeally: Yeah, zipWith would be my choice as well. I'm just saying it's there :)
17:54:55<lilac>SamB: it's not the hackage server that's the problem, it's trusting the content on the server
17:55:12<lilac>a faked server with trusted content would arguably be fine to isntall from :)
17:55:13<Berengal>> [(a,b,c) | a <- [1,2], b <- [3,4] | c <- [5,6]]
17:55:14<lambdabot> [(1,3,5),(1,4,6)]
17:55:15<jbjohns>I read on an internet site about command line parameters, defaults and so on just being monoids. Any implementations of this I could look at? I'm having a hard time visualizing exactly how this would work
17:55:20<joeally>yeah thanks thats the way i would have originally doen it had someone not told me of zipwith
17:55:57<SamB>lilac: I meant to prevent the DNS poisoning stuff
17:55:59<Berengal>joeally: Oh, and there's also ZipLists
17:56:03<dcoutts_>SamB, Elly, lilac: I'd advocate a lightweight system where users can only upload specific packages (to stop subverting well-known names) and the packages should be checked against a hackage key so you know they've not been modified since they were uploaded.
17:56:18<lilac>SamB: my point was, DNS poisoning is irrelevant if you trust the content, and you're hosed anyway if not
17:56:24<joeally>oh
17:56:26<joeally>okay
17:56:34<Berengal>> getZipList $ (*) <$> ZipList [1..10] <*> ZipList [1..10]
17:56:36<lambdabot> [1,4,9,16,25,36,49,64,81,100]
17:56:37<dcoutts_>but not a system where each author has to sign packages and all clients check, that's too much to manage
17:56:40<SamB>lilac: and the GPG thing I was thinking of wouldn't prevent illegitimate servers serving the legitimate content
17:56:52<dcoutts_>SamB: which isn't a problem
17:57:03<SamB>dcoutts: I know!
17:57:15<SamB>who cares if the server was a fake if it gave you the right data, eh?
17:57:22<dcoutts_>SamB: well, except that it lets illegitimate serve old versions which may have known exploits
17:57:29<SamB>dcoutts: well, okay ...
17:57:45<jbjohns>dcoutts: Actually, was it you that said that about command line args = monoids?
17:57:48<SamB>but that's a heck of a lot better than a trojan, no?
17:57:51<dcoutts_>SamB: that's more of a problem for distros with lots of network facing packages
17:58:03<dcoutts_>jbjohns: yes
17:58:51<SamB>anyway ... I was thinking that the hackage client would have grabbed the GPG key upon being configured to access the server ...
17:59:03<dcoutts_>jbjohns: http://www.haskell.org/pipermail/cabal-devel/2007-December/001509.html and it's now implemented in Cabal
17:59:10<jbjohns>dcoutts: cool, any examples you could point me too? It seems to me the cleanest way to implement the defaulting+overriding behavior would be to use a Dictionary
17:59:10<lilac>jbjohns: if you think of such things as a mapping of keys to values, those form a monoid where the empty mapping is zero and map union (preferring the RHS if the same key is in both maps) is plus
17:59:11<SamB>and would check each package for a signature, and ensure that it was signed by that key
17:59:28<lilac>jbjohns: if you think about it, that's how command-line arguments work too
17:59:31<jbjohns>thanks guys
17:59:49<SamB>or possibly a designated successor key
18:00:02<SamB>(duly signed by the original, of course)
18:00:07<dcoutts_>SamB: checking the package index is sufficient if the index contains hashes of the package tar.gz files
18:01:29<skorpan>could someone remind me about the haskell definition of `split', i.e. 'split " " "hello there" = ["hello", "there"]'?
18:01:41<skorpan>hm, actually words will do
18:01:52<Berengal>@src words
18:01:52<lambdabot>words s = case dropWhile isSpace s of
18:01:52<lambdabot> "" -> []
18:01:52<lambdabot> s' -> w : words s'' where (w, s'') = break isSpace s'
18:02:06<skorpan>yep, so i could easily generalise that
18:02:27<Berengal>If you wanted
18:02:43<Berengal>Hmm, is there such a thing as groupBy?
18:02:47<Cale>But, there's a nice library of string splitting functions on Hackage
18:02:47<skorpan>yes
18:02:53<skorpan>@src groupBy
18:02:53<lambdabot>groupBy _ [] = []
18:02:53<lambdabot>groupBy eq (x:xs) = (x:ys) : groupBy eq zs
18:02:53<lambdabot> where (ys,zs) = span (eq x) xs
18:02:56<Berengal>> groupBy (==' ') "hello there person"
18:02:56<amgarching>i am very occasional haskeller, any comments on the code "sanity" here? http://www.moonpatio.com/fastcgi/hpaste.fcgi/view?id=2448 In particular "simplify" looks ugly to me.
18:02:57<lambdabot> Couldn't match expected type `Char -> Bool'
18:03:05<Cale>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split
18:04:04<joeally>[a*b|a<-[1,2,3]|b<-[1,2,3]]
18:04:14<joeally>>[a*b|a<-[1,2,3]|b<-[1,2,3]]
18:05:07<joeally>@[a*b|a<-[1,2,3]|b<-[1,2,3]]
18:05:07<Cale>amgarching: Well... there's a standard complex number library you could use for one.
18:05:07<Cale>> [a*b|a<-[1,2,3]|b<-[1,2,3]]
18:05:07<lambdabot> [1,4,9]
18:05:07<lambdabot>Unknown command, try @list
18:05:09<Cale>The space after > is not optional
18:05:13<Berengal>joeally: Needs a space after >
18:05:14<joeally>okay
18:05:15<Berengal>right
18:05:17<joeally>sorry
18:05:34<Cale>quite all right
18:05:37<joeally>it doesnt work when i use variables
18:05:44<jbjohns>@src foldMapDefault
18:05:44<lambdabot>Source not found. Do you think like you type?
18:05:46<joeally>i get this Illegal parallel list comprehension: use -XParallelListComp
18:06:01<Cale>joeally: Yeah, it's an extension which you have to turn on
18:06:05<joeally>ooh
18:06:11<joeally>how do i do that
18:06:25<Cale>joeally: If you add {-# LANGUAGE ParallelListComp #-} to the top of your file it will work
18:06:31<Berengal>joeally: Yeah, you need to enable them. Either run ghc/ghci with -XParallelListComp, as the suggestion says, or put {-# LANGUAGE ParallellListComp #-} at the very top of your file
18:06:32<joeally>okay thanks
18:06:40<Cale>Or just pass -XParallelListComp on the commandline to ghc
18:06:51<cnwdup>Should libffi.so be provided by ghc?
18:06:52<jbjohns>@src fmapDefault
18:06:53<lambdabot>Source not found. And you call yourself a Rocket Scientist!
18:07:01<joeally>thanks
18:07:06<Cale>Also, if you're inside ghci, you can :set -XParallelListComp
18:07:07<jbjohns>> import Data.Traversable
18:07:08<lambdabot> <no location info>: parse error on input `import'
18:07:41<Cale>jbjohns: The @src and > are not tied to each other anyhow.
18:07:43<amgarching>Cale: this doenst seem to work for complex numbers: (1 % 2) :+ 3
18:07:51<jbjohns>aha
18:08:33<jbjohns>I guess it wouldn't make sense for them to be really
18:08:37<Cale>amgarching: hmm, oh, right.
18:09:06<Cale>amgarching: That's another Haskell 98 stupidity. There's a pointless class restriction on the Complex datatype.
18:09:20<Cale>I suppose it can't be helped.
18:10:55<Cale>Ah, I see why too. It's because Num has too many stupid extra methods. Implementing abs and signum for Complex numbers requires a sqrt.
18:10:58<schoenfinkel>@src Data.Traversable.fmapDefault
18:10:58<lambdabot>Source not found. Have you considered trying to match wits with a rutabaga?
18:11:29<Cale>I'm pretty sure there's no source in the @src database for that. You can get the source from the haddock documentation
18:12:06<Cale>-- | This function may be used as a value for `fmap` in a `Functor` instance.
18:12:07<Cale>fmapDefault :: Traversable t => (a -> b) -> t a -> t b
18:12:07<Cale>fmapDefault f = getId . traverse (Id . f)
18:12:26<Cale>newtype Id a = Id { getId :: a }
18:12:53<Cale>(and it has trivial Functor and Applicative instances)
18:14:44<joeally>I have this function fro Sxy
18:14:47<joeally>> sxy x y = fromIntegral([a*b|b<-y|a<-x]) - fromIntegral((sum x)*(sum y))/fromIntegral(length x)
18:14:56<lambdabot> <no location info>: parse error on input `='
18:15:32<joeally>only it gives this error
18:15:34<joeally>No instance for (Integral [t])
18:15:34<joeally> arising from a use of `sxy' at <interactive>:1:0-10
18:15:34<joeally> Possible fix: add an instance declaration for (Integral [t])
18:15:45<joeally>sxy x y = fromIntegral([a*b|b<-y|a<-x]) - fromIntegral((sum x)*(sum y))/fromIntegral(length x)
18:16:28<skorpan>fromIntegral doesn't take a list
18:16:28<skorpan>[a*b|b<-y|a<-x] is a list
18:16:40<joeally>oh yeah
18:16:42<joeally>thanks
18:16:46<skorpan>make that [ a * b | b<-y, a<-x ] btw
18:16:50<joeally>i for got to do the some of it
18:17:04<skorpan>or [ a * b | b <- y, a <- x ], much more readable
18:17:13<joeally>okay
18:17:15<joeally>noted
18:17:35<joeally>sxy x y = fromIntegral(sum [ a*b | b<-y | a<-x ]) - fromIntegral((sum x)*(sum y))/fromIntegral(length x)
18:17:44<joeally>there we go
18:18:13<Cale>amgarching: So this simplify is more or less collecting the like terms of the sum?
18:18:50<amgarching>how would you factorize \sqrt(int) into int * \sqrt(int) ?
18:19:41<amgarching>Cale: right, there appear several cancelling terms like (x*y) with opposit coeefs in expansion
18:20:57<skorpan>:t foldr'
18:20:58<lambdabot>Not in scope: `foldr''
18:21:02<skorpan>:t Data.Foldable.foldr'
18:21:03<lambdabot>forall a b (t :: * -> *). (Data.Foldable.Foldable t) => (a -> b -> b) -> b -> t a -> b
18:23:25<skorpan>:t foldr1
18:23:26<lambdabot>forall a. (a -> a -> a) -> [a] -> a
18:25:09<Cale>amgarching: I have something perhaps simpler if you don't mind reordering the monomials.
18:26:47<Cale>> map (fst . head &&& sum . map snd) . groupBy ((==) `on` fst) . sortBy (comparing fst) $ [("a",4),("a",3),("b",7),("a",-12)]
18:26:49<lambdabot> [("a",-5),("b",7)]
18:27:24<Cale>> map (fst . head &&& sum . map snd) . groupBy ((==) `on` fst) . sortBy (comparing fst) $ [("a",4),("a",3),("b",7),("a",-12),("b",-7)]
18:27:25<lambdabot> [("a",-5),("b",0)]
18:27:40<Cale>> filter ((/= 0) . snd) . map (fst . head &&& sum . map snd) . groupBy ((==) `on` fst) . sortBy (comparing fst) $ [("a",4),("a",3),("b",7),("a",-12),("b",-7)]
18:27:41<lambdabot> [("a",-5)]
18:29:25<lilac>@seen roconnor
18:29:25<lambdabot>roconnor is in #haskell-in-depth, #haskell-blah and #haskell. I last heard roconnor speak 1h 8m 28s ago.
18:30:04<Cale>simplify = filter ((/= (0,0)) . snd)
18:30:04<Cale> . map (fst . head &&& csum . map snd)
18:30:04<Cale> . groupBy ((==) `on` fst)
18:30:04<Cale> . sortBy (comparing fst)
18:30:10<lilac>@tell roconnor I've uploaded a version of the numbers package with Enum for Natural fixed.
18:30:10<lambdabot>Consider it noted.
18:30:46<lilac>Cale: s/csum/sum/?
18:30:55<Cale>lilac: csum is something from his code
18:31:19<Cale>He ended up having to reimplement complex numbers because Data.Complex has a stupid class dependency.
18:31:30<lilac>fair enough
18:31:32<Cale>(and won't admit complex rationals0
18:32:44<lilac>something like (+) *** (+) (for a (***) that works on 2-arg functions) then?
18:33:14<lilac>@hoogle (a -> b, c -> d) -> (a, c) -> (b, d)
18:33:14<lambdabot>No results found
18:33:40<amgarching>Cale: does it really work?! I'll need some googling to understand that. I saved your snipplets, thanks for your thoughts. I need to run.
18:34:02<arjanb>@type on
18:34:03<lambdabot>forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
18:34:08<Cale>amgarching: However, I wonder if it wouldn't save some trouble to make use of a more general library regarding these polynomials... I have a nice library for multivariate polynomials (and other monoid rings) which I still haven't put on hackage.
18:34:45<EvilTerran>?type uncurry (&&&)
18:34:46<lambdabot>forall (a :: * -> * -> *) b c c'. (Arrow a) => (a b c, a b c') -> a b (c, c')
18:34:55<EvilTerran>?type uncurry (***) -- even
18:34:56<lambdabot>forall (a :: * -> * -> *) b c b' c'. (Arrow a) => (a b c, a b' c') -> a (b, b') (c, c')
18:34:59<Cale>amgarching: Note that comparing is from Data.Ord, `on` is from Data.Function, and (&&&) is from Control.Arrow
18:35:04<wli>Cale: Any of the algorithms for translating systems of polynomial equations into eigensystems?
18:35:25<Cale>wli: No, nothing of that sort. Just basic arithmetic on monoid rings.
18:35:34<joeally>is there any way you can have executed writing in your code like # or /**/ in other languages
18:35:43<amgarching>Cale: I just wanted to compare two expressions for spherical harmonics expansion for equivalence
18:36:19<joeally>unexecuted*
18:36:36<joeally>commets
18:36:39<Cale>joeally: {- ... -} and -- ...
18:36:43<joeally>okay
18:36:50<joeally>thank you
18:36:59<Cale>joeally: Moreover, it's okay to nest the bracketed comments.
18:37:06<Cale>(unlike in C)
18:37:20<joeally>thanks
18:37:37<Hunner>How would I pattern match for (Either a b)? Am I thinking about Either wrong?
18:37:44<Cale>case foo of
18:37:47<Cale> Left x -> ...
18:37:51<Cale> Right y -> ...
18:37:57<Hunner>ah, I think I saw that somewhere. Thanks Cale
18:38:15<Cale>Hunner: Or of course, use multiple equations, like you see in various functions.
18:38:15<Hunner>ACTION didn't recognize it though
18:48:21<jbjohns>Ok, I'm looking through the cabal-install code at the flag -> monoid code. Can anyone tell me the advantage of this over using a Dictionary and overwriting the values? Like in Java you would just make a Properties object and load the config files in reverse order of preference.
18:48:48<Cale>jbjohns: That's exactly what it is.
18:48:50<jbjohns>I mean, I believe you that they are there, I'm just trying to break out of my OO thinking
18:49:15<mauke>dictionaries form a monoid
18:49:25<jbjohns>ok, I think I get that
18:49:29<Cale>jbjohns: The monoid in question has the empty dictionary as a unit, and preferential combining as multiplication.
18:49:35<Cale>(mappend)
18:50:52<gwern>jbjohns: so therefore the advantage is reusing existing code and directly naming the abstract math object you are using
18:50:58<Cale>jbjohns: When you have a bunch of things which have a unit and an associative combining operation, it's usually good to recognise them as a monoid, because then various libraries which know how to work generically with various monoids can make use of that, and it helps to document the properties of the code.
18:51:23<Cale>Also, you get a bunch of related monoids for free, which is sometimes helpful.
18:51:44<Cale>For example, we automatically get an mempty and mappend for functions which produce these dictionaries.
18:52:02<jbjohns>ok, so one obvious advantage is the type system helps out to make sure you aren't mixing e.g. Boolean flags with value flags or list flags, right?
18:52:19<Cale>Yes, but it would do that anyway.
18:52:50<jbjohns>well, like in Java with the Properties object approach; it's all just strings.
18:52:52<gwern>yeah; the sig would be Monoid Option vs Monoid Bool; this clashes just as would Option vs Bool
18:53:30<Cale>Where is the code in question btw?
18:53:46<jbjohns>from me? Which code?
18:53:55<Cale>The code that you're currently looking at.
18:54:20<jbjohns>I just recently went through some property loading stuff with Java at around the same time I saw the entry from dcoutts so I wondered what it would look like in Haskell
18:54:23<Cale>This is sort of a standard approach, so I have a rough idea of what it looks like, but I haven't seen the cabal version of it :)
18:54:40<jbjohns>Ah, the cabal code I just did a google for "cable source"
18:54:54<jbjohns>and now I'm looking through the darcs repo
18:55:12<jbjohns>http://darcs.haskell.org/cabal/Distribution/Simple/
18:55:15<jbjohns>that's part of it
18:55:22<jbjohns>Setup.hs
18:56:12<dcoutts_>jbjohns: right, we don't want a standard collection type like a dictionary or map because that the command line parameters are all different types but a collection would force them to be all the same type
18:56:14<jbjohns>I've typically been a dynamically typed programmer, but all this C#/Java they've had me doing at work has started to grow my interest in Haskell lately for some reason
18:57:11<dcoutts_>jbjohns: probably because Haskell has a proper static type system :-)
18:57:11<persica>"some reason" -> "good reason" (fixed that for you)
18:57:12<jbjohns>dcoutts: good point
18:57:51<jbjohns>well, not "for some reason", because I do see advantages even those crappy type systems have so I've been interested in what a state-of-the-art one can do for me
18:58:25<gwern>dcoutts_: that wouldn't be too bad; we could just define a sum type for the dictionary though
18:58:42<olsner>I just made a bug... in the type system!
18:58:50<jbjohns>actually I guess it was Sigfpe's monoid thing he did. That really sparked my interest
18:58:59<dcoutts_>gwern: bleugh, I want to know I'm getting the right type for each command line arg
18:59:08<gwern>heh
18:59:14<Cale>It does look like it might be nice to have some Data.Generics-based combinators to make those monoid instances though.
18:59:21<dcoutts_>Cale: yes
18:59:25<gwern>my point being that if java had sum types it wouldn't be so bad to not have monoids
18:59:30<gwern>(did java ever get'em?)
18:59:32<Cale>With 20 or 30 fields the code gets really repetitive :)
18:59:44<jbjohns>where he just changed the type signature of some function to have Dual to make the tracing run in reverse
18:59:52<dcoutts_>Cale: aye, sadly I'm restricted to H98 for Cabal
19:00:36<Cale>jbjohns: Yeah, monoids are absolutely everywhere in computer programming (and computer science) and they're really useful to identify
19:01:10<jbjohns>I've been reading the tour entry in the latest Monad.Reader
19:01:18<jbjohns>the applicative stuff is really cool
19:01:30<Cale>http://www.reddit.com/r/programming/comments/7cf4r/monoids_in_my_programming_language/c06adnx -- here's an oldish response I gave to someone who was interested in knowing why monoids are useful.
19:02:17<jbjohns>yea, seen that one. The sorting stuff is quite neat
19:02:28<olsner>if typing makes haskell programs free of run-time defects, is unit-testing required for testing the typing rules you've built to enforce the correctness of the rest of the program?
19:03:12<Cale>olsner: Well, typing doesn't automatically make sure the program is entirely correct, but it goes some distance toward it.
19:03:38<Cale>olsner: You might, if your types are sufficiently complicated, want to do a bunch of testing.
19:03:44<Cale>(at the type level)
19:04:23<Cale>But normally, types are much less complicated than the code and are easy enough to check by visual inspection.
19:04:35<persica>Typing supplements testing more than replaces it. It sort of seems like a general sanity check, but it doesn't prevent you from leaving out a step or the like.
19:04:48<Cale>Well, sometimes it does ;)
19:05:06<olsner>yeah, this is easily the most complex type program I've made thus far
19:05:20<Cale>:t let myMap :: (a -> b) -> [a] -> [b]; myMap f [] = []; myMap f (x:xs) = x : myMap xs in myMap
19:05:21<lambdabot> Couldn't match expected type `a -> b' against inferred type `[a1]'
19:05:22<lambdabot> In the first argument of `myMap', namely `xs'
19:05:22<lambdabot> In the second argument of `(:)', namely `myMap xs'
19:05:29<Cale>:t let myMap :: (a -> b) -> [a] -> [b]; myMap f [] = []; myMap f (x:xs) = x : myMap f xs in myMap
19:05:31<lambdabot> Couldn't match expected type `b' against inferred type `a'
19:05:31<lambdabot> `b' is a rigid type variable bound by
19:05:31<lambdabot> the type signature for `myMap' at <interactive>:1:19
19:05:32<persica>The way I see it, the type system makes sure the system is doing what you are telling it to. But we sometimes tell it the wrong thing.
19:05:46<Cale>There we go, that's the error I wanted ;)
19:05:48<persica>And we tell it what the type system is... so...
19:06:13<Cale>Yeah, it doesn't completely ensure that the program you've written is the program you wanted to write.
19:06:29<Cale>Just makes it hard to to structurally unsound things.
19:06:43<Cale>I've likened it to the nubs on lego blocks in the past.
19:07:00<EvilTerran>particularly in languages with restricted side-effects, strict typing dramatically limits the domain of situations over which you need to test
19:07:22<jbjohns>do you find that in Haskell it's easier (as in; less work) to do unit testing?
19:07:23<Cale>to do*
19:07:35<Cale>jbjohns: Absolutely, yes.
19:07:45<Cale>jbjohns: Purity is an enormously helpful thing.
19:07:49<EvilTerran>Cale, and unsafeCoerce is a craft knife and a bottle of glue?
19:07:55<Cale>EvilTerran: hehehe
19:08:02<EvilTerran>:P
19:08:12<Cale>EvilTerran: Watch out! You'll cut your finger!
19:08:32<olsner>unsafeCoerce duplo :: Lego
19:08:38<jbjohns>yea, looking at the QuickCheck stuff looks awesome. I was just wondering how often in practice the tests are mostly just constraints that generate tests
19:09:02<EvilTerran>Cale, and then glue it to the table?
19:09:18<EvilTerran>ah, the hazards of semantic-breaking functions...
19:09:44<EvilTerran>unsafeGlueMissileToFinger
19:09:44<Cale>jbjohns: I find it's a very useful way of testing my code, or testing that a change I'm about to make in the way I've implemented something preserves the meaning...
19:10:14<Cale>jbjohns: Some people try to discover enough general properties of their code that the quickcheck tests get full code coverage.
19:10:53<Cale>jbjohns: That's usually a fairly tricky thing to do, but if you can do it, it gives at least a little confidence that your tests actually characterise what it is that you're doing.
19:10:55<olsner>quickcheck properties seem like they translate very well into general pieces of wisdom about what it is you're trying to do, really
19:11:14<Cale>Yes, they make great documentation.
19:11:18<jbjohns>nice. The problem I have with TDD in dynamic languages and even C#/Java is that you're basically just writing code. This code could also have bugs. Describing constraints and then verifying them sounds much better. :)
19:11:26<olsner>"operation A should lead to property Bar and should never ever break Foo"
19:11:59<olsner>and writing an Arbitrary instance shows you why you want to encode as many properties as possible in the actual data types you're working with
19:11:59<Cale>jbjohns: It also means that you're testing the interrelationships between various bits of your code, and not just in isolation.
19:12:06<skorpan>jbjohns: there are tools for verifying java code as well
19:12:36<Cale>Yeah, the need to write instances of Arbitrary is a good way to ensure that you're making sufficient use of the type system ;)
19:12:55<olsner>(although you can always add quickcheck properties for your arbitrary instance)
19:13:10<Cale>(in particular, it gets you to use newtype instead of just type)
19:13:59<Cale>Though, I sort of wish that quickcheck came with a bunch of identity newtypes which twisted the arbitrary instances in various ways.
19:14:18<Cale>I wonder how doable that is :)
19:14:38<olsner>quickcheck2 does iirc
19:15:22<pumpkin>twisty newtypes!
19:15:25<olsner>Cale: you have e.g. OrderedList, NonZero etc from here: http://hackage.haskell.org/packages/archive/QuickCheck/2.1.0.1/doc/html/Test-QuickCheck-Arbitrary.html
19:15:41<Cale>Aha! Very nice :)
19:16:18<jbjohns>skorpan: I know, but not being pure, the utility is lessened, no?
19:16:44<jbjohns>cale: what do you mean "newtype instead of just type"? You mean giving existing types an alias as well as naming others or?
19:16:44<Cale>jbjohns: I imagine so.
19:17:19<Cale>jbjohns: Well, if you use type to define the types your program is using, you get fewer guarantees about correctness.
19:17:59<Cale>jbjohns: (in exchange for a little bit of quick convenience, because all the functions which operated on the original type still works on the one you defined with type)
19:18:01<jbjohns>hrm, I don't understand. But I'm reading through "Real world Haskell", maybe that will clue me in
19:18:25<jbjohns>ah, type! Not data. What does type do, just an alias?
19:18:32<Cale>With newtype, you get a genuinely different type as far as the type system is concerned, but it just happens to be exactly the same as an existing type as runtime.
19:18:36<Cale>yeah
19:18:57<Cale>type just makes an alias which desugars away before the type checker even runs.
19:19:05<jbjohns>ah
19:21:21<Cale>newtype by contrast is like data, except that you're only allowed one case and one field, and the semantics for pattern matching are very subtly different, so that the compiler can represent values of the newtype as values of the original type that it wraps
19:21:46<Cale>and the type checker gets to actually check things properly then
19:21:59<Cale>For instance, you might have:
19:22:07<Cale>newtype Dollars = D Integer
19:22:33<pumpkin>mmm, enjoying the new hackage twitter account
19:22:37<Cale>which would be like an Integer at runtime, but with no chance of confusing it with other Integers which happen to be in the program
19:22:42<mm_freak>unfortunately for your own account, you'll likely never exceed the size of an Int =/
19:22:49<Cale>hehe :)
19:22:50<olsner>newtype is perfect for "tagging" values
19:22:59<Cale>yeah
19:23:10<Berengal>type is nice as a documentation tool
19:23:20<Cale>If you need to write a new instance of a typeclass when one already exists, newtyping it is a good trick.
19:23:21<Berengal>Like String for [Char] or FilePath for String
19:23:33<Cale>You can then use the data constructor for the newtype to select which instance you want.
19:23:55<mm_freak>Berengal: i use 'type' to save some typing… like "'type' for me" =)
19:24:18<mm_freak>i often use things like this: type AppIO = StateT AppState (ReaderT AppConfig IO)
19:24:23<Cale>Berengal: Though, it's a bit of a shame that we don't have nicely structured cross-platform file paths by default. :)
19:24:34<mm_freak>(a few days earlier, i just used StateT or RWS, though)
19:24:48<olsner>and you can also hide newtypes in modules to get a cheap way to make sure that only valid values generated by your module get passed around
19:24:52<mm_freak>((RWST))
19:24:56<Berengal>Cale: Yeah, it sort of is... Still, file paths are strings...
19:25:18<Cale>Berengal: Actually, the fact that file paths are Strings might be a bit of a shame in itself...
19:25:33<jbjohns>that's cool stuff. The other day I was looking at the monoid stuff with Sum and Product but when I tried to make my own with newType ghc wouldn't let me make Monoid instances of both
19:25:36<Cale>Peaker has some interesting ideas about this.
19:25:53<Berengal>Cale: Well, it makes them easy to work with. I wouldn't cry if FilePath turned newtype on me though
19:26:02<jbjohns>Berengal: I would disagree actually. File paths have more than that, they have seperators that can be / or \ and other things
19:26:21<skorpan>if i'm in a monad HelloM and i want to execWriter, how would i do that?
19:26:30<jbjohns>that is, they are a string but there are certain assumptions about them
19:26:33<virus_>I'm having a lookt at "3.15 Datatypes with Field Labels" in the Haskell 98 Report, but I don't seam to get it. Is there anywhere a nice example of these?
19:26:52<Cale>skorpan: Well, the execWriter can't have anything to do with your monad, so stick it in a let?
19:26:53<olsner>data FilePath = FilePath (Maybe Root) [String]
19:27:16<skorpan>Cale: but then how would i extract what the writer resulted in?
19:27:37<Cale>skorpan: let log = execWriter (some Writer computation)
19:27:38<FunctorSal>you're learning haskell basics from the report? that's badass ;)
19:27:49<mm_freak>olsner: the first argument is going to be Nothing in most cases
19:27:53<skorpan>Cale: i see... :|
19:28:03<olsner>mm_freak: maybe
19:28:05<Cale>skorpan: Does that make sense?
19:28:09<Berengal>virus_: data Person = Person {firstName :: String, lastName :: String, age :: Int}
19:28:43<olsner>some platforms do have esoteric notions of sets of roots though
19:28:50<Berengal>Then you can do 'setAge person newAge = person{age = newAge}'
19:28:53<mm_freak>i'd rather prefer something like: newtype FilePath = FilePath ByteString
19:29:20<Berengal>I'd prefer an abstract FilePath myself...
19:29:21<mm_freak>because all platforms have some string representation of roots, so i'd just add some functions for root handling
19:29:21<EvilTerran>virus_, Berengal's example creates a constructor, Person :: String -> String -> Int -> Person; and accessors firstName, lastName :: Person -> String; age :: Person -> Int
19:29:22<skorpan>Cale: it does actually, i never thought about the fact that execWriter returns w and not e.g. "m w"
19:29:31<Cale>skorpan: Okay :)
19:29:46<virus_>ah, cool. now that makes a lot more sense
19:29:51<mm_freak>Berengal: that would result in 'show' or some 'pathToString' being abused most of the time
19:30:17<Cale>mm_freak: Well, I think it would still make manipulation easier.
19:30:17<FunctorSal>another cute use of named fields is record puns: cycleName Person{firstName} = cycle firstName
19:30:22<EvilTerran>mm_freak, and "stringToPath"
19:30:37<Berengal>mm_freak: Can't be worse than simply extracting the bytestring...
19:30:45<FunctorSal>or setName p firstName = p{firstName}
19:30:47<EvilTerran>FunctorSal, is that an extension thar?
19:30:57<cnwdup>data Plugin = P { runPlugin :: IO Plugin }, myPlugin = P (do { putStrLn "Hello."; return myPlugin } }, evalPlugin plugin = runPlugin plugin >>= evalPlugin -- how expensive would that be if I want to have a non-terminating plugin loop and state emulated due to returning the plugin-structure?
19:31:00<FunctorSal>EvilTerran: yeah, NamedFieldPuns
19:31:16<EvilTerran>nice
19:31:19<FunctorSal>even more concise are record wildcards
19:31:29<Cale>What would possibly be really cool is if permissions to act on files was obtained from the filesystem in a way which didn't necessarily involve these strings at all.
19:31:30<FunctorSal>cycleName Person{..} = cycle firstName
19:31:30<EvilTerran>looks a bit non-scalable, but nice for a lot of circumstances
19:31:37<EvilTerran>perlers would love it :P
19:31:57<skorpan>hm, why isn't there anything such as evalWriter?
19:32:02<FunctorSal>EvilTerran: actually it's more forwards-compatible than positional components
19:32:13<Cale>skorpan: I don't know. It's stupid.
19:32:26<FunctorSal>granted, that is, if you don't change the names
19:32:34<skorpan>Cale: is evalWriter stupid or is it stupid that it doesn't exist?
19:32:35<Cale>skorpan: Maybe they figured that you wouldn't have bothered to write it as a Writer computation in the first place if you didn't care about the log.
19:32:42<EvilTerran>FunctorSal, i mean, it wouldn't work as a syntax on its own if you needed to dismantle two records of the same type in the same scope, say
19:32:44<Cale>It's stupid that it doesn't exist.
19:32:49<mm_freak>Berengal: and not better, i guess… abstractions are fine, but too much abstraction can get annoying
19:32:53<FunctorSal>EvilTerran: ah, right
19:32:57<Cale>In fact, I'm a little fed up with the whole mtl.
19:33:13<skorpan>there's been some discussion about mtl on the ML, no?
19:33:23<skorpan>on haskell-cafe, that is
19:33:36<Berengal>mm_freak: Yeah. I'm fine with type FilePath = String too :P
19:33:52<Berengal>But if we're going to abstract, might as well make it an abstract type :)
19:34:03<EvilTerran>FunctorSal, ie, it fills the same sort of niche served by perl's mighty "it" variable ($_). it works in lots of small cases, but stops being useful once you start needing the name for more than one thing
19:34:08<FunctorSal>Berengal: wouldn't newtype with OverloadedStrings be better?
19:34:23<mm_freak>Berengal: for whatever reason =)
19:34:27<FunctorSal>and deriving Monoid
19:34:41<mm_freak>abstraction doesn't have to mean hiding things
19:35:00<mm_freak>it can also just mean: type-safe convenience =)
19:35:20<Cale>mtl really isn't that good a monad library. There are nicer ones like monadLib.
19:35:28<Cale>Oh! I just had a lovely idea...
19:35:57<Berengal>mm_freak: No, it doesn't, but if you think about what a file path really is, would you say it's a string, or it's location on disk?
19:36:20<FunctorSal>generally type classes with generalizedNewtypeDeriving seems like a good way to have your type-safe cake and eat it without too much wrapping
19:36:25<Cale>I should ask Edward Kmett about seeing if his category-extras tricks could possibly work to improve performance of MonadPrompt...
19:36:35<virus_>Berengal, EvilTerran: So how would I access the data fields? like filtering all persons from a list with their first name being "Anna": filterAnna l = filter(\p -> p{firstName} == "Anna", l)
19:36:55<Saizan>MonadPrompt is already CPS'ed iirc
19:37:05<Cale>hmm, come to think of it :)
19:37:07<EvilTerran>virus_, filter ((=="Anna") . firstName) would work
19:37:13<FunctorSal>virus_: that would be filter (\p -> firstName p == "Anna")
19:37:20<mm_freak>Berengal: that's a good point
19:37:26<FunctorSal>the {} is for pattern matching
19:37:36<mm_freak>Berengal: however, i don't know any OS where it's not a string =)
19:37:42<Cale>Actually, I should look into what the performance of MonadPrompt is actually like.
19:38:00<Cale>Having a MonadPrompt-based monad library would be really neat.
19:38:20<EvilTerran>virus_, or filterAnnas l = [p | p@Person{firstName = "Anna"} <- l] would work, too, i believe
19:38:25<Berengal>mm_freak: Of course, working at the lower level doesn't hurt us too much in this case. There might not be a good reason to abstract, but if we're already at the point of discussing how to abstract we might as well do it properly. Abstracting a string to a string makes no sense :)
19:38:31<mm_freak>Berengal: generally real numbers are limits of cauchy series, but if you viewed it that way, the Prelude would get extremely inconvenient =)
19:38:53<virus_>ah. so every fields creates an accessor
19:39:16<Cale>(though, even as it is, how MonadPrompt actually functions is a little bit tricky for me to understand)
19:39:20<EvilTerran>virus_, that using the record syntax in a pattern (Person{firstName = "Anna"}), as well as at-patterns (the pattern x@(...) acts like (...), but also binding the value matched by that pattern to x)
19:39:29<skorpan>"warn" is to "warning" as X is to "error"... what is X?
19:39:34<skorpan>"err"?
19:39:39<wli>ACTION is at something of a loss to describe how to represent real numbers with arbitrary/infinite precision.
19:40:01<Twey>Yes, ‘to err’
19:40:05<Twey>It's a verb
19:40:06<skorpan>thank
19:40:07<skorpan>s
19:40:13<Twey>err/erring/erred/erred
19:40:16<EvilTerran>virus_, indeed; those accessors are normal functions, just generated automatically for your convenience :)
19:40:23<EvilTerran>wli, CReal not suitable?
19:40:38<Saizan>Cale: though you've to interpret a Prompt action into something, and often it's nice to have a monad as that something
19:40:47<wli>It may well be. I'm merely at a loss to explain how it works.
19:40:51<Twey>skorpan: I wouldn't say they were really comparable in computing terms, though
19:41:07<EvilTerran>wli, ah. i have no idea how it works, so i'm afraid i can't help you there. :P
19:41:29<Twey>To warn is to offer information about something, but to err is to actually commit the error
19:41:36<Saizan>well, i'm not that sure about often :)
19:41:46<EvilTerran>> exp (sqrt (-1) * pi) :: Complex CReal -- however, i do love that this actually works
19:41:48<lambdabot> (-1.0) :+ 0.0
19:41:49<Cale>Saizan: That's part of what makes it nice, you get things like liftP :: Prompt p r -> PromptT p m r
19:42:24<wli>What is this MonadPrompt thing?
19:42:33<Cale>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadPrompt
19:42:42<Cale>http://hackage.haskell.org/packages/archive/MonadPrompt/1.0.0.1/doc/html/src/Control-Monad-Prompt.html#MonadPrompt
19:43:33<Cale>wli: Basically, it's an extremely general monad parametrised over an arbitrary datatype of effect descriptions. When you run it, you supply implementations of those effects.
19:43:52<Saizan>it's also nice that you could combine monad by using (p :+: q) as the prompt type
19:43:58<Cale>Yes :)
19:45:28<skorpan>is there any simple showList definition which is equivalent to "lines"?
19:46:34<Cale>I feel that perhaps there ought to be something like... data Evaluator p r b = Evaluator { ret :: r -> b ; prm :: forall a. p a -> (a -> b) -> b }, and then an algebra of operations on those.
19:47:18<skorpan>@instance Show Char
19:47:19<lambdabot>Maybe you meant: instances instances-importing
19:47:39<FunctorSal>skorpan: lines . fmap show?
19:47:50<FunctorSal>if I understand you correctly
19:48:49<skorpan>what i mean is that i simply want [A 2, A 9] to be serialized to (show (A 2) ++ "\n" ++ show (A 9) ++ "\n")
19:49:05<skorpan>using showList in instance Show A where
19:49:12<skorpan>data A = A Int
19:49:17<FunctorSal>that's unlines . fmap show
19:49:23<skorpan>no, i got a type error
19:49:28<FunctorSal>yeah it is unlines
19:49:39<FunctorSal>> unlines . fmap show $ [1,2,3]
19:49:40<skorpan>oh, right
19:49:41<lambdabot> "1\n2\n3\n"
19:49:46<skorpan>thanks :)
19:49:49<FunctorSal>np
19:49:50<Cale>skorpan: It's not usually considered a great idea to make show instances that don't produce valid Haskell code...
19:50:04<Cale>But you can of course do it
19:50:10<skorpan>Cale: i know, but in this case it's only for ease of debugging
19:50:17<FunctorSal>theres always Text.PrettyPrint.ANSI.Leijen.Pretty :)
19:50:18<Cale>ah, okay :)
19:50:44<Cale>Wow, someone went nuts with the module path there ;)
19:50:51<FunctorSal>indeed
19:51:09<FunctorSal>it's particularly evil that the parts aren't hierarchical, so any permutation would make sense
19:51:16<FunctorSal>;)
19:51:21<skorpan>FunctorSal: actually, that seems to be returning "" for me for some reason... when i don't define showList, i get the right output
19:51:36<skorpan>uh, wait, no, my bad :|
19:51:47<skorpan>i had showList xs = ..
19:51:53<skorpan>uh, what :|
19:51:55<skorpan>i'm confused!
19:52:27<skorpan>FunctorSal: ah, yes, i see... showList is [a] -> ShowS
19:52:34<skorpan>type ShowS = String -> String
19:52:41<skorpan>that was the reason that i asked in the first place :)
19:53:31<SamB>FunctorSal: almost makes you want to have [facet :: tag] specifications in imports ...
19:53:43<Saizan>you're supposed to prepend your output to the given list
19:53:47<FunctorSal>SamB: I thought that too...
19:54:16<SamB>but then you'd need a way to retroactively add those facet :: tag pairs to modules from existing packages
19:54:21<SamB>and specify defaults
19:54:25<SamB>or something ...
19:56:52<roconnor>Cale: have you installed the new numbers package into lambdabot?
19:56:52<lambdabot>roconnor: You have 1 new message. '/msg lambdabot @messages' to read it.
19:57:10<Cale>roconnor: hmm
19:57:31<roconnor>Cale: lilac installed proper Enum methods for Natural.
19:57:40<Cale>roconnor: I haven't updated things on the machine lambdabot is running on in quite some time.
19:58:17<Cale>/home/cale/.ghc/x86_64-linux-6.8.3/package.conf:
19:58:17<Cale> numbers-2008.4.20, numbers-2008.4.20.1
19:58:25<virus_>for a testcase I want to define a list of objects. Now I've written myList = [ (Foo "a"), (Foo "b"), (Foo "c") ], but with newlines and it doesn't recognize it anymore. It tells me about a parse error with incorrect indentation. I tried adding a \ at the end of the lines with no success.
19:58:37<roconnor>Cale: lilac uploaded it a few hours ago.
19:58:49<EvilTerran>virus_, \ at the end of lines doesn't mean anything in haskell, except in stringd
19:58:54<Cale>updated.
19:59:28<virus_>So is there a way of splitting a list into multiple lines in the sources?
19:59:28<EvilTerran>virus_, the general rule is, if you're continuing an expression on the next line, be sure to indent the continuations more than the first line
19:59:43<EvilTerran>virus_, and don't use tabs
20:00:15<EvilTerran>because the layout engine's interpretation of them may be different to your editor's interpretation
20:00:18<virus_>ok. no tabs used so far. I got expandtab enabled as I'm writing a lot of python code :)
20:02:51<roconnor>> [1..infinity]
20:02:53<lambdabot> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28...
20:03:04<mauke>:t infinity
20:03:05<lambdabot>Natural
20:03:54<trofi>> infinity
20:03:55<lambdabot> * Exception: stack overflow
20:03:59<trofi>> infinity + 1
20:04:01<lambdabot> * Exception: stack overflow
20:04:37<trofi>> infinity `div` 2
20:04:42<lambdabot> * Exception: stack overflow
20:04:55<trofi>> infinity == infinity
20:05:10<lambdabot> thread killed
20:05:19<roconnor>@tell lilac Your new Naturals appear to be installed in lambdabot now.
20:05:19<lambdabot>Consider it noted.
20:05:32<roconnor>@tell lilac thanks to Cale.
20:05:32<lambdabot>Consider it noted.
20:05:45<virus_>EvilTerran: so there is no possibility to split the declaration of a static list into multiple lines?
20:05:47<roconnor>> min 5 infinity
20:05:48<lambdabot> 5
20:05:53<roconnor>> min infinity 5
20:05:54<lambdabot> 5
20:06:02<mauke>virus_: of course there is
20:06:05<mauke>I do it all the time
20:06:33<roconnor>[1,2,3]++\n[4,5,6]
20:06:40<Jedai>virus_: You can split such a declaration anywhere you want
20:06:52<roconnor>[1,2,3,\n4,5,6]
20:06:59<trofi>> min 5 (-infinity)
20:07:01<lambdabot> * Exception: Natural: (-)
20:07:11<trofi>> max 5 (-infinity)
20:07:13<lambdabot> * Exception: Natural: (-)
20:07:16<trofi>:p
20:07:23<roconnor>-infinity isn't a Natural number
20:07:27<roconnor>neither is -1
20:07:32<Jedai>trofi: Naturals are naturals... there is no negative numbers
20:07:35<Philonous>infinity isn't a natural number either
20:07:36<roconnor>> -1 :: Natural
20:07:38<lambdabot> * Exception: Natural: (-)
20:07:43<roconnor>Philonous: :D
20:08:03<roconnor>Philonous: infinity isn't a natural number, but it is a Natural number.
20:08:05<trofi>> (-1)/0
20:08:06<lambdabot> -Infinity
20:08:18<roconnor>trofi: different type
20:08:24<roconnor>that's a Double.
20:08:29<trofi>yes, i understand
20:08:31<Jedai>trofi: That's Float (or Double), nothing to do with *Natural
20:08:34<virus_>http://codepad.org/VDj7XBgA
20:09:08<Jedai>virus_: The "]" is incorrectly placed
20:09:30<deech>Hi all, is there a Distance class that determines the distance between two Enumerable things? So for instance if it were specializing on the alphabet, the distance between B and D would be 3.
20:09:40<virus_>When moving it at the end of the last entry it works fine - how is that so?
20:09:51<trofi>:t fromEnum
20:09:56<lambdabot>forall a. (Enum a) => a -> Int
20:09:59<Jedai>virus_: As it is in the first column it should be the start of a new top-level definition
20:10:04<EvilTerran>deech, you can do that with just Enum
20:10:30<skorpan>could someone help me figure this pretty easy SYB problem out? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5052#a5052
20:11:01<Jedai>virus_: You could also indent it a little and it would work too
20:11:10<EvilTerran>> (subtract `on` fromEnum) 'A' 'N' -- 13!
20:11:12<lambdabot> 13
20:12:08<EvilTerran>> let enumDistance from to = fromEnum to - fromEnum from in enumDistance 'a' 'n' -- deech: this is probably clearer
20:12:09<lambdabot> 13
20:12:14<Jedai>skorpan: I probably wouldn't use Syb there...
20:12:32<Jedai>skorpan: But I guess it's an exercise ?
20:12:45<skorpan>no, i've just forgotten all i ever knew about SYB :)
20:12:52<skorpan>i actually need this now
20:12:55<EvilTerran>virus_, the general rule is, if you're spreading an expression across several lines, to make sure the second to last lines are *all* indented more than the first
20:13:22<skorpan>i'm writing a light-weight javascript verifier, which will make sure that there are no multiple function declarations in each block of the code
20:13:34<EvilTerran>virus_, although all lines but the first are usually at the same indentation level as each other
20:13:35<virus_>EvilTerran: ok. including the "]". I thought it'd work like python in this case - ignoring the indent until the ].
20:13:37<deech>EvilTerran: Thanks. I have used this, but it seems like such common operation that there would be a class for it.
20:14:22<EvilTerran>deech, well, as you see, you don't really need a separate class for it. it might make sense for it to be in Data.Enum, though
20:14:59<EvilTerran>deech, now i think about it, there's similar functionality in Data.Index, though
20:15:01<EvilTerran>?src Ix
20:15:01<lambdabot>class (Ord a) => Ix a where
20:15:01<lambdabot> range :: (a,a) -> [a]
20:15:01<lambdabot> index :: (a,a) -> a -> Int
20:15:01<lambdabot> inRange :: (a,a) -> a -> Bool
20:15:01<lambdabot> rangeSize :: (a,a) -> Int
20:15:03<deech>EvilTerran: Yes that is what I meant. Thought, words, disconnect. Why I laugh?
20:15:36<EvilTerran>> rangeSize ('a','n')
20:15:36<deech>EvilTerran: Cool, never looked at Ix.
20:15:38<lambdabot> 14
20:15:58<EvilTerran>> rangeSize ('a','a') -- this is off-by-one from the enumDistance though, in the Char case
20:16:00<lambdabot> 1
20:16:12<Cale>skorpan: Must it use Data.Generics?
20:16:19<Cale>skorpan: A simple list comprehension would be simpler.
20:16:37<skorpan>Cale: i suppose
20:16:39<Cale>[Bike b | Bike b <- xs]
20:17:09<Jedai>[ b | b@(Bike _) <- xs ]
20:17:21<EvilTerran>deech, Ix is usually used for things like array indices, so it acts differently in some ways to Enum
20:17:57<deech>EvilTerran : Will have to take a closer look at Ix. Thanks!
20:18:28<EvilTerran>> range ((0,0) , (1,1)) -- range :: Enum a => (a,a) -> [a]; all the indices that would be in an array starting at (0,0) and finishing at (1,1), ie, a 2-dimensional array
20:18:30<lambdabot> [(0,0),(0,1),(1,0),(1,1)]
20:18:36<Jedai>EvilTerran: I'm not sure if that's the case on the classic Enum types (though of course Ord and Ix don't always accord on "inRange")
20:19:18<EvilTerran>Jedai, well, each is defined for some types the other isn't defined for, iirc
20:19:43<Jedai>EvilTerran: Right :) (though Ix could be defined for every Enum type)
20:19:50<EvilTerran>Enum doesn't do tuples, and Ix doesn't do Float/Double (although arguably Enum shouldn't either)
20:19:59<skorpan>i just realized why i want generics in this case... i'm using BList, a zipperish data structure. so, back to my question, how would i do it? :)
20:20:48<Jedai>EvilTerran: Enum really shouldn't do Float/Double
20:20:54<Jedai>:(
20:21:58<EvilTerran>it does seem at odds with the semantics for other Enum instances
20:23:05<EvilTerran>> [0 :: Data.Fixed.Fixed E6 ..]
20:23:07<lambdabot> [0.000000,0.000001,0.000002,0.000003,0.000004,0.000005,0.000006,0.000007,0....
20:23:40<Cale>maybe something like: concat $ gmapQ (mkQ [] (\v -> case v of b@(Bike {}) -> [b]; _ -> [])) myStruct
20:23:45<EvilTerran>> [0 :: Float ..] -- yeah, these two make sense when compared
20:23:47<lambdabot> [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0...
20:23:52<Cale>I don't really know Data.Generics all that well
20:25:06<Cale>skorpan: Where is BList defined?
20:25:30<skorpan>Cale: it's a Yi thing
20:25:40<skorpan>Yi.Syntax.BList
20:25:44<skorpan>data BList a = One [a] | Two ([a] -> [a]) [a]
20:25:54<skorpan>i'm currently writing a bListToList function...
20:26:18<Cale>Interesting.
20:26:19<amgarchIn9>"Conflicting definitions for `q' in case alternative": How can I match duplicates in a list: q:q:qs ???
20:26:42<Zao>a:a':as | a == a' = ...
20:26:46<EvilTerran>amgarchIn9, give them different names, and use a guard on the pattern
20:26:47<Cale>p:q:qs | p == q -> ...
20:28:46<EvilTerran>"Welcome to #haskell, where your questions are answered in contrapuntal fugue."
20:29:37<Cale>skorpan: Isn't that as simple as toList (One r) = r; toList (Two l r) = reverse (l []) ++ r
20:29:38<Cale>?
20:29:45<Cale>ACTION doesn't see why it needs generics...
20:30:20<Cale>Oh, it's already a Foldable even...
20:30:40<Cale>:t Data.Foldable.toList
20:30:41<lambdabot>forall (t :: * -> *) a. (Data.Foldable.Foldable t) => t a -> [a]
20:32:14<hydo>"Cannot find module X.X it was found in multiple packages" ugh
20:33:15<gwern>I'm having a brainfart. BSD license requires attribution?
20:33:39<mauke>depends on which BSD license you mean
20:34:06<c_wraith>that's the main (only?) difference between the two main variants.
20:34:53<gwern>thought bsd3 removed the advertising clause, but one still had to attirubte in the metadata
20:35:14<mauke>oh, hm
20:35:27<amgarchIn9>is hpaste dead for you?
20:36:08<mauke>no
20:36:31<skorpan>Cale: thanks for reminding me of Data.Foldable.toList :)
20:39:32<amgarchIn9>how would you pull out a full square out of sqrt(Integer)? Any simpler way than this? -> http://haskell.pastebin.com/mf4fb0f1
20:40:40<roconnor>heh, the famous prime / isPrime circle.
20:40:51<SubStack>amgarchIn9: do you really need primes to do that?
20:42:33<roconnor>amgarchIn9: I suspect there is a better way, but I don't know of one.
20:55:02<hydo>Clean install of 6.10.3 and cabal-install... first package I tried to install is HStringTemplate and I'm getting http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2450#a2450 I'm assuming this is one of those "oh, yea, you need to X"
20:57:07<hydo>ah, ha! -fsyb-with-class
21:00:33<mightybyte>Anyone know why I'm getting an error in this code? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5056
21:00:48<hydo>Ok, does anyone know what I'm doing wrong? Compiling HStringTemplate, cabal configure -fsyb-with-class (since it won't build for me without it) , cabal build then cabal install rebuilds the library, of course without -fsyb-with-class. So I can build it, but I can't install it? Any of you know what I'm doing wrong?
21:01:05<byorgey>@seen ivanm
21:01:06<lambdabot>I saw ivanm leaving #gentoo-haskell, #xmonad and #haskell 6h 23m 19s ago, and .
21:01:30<Saizan_>hydo: cabal install --only
21:02:15<hatds>mightbyte: you have to call the function at (Foo ns) and (Bar ss)
21:02:31<hydo>Saizan_: is that a hidden option? I don't see any reference to it in 'cabal help install'?
21:02:40<hydo>s/?$//
21:03:06<Saizan_>hydo: yes it is
21:03:18<amgarchIn9>roconnor: one better way here: http://haskell.pastebin.com/m4a1b56b3 , I see some timing difference for sqrt23 $ factorial 100
21:03:27<Saizan_>hydo: you can also pass flags like -fsyb-with-class to install directly
21:03:40<Saizan_>hydo: instead of configuring separately
21:03:53<hydo>Saizan_: okie dokie. I'll remember that then. It's the magic make-it-work bit.
21:04:00<mightybyte>hatds: Why? What I want is gen :: Show a => ([a] -> String) -> MyData -> String
21:04:11<hydo>Saizan_: I tried that and it didn't work... still got the 'found in multiple packages' error.
21:04:54<hydo>Saizan_: doesn't matter actually... on to the next issue... :O
21:05:01<hydo>err.. :P rather
21:05:06<Saizan_>hydo: the problem is that HStringTemplate doesn't depend on base >= 4
21:05:33<hatds>mightybyte: ah I misread
21:06:35<yaxu>should the haskell platform work with ghc 6.10.3? I'm getting "configure: error: The core package editline-0.2.1.0 is missing. It should have been distributed with 6.10.2"
21:07:13<mightybyte>hatds: I've tried it with and without that type signature. Both fail, but they give slightly different errors.
21:09:33<hatds>mightybyte: gen :: (forall a. [a] -> String) -> MyData -> String you need to enable though RankNTypes
21:09:58<hatds>you can put {-# LANGUAGE RankNTypes #-} on the top of your file
21:10:27<hatds>I think you'll have trouble constructing such a function though :)
21:11:01<mightybyte>hatds: Ahh, that works.
21:11:17<mightybyte>hatds: Oh, I have an application for that pattern.
21:13:45<hatds>mightybyte: I think what you are trying to accomplish can only be done by making your own show class or using the existing one, you can say you want a function that will work for any "Show-like" class
21:13:55<hatds>*can't say
21:14:58<mightybyte>hatds: And make MyData an instance of that class?
21:15:13<hatds>mightybyte: yea
21:16:07<hatds>either that or settle for the type signature gen :: (MyData -> String) -> MyData -> String
21:16:32<mightybyte>hatds: I don't want to use that type signature because gen is complex and I'm trying to reuse it.
21:17:14<hatds>for other types besides MyData or for other show-like functions?
21:17:16<mightybyte>hatds: ...allowing different behaviors by letting the caller pass in their choice of listFunc.
21:17:22<mightybyte>Both
21:17:53<leimy>anyone here a fan of Timber?
21:18:13<skorpan>i know pejo is
21:18:27<mightybyte>A more complex data type instead of MyData and Text.XHtml.Strict.HTML instead of Show.
21:18:45<leimy>@users
21:18:46<lambdabot>Maximum users seen in #haskell: 658, currently: 614 (93.3%), active: 14 (2.3%)
21:19:04<pejo>leimy, ohoy!
21:19:09<hatds>mightybyte: gen itself will have to be overloaded if you want to generalize for other types besides MyData: as it stands gen contains patterns like "Foo ns", which forces the second argument to be "MyData"
21:19:10<mightybyte>Does forall allow you to include type class restrictions?
21:19:24<hatds>yes
21:19:30<leimy>pejo: Just looking at timber :-)
21:19:39<leimy>looks intriguing
21:19:48<mightybyte>hatds: Oh, not for multiple types. Just for one, more complex, MyData.
21:20:12<pejo>leimy, great! Let me know what you find out!
21:22:38<monochrom>f :: (forall a. Ord a => a -> a > Bool) -> Int -> Bool is an example of using forall and typeclass restriction.
21:22:45<leimy>pejo: I'm wondering when the latest Timber compiler might show up on hackage :-)
21:23:09<mightybyte>hatds: Excellent. gen :: (forall a. Show a => [a] -> String) -> MyData -> String solved my problem
21:23:22<mightybyte>monochrom: Thanks
21:24:09<mightybyte>hatds: That works perfectly. Thank you.
21:24:10<pejo>leimy, hackage doesn't allow me to upload, it just hangs. There's a tar.gz on the homepage though, which is the same file as the one that should be on hackage.
21:24:32<leimy>pejo: I see. I've never been sure how things get updated there.
21:24:57<leimy>pejo: do timber programs have an extension that's used often?
21:25:02<monochrom>It downloads from the future. :)
21:25:04<leimy>like ".timber"?
21:25:06<pejo>leimy, if you download that file and unpack it and cd into the directory you can run "cabal install" from there and it will act almost as if you had cabal install'd directly from hackage.
21:25:20<leimy>pejo: that's ok, I just installed the older one :-)
21:26:21<pejo>leimy, the file extension used so far is .t. If you bump into problems with 1.0.2: try to update to 1.0.3, it has an awful lot of small bugfixes all over the place.
21:26:29<leimy>ok
21:26:32<leimy>fair enough :-)
21:27:32<pejo>dcoutts, any idea why hackage just hangs for me? :-)
21:28:03<dcoutts>pejo: nope, does it look like it's up?
21:28:08<augustss_>yo!
21:28:49<dcoutts>hia augustss_
21:29:06<leimy>Weird.. I did "cabal install timberc" and it got stuck on happy
21:29:12<leimy>but then I manually said "cabal install happy"
21:29:17<leimy>and then "cabal install timberc"
21:29:19<leimy>and it was good
21:29:27<dcoutts>leimy: it doesn't yet track deps on tools, only on libs
21:29:30<leimy>isn't cabal install supposed to do all the dependencies for me?
21:29:36<leimy>ok that explains it.
21:29:43<pejo>dcoutts, just because I asked it worked now. Sorry.
21:29:52<dcoutts>pejo: :-)
21:29:54<monochrom>Proof by transitivity is hard. :)
21:31:56<pejo>leimy, ok, it's on hackage now.
21:32:24<leimy>pejo: awesome!
21:33:50<leimy>pejo: how portable is the C that is generated by timberc?
21:34:00<leimy>meaning, do I need to port a bunch of runtime to make stuff run elsewhere?
21:35:58<pejo>leimy, it's not 64-bit clean at the moment I think. A 32-bit posix-like platform should be ok though.
21:36:12<leimy>but just libTimber.a ?
21:41:20<pejo>leimy, if you run "timberc -v --make File" you will see what flags it is passing to gcc, and what files it is including. I apparently broke my local verison.
21:41:32<leimy>ah ok :-)
21:44:29<pejo>leimy, (libTimber.a is the standard library (Prelude) and some parts of the RTS though).
21:46:20<mreh>does lambda calculus relate in any way to the calculus of infintessimals
21:46:24<mreh>aka calculus
21:52:18<DrSyzygy>> sum . (1.0/) $ [51..100]
21:52:19<lambdabot> No instance for (Fractional [a])
21:52:19<lambdabot> arising from the literal `1.0' ...
21:52:43<DrSyzygy>> sum . ((1::Float(/) $ [51..100]
21:52:44<lambdabot> <no location info>: parse error on input `..'
21:52:53<Jedai>> sum . map (1.0/) $ [51..100]
21:52:53<DrSyzygy>> sum . ((1::Float)/) $ [51..100]
21:52:55<lambdabot> Couldn't match expected type `[a]' against inferred type `Float'
21:52:55<lambdabot> 0.6881721793101949
21:53:04<DrSyzygy>Jedai: Thanks. I seem to be stupid tonight.
21:53:23<Jedai>DrSyzygy: We all have this kind of moment.. ^^
21:53:26<centrinia>What is calculus anyway?
21:53:30<yaxu>ACTION finds installing haskell a bit frustrating
21:53:38<DrSyzygy>centrinia: I'll show you in a sec.
21:53:41<Jedai>yaxu: On what OS ?
21:53:51<DrSyzygy>Actually ..... http://michiexile.livejournal.com/193692.html
21:53:51<yaxu>ubuntu
21:53:58<DrSyzygy>Check it out before I update it to get the puzzle.
21:54:09<yaxu>the haskell wiki points me at the ubuntu packages, which are out of date
21:54:20<yaxu>so I download the latest binary and that's incompatible with the haskell platform
21:54:25<DrSyzygy>Yo yaxu!
21:54:30<yaxu>hey DrSyzygy
21:54:37<yaxu>congratulations on your Dr :)
21:54:41<Jedai>yaxu: What's incompatible ?
21:54:44<DrSyzygy>Thanks! :-)
21:54:57<yaxu>from earlier: should the haskell platform work with ghc 6.10.3? I'm getting "configure: error: The core package editline-0.2.1.0 is missing. It should have been distributed with 6.10.2"
21:55:38<yaxu>ACTION tries installing that from hackage
21:56:06<Jedai>yaxu: Arf... just edit a little bit the .cabal, editline isn't with 6.10.3 (it use haskeline instead and good riddance)
21:56:23<yaxu>Jedai: ah ok, thanks!
21:57:16<Jedai>yaxu: Don't try to install editline, it was a substitute for readline (chosen for license reason) but it's not very good, instead 6.10.3 use haskeline for ghci, which is a pure haskell library
21:58:48<monochrom>mreh: No, lambda calculus and Newton/Leibniz's calculus are unrelated. The common word "calculus" means very broadly "a method of calculation", which doesn't say anything.
21:59:20<centrinia>Oh.
21:59:40<monadic_kid>nor is predicate calculus
21:59:43<yaxu>Jedai: ok I deleted it from the cabal file, looks happier now
21:59:46<monochrom>lambda calculus is "a method of calculation" because it comes with rules like beta reduction for you to simplify expressions.
22:00:29<centrinia>I thought calculi all involved transformations of sequences of symbols.
22:00:43<monochrom>Newton/Leibniz's calculus is "a method of calculation" because it comes with rules like the product rule and integration by parts to simplify derivatives and integrals.
22:01:05<centrinia>Analytic Calculus. ;)
22:01:09<monochrom>Yes, calculation means playing with symbols.
22:01:54<centrinia>Is there a predicate algebra and a lambda algebra?
22:01:54<monochrom>Note how the rules of integration are playing symbols instead of thinking "how to do this with Riemann sums".
22:02:13<gwern>I sometimes wonder why we can't do total FP in haskell; surely someone has written a compiler or dsl or something? but I don't see anything on hackage
22:02:34<Twey>‘Total FP’?
22:02:49<centrinia>ACTION has read about some variants of Haskell that have no partial functions.
22:02:57<monadic_kid>Twey: living without general recursion
22:03:00<Cale>Twey: functional programming with no _|_
22:03:06<Twey>Oh right
22:03:08<Twey>O.O
22:03:13<Twey>Is that Turing-complete?
22:03:17<gwern>Twey: nope
22:03:19<monadic_kid>Twey: nope
22:03:19<Cale>Necessarily not.
22:03:21<Twey>Aha
22:03:23<Twey>I thought as much.
22:03:24<centrinia>Bottomless functional programming. :)
22:03:29<Twey>Heh
22:03:34<Cale>But it's surprising how much it's possible to express.
22:04:05<gwern>and while it isn't too bad in some ways, some parts of it scare me. like some of his comments
22:04:08<gwern>' This is sometimes quite hard
22:04:10<monochrom>Yes, from any calculus you can get an algebra. A calculus has rules that say "if you see X, reduce it to Y and hopefully it helps". To get an algebra, just assert the corresponding axiom X=Y and don't bias towards either direction.
22:04:10<gwern>- for example rewriting the well known sieve of Eratosthenes program in this
22:04:14<gwern>discipline involves coding in some bound on the distance from one prime to the
22:04:17<gwern>next.
22:05:03<Base>Hey
22:05:06<monadic_kid>strict dependant types require total functions i think i read somewhere before
22:05:15<Base>Can someone help me out with something
22:05:20<Cale>gwern: Of course. If you think about it, where is the knowledge encoded in the sieve program that there will indeed be another prime? If there were only finitely many primes, it would just run forever, which total functional programs are not allowed to do.
22:05:31<centrinia>Wait, reductions in calculi are invertible?
22:05:45<byorgey>Base: don't ask to ask, just ask =)
22:05:45<lambdabot>byorgey: You have 1 new message. '/msg lambdabot @messages' to read it.
22:05:48<gwern>Cale: why does it need to know that? of course there will be another prime
22:06:01<Base>oh okay byorgey :)
22:06:02<Base>Define a function partition that takes an integer k and a list and returns the list
22:06:02<Base>partitioned into sublists of length k (the last sublist could be of length less than k), e.g.,
22:06:02<Base>partition 3 [1,2,3,4,5,6,7,8] ->[[1,2,3],[4,5,6],[7,8]].
22:06:13<monochrom>That's not what I said.
22:06:17<Cale>"Calculus" isn't a well-defined term. It just means "Means of calculation", which is sufficiently abstract to refer to a lot of things. Trying to pin it down more than that is folly.
22:06:23<byorgey>Base: is this a homework question?
22:06:35<Twey>Cale: Seems a bit poorly-considered to me
22:06:36<Base>Part of a huge one
22:06:45<Base>I'm stuck at this and one other
22:06:47<Cale>Base: you know about take and drop right?
22:06:54<byorgey>Base: well, what have you tried so far? we are happy to help but we won't do your homework for you.
22:06:55<Twey>An algorithm can be O(1) with an infinite constant, on a really poorly-designed system.
22:07:02<Twey>Termination is an implementation detail.
22:07:06<monochrom>I said from a calculus to an algebra you use =. I did not say you do that to the calculus.
22:07:11<Base>Yeah I don't want you to do my homework for me
22:07:13<Botje>Twey: every algorithm is O(1), just set n = 1 :o)
22:07:17<centrinia>> let takeEvery n [] = []; takeEvery n (x:xs) = x:takeEvery (drop (n-1) xs) in takeEvery 2 [0..]
22:07:18<lambdabot> Couldn't match expected type `[t]' against inferred type `Int'
22:07:25<Twey>Botje: *laughs*
22:07:26<centrinia>> let takeEvery n [] = []; takeEvery n (x:xs) = x:takeEvery n (drop (n-1) xs) in takeEvery 2 [0..]
22:07:27<Cale>Base: The way I would do it involves the following functions: take, drop, iterate, map, takeWhile
22:07:28<lambdabot> [0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,5...
22:07:34<byorgey>Base: you can paste what you have so far at hpaste.org
22:07:41<Twey>I mean it can not recurse :-P
22:07:45<DrSyzygy>:t iterate
22:07:46<lambdabot>forall a. (a -> a) -> a -> [a]
22:07:48<gwern>@hoogle splitAt
22:07:49<lambdabot>Prelude splitAt :: Int -> [a] -> ([a], [a])
22:07:49<lambdabot>Data.ByteString splitAt :: Int -> ByteString -> (ByteString, ByteString)
22:07:49<lambdabot>Data.List splitAt :: Int -> [a] -> ([a], [a])
22:08:08<monadic_kid>Twey: you can have structural recursion in total program, just not general
22:08:09<Cale>Base: oh, and not, null
22:08:17<monochrom>Axioms in an algebra are intended to be invertible. Rules in a calculus come with directions because usually only one direction gets you closer to the answer.
22:08:30<Base>Cale I see
22:08:43<Base>I'm more object oriented than function oriented
22:08:53<Base>I tried to take length of string
22:08:57<gwern>> let part n as = let s = splitAt n as in (fst s) : part (snd s) in part 3 [1..10]
22:08:57<Base>and work on that
22:08:58<lambdabot> Couldn't match expected type `[a]' against inferred type `Int'
22:09:00<Base>using splitat
22:09:04<centrinia>monochrom, the calculi are more general than the algebras?
22:09:07<Base>but it was too messy :\
22:09:08<gwern>> let part n as = let s = splitAt n as in (fst s) : part n (snd s) in part 3 [1..10]
22:09:09<lambdabot> [[1,2,3],[4,5,6],[7,8,9],[10],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],...
22:09:18<gwern>hm, that's not quite right :)
22:09:26<byorgey>that's a good start though =)
22:09:28<Cale>Base: It's also possible to write something recursive with splitAt, but it should not be necessary to use length
22:09:33<Twey>monadic_kid: But you don't need any recursion at all for a program to fail to terminate.
22:09:40<gwern>byorgey: kind of hard to write pattern-matching in lb!
22:09:43<centrinia>> let part n as = map (take n) (iterate (drop n) as) in part 3 [1..]
22:09:44<lambdabot> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18],[19,20,21],[22,23...
22:09:49<centrinia>> let part n as = map (take n) (iterate (drop n) as) in part 3 [1..10]
22:09:50<lambdabot> [[1,2,3],[4,5,6],[7,8,9],[10],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],...
22:09:53<DrSyzygy>> let part n as = let s = splitAt n as in (fst s) : part n (snd s) in takeWhile (not . null) 3 [1..10]
22:09:54<lambdabot> Couldn't match expected type `[t1] -> t'
22:10:00<DrSyzygy>Pbtbtbtbt
22:10:03<DrSyzygy>:t takeWhile
22:10:04<lambdabot>forall a. (a -> Bool) -> [a] -> [a]
22:10:10<DrSyzygy>:t not . null
22:10:11<lambdabot>forall a. [a] -> Bool
22:10:11<gwern>personally, I like the concreteness of using 'splitAt', although the tuple parsing is too bad
22:10:17<centrinia>> let part n as = takeWhile (not . null) $ map (take n) (iterate (drop n) as) in part 3 [1..10]
22:10:19<lambdabot> [[1,2,3],[4,5,6],[7,8,9],[10]]
22:10:24<gwern>@hoogle Int -> [a] -> [[a]]
22:10:24<lambdabot>Control.Monad replicateM :: Monad m => Int -> m a -> m [a]
22:10:24<lambdabot>Prelude drop :: Int -> [a] -> [a]
22:10:24<lambdabot>Prelude take :: Int -> [a] -> [a]
22:10:37<Cale>Well, since centrinia has already given it away...
22:10:41<monochrom>I feel that I am trolled. I am asked questions that are already answered. I say "P is true" and I am asked "so P is false?"
22:10:45<centrinia>Oops. :(
22:10:50<gwern>(hm. I wonder how one could do it with replicateM?)
22:10:58<Cale>part n = map (take n) . takeWhile (not . null) . iterate (drop n)
22:11:29<blackh>Base: Yes we do do your homework for you. I hope functional programming gets you interested. I have been doing OO programming for years and I would never go back to it by choice after learning FP.
22:11:38<gwern>@quote homework
22:11:39<lambdabot>vincenz says: sure, give us your homework and we'll email it straight to your teacher :)
22:11:56<gwern>Welcome to #haskell, where your homework questions are answered in majestic stereo!
22:11:58<Base>blackh are you serious?
22:12:01<_JFT_>blackh: 100% with you on this one
22:12:04<DrSyzygy>*snerk*
22:12:13<blackh>Base: Yes, very serious.
22:12:20<Cale>Me too.
22:12:33<DrSyzygy>The "We won't do your homework" attitude gets kinda undermined by the tendency for people to start games of code golf in here. :-P
22:12:54<DrSyzygy>ACTION is sad that the original majestic stereo quote got removed from the lambdabot...
22:13:05<gwern>@quote stereo
22:13:06<lambdabot>LoganCapaldo says: * LoganCapaldo must resist urge to mention stereo
22:13:09<Cale>Basically, the policy should be "you should be careful not to ask your homework questions because we will do them for you and you will fail the exam"
22:13:11<gwern>heh
22:13:13<gwern>@quote stereo
22:13:14<lambdabot>omnId says: geez, how many metastereo quotes are going to be @remembered? >_>
22:13:16<DrSyzygy>@quote majestic
22:13:16<lambdabot>No quotes match. Maybe if you used more than just two fingers...
22:13:36<blackh>Base: When I was a student years ago FP wasn't very advanced. A FP book sat on my shelf for 20 years and collected dust. My life would have been greatly improved if I had taken an interest in it earlier!
22:13:37<gwern>remember Cale Welcome to #haskell, where your questions are answered in majestic stereo!
22:13:43<gwern>er.
22:13:48<gwern>@remember Cale Welcome to #haskell, where your questions are answered in majestic stereo!
22:13:48<lambdabot>Okay.
22:13:57<Cale>I believe I deleted that one on purpose.
22:14:01<DrSyzygy>Woot!
22:14:04<DrSyzygy>Awwwwww.
22:14:10<gwern>Cale: it was too good to leave dead
22:14:13<gwern>like sherlock holmes
22:14:29<centrinia>Cale, why did you delete it?
22:14:42<Cale>centrinia: Because it highlights me whenever someone uses it.
22:14:58<gwern>welcome to #haskell, where your crimes are deduced by glorious zombies!
22:14:59<Base>blackh I think ummm web applications are more into oo
22:15:10<DrSyzygy>Cale: Would having the quote without attribution make you happier?
22:15:13<Cale>yes :)
22:15:21<gwern>@forget Cale Welcome to #haskell, where your questions are answered in majestic stereo!
22:15:22<lambdabot>Done.
22:15:37<DrSyzygy>Hey - we could attribtue to Ca1e
22:15:38<gwern>@remember Anonycale Welcome to #haskell, where your questions are answered in majestic stereo!
22:15:38<lambdabot>I will remember.
22:15:39<blackh>Base: I've written 20,000 lines of web app in Haskell. It is far better than any of the dozens on web apps I've written in OO languages.
22:15:43<DrSyzygy>Or that works.
22:15:52<DrSyzygy>Does it?
22:15:52<Cale>@quote stereo
22:15:52<lambdabot>greeting says: Welcome to #haskell where your questions are answered in glorious stereo!
22:15:56<Cale>@quote majestic
22:15:56<lambdabot>Anonycale says: Welcome to #haskell, where your questions are answered in majestic stereo!
22:16:00<Cale>yeah, that's okay
22:16:04<gwern>what, what?
22:16:07<copumpkin>lol
22:16:10<gwern>which was it, glorious or majestic?
22:16:11<DrSyzygy>Hehehe
22:16:17<Cale>majestic
22:16:28<leimy>@quote stereo
22:16:29<lambdabot>greeting says: Welcome to #haskell where your questions are answered in glorious stereo!
22:16:39<leimy>@quote homework
22:16:40<lambdabot>dons says: [In reference to <joelr1> did you guys know that #ocaml has 37 members and #erlang has 34 vs. 202 on #haskell?] I think part of the #haskell success comes from the approach that we all
22:16:40<lambdabot>know each other, it's not a homework channel like #java. We created a community of peers, working on the overall goals of the community. That's why people keep coming back
22:16:42<Cale>@forget greeting Welcome to #haskell where your questions are answered in glorious stereo!
22:16:42<lambdabot>Done.
22:16:42<gwern>Cale: then away it goes
22:16:46<Cale>@flush
22:16:59<Base>blackh can you show me some web apps developed in haskell
22:17:04<gwern>Cale: incidentally, you push any state/ updates to darcs lb lately?
22:17:13<gwern>Base: well, gitit is a nice haskell webapp
22:17:18<gwern>(I like it alot)
22:17:20<Apocalisp>Haskell Web Toolkit looks promising.
22:17:27<Cale>gwern: I haven't. I've basically let lambdabot run itself for the last several months.
22:17:39<gwern>Cale: ah. well at some point you should
22:17:45<blackh>Base: Haskell is not as well supported with libraries as something like Python or PHP, but the web app support is pretty good. The huge advantage is the language itself.
22:17:50<Cale>It's somewhat surprising that it's still running :)
22:17:52<gwern>maybe schedule it for once a month; I noticed we've been losing HWN quotes
22:18:10<Elly>HWN?
22:18:18<centrinia>@google HWN
22:18:19<lambdabot>http://www.hwn.org/
22:18:19<lambdabot>Title: The Hurricane Watch Net
22:18:30<DrSyzygy>Haskell Weekly News
22:18:31<blackh>Base: I can't show you any web apps because mine is commercial and I haven't used the popular Haskell frameworks, but take the suggestions of others.
22:18:36<Elly>oh, that :)
22:18:38<gwern>@where HWN
22:18:39<aavogt>@go hwn
22:18:39<lambdabot>http://sequence.complete.org/
22:18:40<lambdabot>http://www.hwn.org/
22:18:40<lambdabot>Title: The Hurricane Watch Net
22:18:50<gwern>aavogt: go is short for google
22:18:54<Cale>There are a bunch of interesting web libraries for Haskell, but web programming is something that only interests me abstractly.
22:18:57<aavogt>sure it is
22:19:14<aavogt>sounds reasonable, now that I think of it
22:19:30<gwern>google is closest in lb's edit distance setup
22:19:40<blackh>Base: Amazing things are possible with web applications in Haskell. Some of the widget libraries are truly ingenious in the way they abstract things, in ways that aren't possible in OO languages.
22:20:11<Base>blackh you really got me intrested o.O
22:20:17<blackh>Base: I'll give you a concrete example of something I did...
22:20:27<Base>I mean i did my intern in a software company
22:20:30<Cale>For example formlets :)
22:20:30<Base>purely OO
22:20:42<blackh>Base: Formlets - that's the word I was looking for.
22:20:49<Base>and they're implimenting umm share point atm i thinl, they were talking about it before
22:21:00<Base>blackh imma check that
22:21:04<hydo>I hope web programming in haskell gets more popular (ie. I could get a job doing it) because it sure is a lot of fun.
22:21:23<blackh>Base: Here's something I did just to illustrate the power of the language: I have a function called // which I use to output HTML, e.g.
22:21:35<zachk>do most of you guys use happs? or just handroll
22:21:51<hydo>I'm using Hack + happstack
22:21:55<Cale>I don't actually write web apps. ;)
22:22:02<blackh>Base: Really simple stuff, such as "<tr><td colspan=\"5\" style=\"width:" // text (show maxPhotoWidth) //
22:22:02<blackh> "px;padding-bottom:5px\">" // inMarkup "</td></tr>\n" (
22:22:02<blackh> photoTexts !! 0) //
22:22:06<gwern>zachk: gitit is based on happstack yeah
22:22:07<iago>uhm, someone argues that in haskell you can implement web apps easier than in tapestry for example?
22:22:18<hydo>usually happstack by itself, but I've been playing with Hack for the past couple of days.
22:22:24<amgarchIn9> polynom' = filter (\(m, c) -> c /= 0) $ map re' polynom
22:22:25<amgarchIn9> re' (m, (r,_)) = (m, r)
22:22:34<_JFT_>@go gitit
22:22:35<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gitit
22:22:35<lambdabot>Title: HackageDB: gitit-0.5.3
22:22:43<amgarchIn9>how would you map+filter in one shot^^^
22:22:47<hydo>iago: I would agree with that... mainly because I don't know java (tapestry is a java fw right?)
22:23:01<Cale>amgarchIn9: I suppose a comprehension is possible
22:23:08<blackh>Base: The ingenious bit is that // can store state and do other clever things. One thing I use this for is I store footnotes as I go along, and collect them up at the bottom of the page.
22:23:20<gwern>amgarchIn9: that doesn't really make sense; a filter is over a list, but a map deals with each item individually
22:23:46<Cale>polynom' = [(m,r) | (m,(r,_)) <- polynom, r /= 0]
22:23:47<gwern>amgarchIn9: you could have re' do something like return Nothing if c == 0, or something, but you would then still need to filter out the nothings
22:23:50<blackh>Base: There's even one bit where I collect footnotes from earlier in the page. I can do this because I evaluate it twice - once to store the footnotes, and one final time to generate the output.
22:24:05<_JFT_>amgarchIn9: might try to use concatMap
22:24:16<Base>blackh o.O
22:24:17<c_wraith>amgarchIn9: catMaybes is probably the closest thing to what you want to do
22:24:19<Base>that's sweet!
22:24:22<Cale>List comprehensions do have a purpose, you know :)
22:24:34<amgarchIn9>Cale: great!
22:24:43<gwern>Cale: yes, to make other languages envious
22:25:46<_JFT_>cale: silly of me but as much as I liked list comprehension when I started Haskell it is the one feature I rarely used and tend to forget about :P
22:25:46<blackh>Base: This is all done in a general way. Another thing I use it for is where I do some processing that requires a certain CGI field to be kept in all links, I just say .. // preserve "some_id" // .. and all forms/links on the page pick it up.
22:26:23<blackh>Base: The key concept is "composability".
22:26:47<blackh>Base: Composability is where Haskell really excels. It turns programming into lego in a way that OO only attempts to do.
22:27:07<blackh>Base: This is true of all FP languages, though, not just Haskell.
22:27:14<lament>that's why Haskell is such a tremendous success, and OO is failing so badly.
22:27:21<Cale>_JFT_: I've gone through the same thing. It's easy to forget they're there. Usually the urge to use concatMap makes me consider them now.
22:27:32<iago>hydo, yep, tapestry is java, but it's hard to do easier write a web app
22:27:49<gwern>blackh: composability benefits from purity & laziness, though
22:27:50<_JFT_>cale: Thank you for the tip! I never thought of their likelyness
22:28:06<Axman6>iago: ever tried google app engline?
22:28:10<Axman6>enging*
22:28:17<blackh>lament: If that's sarcasm I detect there, I just want to add that I have been at the coal face and OO has failed in many instances.
22:28:21<hydo>Axman6: engine? :)
22:28:22<mux>anyone using GHCi 6.10.3 here who could try a simple :run command ? it seems it always fail for me
22:28:24<Axman6>bah
22:28:27<Axman6>yes
22:28:30<hydo>hehe
22:28:36<Axman6>i just woke up
22:28:43<Axman6>well, i'm still waking up
22:28:47<Base[away]>blackh I should look more into it
22:28:56<_JFT_>mux: which command?
22:28:59<Axman6>and typing while eating breakfast
22:29:23<hydo>blackh: do you use happstack?
22:29:26<iago>Axman6, no
22:29:29<mux>_JFT_: :run
22:29:44<_JFT_>mux: with which arguments^
22:29:45<_JFT_>?
22:29:55<mux>whatever, on any program
22:30:06<blackh>hydo: No .. I've rolled my own. Partly because I don't like SQL and partly because the app is so big that I get the longer term benefit from the total control this approach gives me.
22:30:12<mux>if you experience the same bug it won't matter
22:30:32<mux>it just fails with: Couldn't find command in ""
22:30:33<Axman6>iago: well,m i managed to get a pretty decent blog up and running with it, in about three hours, without knowing anything about python or much about google app engine (only found out about it by going to a google tech talk)
22:30:35<_JFT_>mux: never used it give me one sec to see what I'm supposed to feed it :P
22:30:39<hydo>blackh: It wouldn't happen to be publicly viewable, would it? :)
22:30:55<mux>ACTION found the code source and starts looking for the bug
22:30:55<TomMD>mux: It works for me (GHC 6.10.3, x86_64, Linux)
22:31:05<blackh>hydo: Unfortunately no, but I'd be happy to talk to you about it and show you bits of it.
22:31:56<_JFT_>mux: it is working for me
22:31:59<blackh>hydo: I've thought about taking some of the good stuff I've developed and putting it out there. My forms/html generation have worked out brilliantly, but so as HappStack. Maybe I can contribute something, though.
22:31:59<iago>Axman6, well, if you do a blog in three hours I could expect something very specialized
22:32:10<mux>TomMD, _JFT_: ok, thanks
22:32:11<Axman6>eh?
22:32:22<_JFT_>mux: GHC 6.10.3, OS X 10.5
22:33:00<iago>perhaps I don't understand you well, I dunno
22:34:06<mux>now that's really weird
22:34:35<Axman6>iago: seriously, if you want to write highly scalable app, that use the same data store infrastructure google do, google app engine is well worth checking out
22:35:09<blackh>Axman6: Does your app require Google's say-so to run?
22:35:17<Axman6>nope
22:35:24<Axman6>just upload it and go
22:35:57<Axman6>you can even use google accounts for authentication (which is the default way of doing things)
22:36:03<blackh>Axman6: What I mean is, let's say Google got taken over by evil aliens, and they decided to shut down all Google app engine apps, would the owners of the apps be able to move them to their own servers?
22:36:41<Axman6>well, you do all the development on you local system, so sure
22:36:55<Boney>blackh: I agree with you, while this cloud stuff seems wonderful, and companies like google might make a 99.9% promise. I still don't have control.
22:37:08<Boney>if they break something and cause some regression, I can't patch their code.
22:37:19<Axman6>the data in the data store may be harder to get out, but i think it'd still be trivial
22:37:24<blackh>Axman6, Boney: That's good, then. I'm extremely wary of vendor lock-in. I don't mean to imply that all aliens are evil, by the way.
22:37:48<Boney>of course.
22:38:07<Boney>ACTION is one of those people that still runs his own mailserver.
22:38:11<Axman6>google have very strong feelings about API's so people can have control
22:38:56<Boney>Axman6: I havn't looked into it so I'm not authorative. I'll have to do some reading sometime.
22:40:01<Boney>Essentially my wife uses hotmail.com for her e-mail and complains when they change something (she often sees UI changes as regressions)> I use mutt and don't have this problem. This is my level of experience with "the cloud".
22:40:13<Boney>heh, I nearly typed "clod"
22:40:27<Twey>Haha
22:40:30<Twey>Clod computing
22:40:42<DrSyzygy>Boney: Not only running my own - but also providing my own and my wife's family with sensible mail services. :-P
22:40:43<Boney>"put it in the clod"
22:40:48<inimino>amateur postmasters unite!
22:40:59<Twey>It's the next wave of eco-friendly computer systems
22:41:00<Axman6>it's a really nice system though. you don't have to worry about setting up databased or anything, you just make a python class that has some 'properties' that the data store knows how to handle, and you just create not objects and run obj.put() and it's there
22:41:05<Boney>DrSyzygy: that's my intention, if Liz actually wanted to try it.
22:41:15<Axman6>you've also got access to their memcache stuff, which makes stuff about 10 times faster
22:41:23<Boney>maybe I"ll put some webmail thing on it so she feels comfortable :-)
22:41:40<DrSyzygy>Boney: Squirrelmail is surprisingly nice.
22:42:13<Axman6>ACTION got his Arduino board yesterday :D
22:42:14<Boney>Yep, I think I've used it once for something.
22:42:19<inimino>I really hate Squirrelmail actually
22:42:22<_JFT_>Dumb question but is there a hidden way to enter binary literals?
22:42:29<Boney>Axman6: sounds nice.
22:42:44<SamB>_JFT_: nope -- just use hex
22:43:03<DrSyzygy>inimino: I'm sure you have better tools though, don't you? You gotta think like, say, my mom. :-P
22:43:07<_JFT_>SamB: Thanks, that's what I've been doing
22:43:21<SamB>this isn't scheme, you know!
22:43:33<_JFT_>SamB: was hoping for some hidden way :P
22:43:34<SamB>that's like the one thing they even HAVE syntax for
22:43:52<inimino>DrSyzygy: I think Squirrelmail is not good for your Mom either, it's archaic and unfriendly
22:43:58<SamB>_JFT_: well, you *could* cheat and use Template Haskelll
22:44:01<SamB>er. Haskell
22:44:14<DrSyzygy>inimino: Any recommendations on better webmail packages?
22:44:30<_JFT_>SamB: Now that's an idea, I've never played with TH that should be quite simple for such a little task...
22:44:38<inimino>DrSyzygy: but then, Gmail isn't very Mom-friendly either, but not for the same reasons
22:45:20<inimino>DrSyzygy: unfortunately, no, unless you want to take a couple months and help me write one ;-)
22:45:34<DrSyzygy>inimino: WAY too many paper deadlines the next few months.
22:45:42<inimino>DrSyzygy: I think the state of FOSS webmail clients has been abysmal for a long time
22:45:50<zachk>foss?
22:45:54<inimino>DrSyzygy: yeah, I don't really have any time to do anything about it either
22:46:35<cads>ACTION misses you haskell guys in the clojure community
22:46:51<inimino>zachk: free/open-source software
22:47:14<lament>is there really no power function with non-integral exponents?
22:47:28<cads>lament, I think there's an exp function somewhere
22:47:29<DrSyzygy>lament: sqrt?
22:47:32<DrSyzygy>:-P
22:47:42<DrSyzygy>?ho exp
22:47:42<lambdabot>Maybe you meant: hoogle hoogle+ . ? @ bf echo ft ghc id pl rc show thx v wn yow
22:47:47<DrSyzygy>?hoogle exp
22:47:48<lambdabot>Prelude exp :: Floating a => a -> a
22:47:48<lambdabot>Language.Haskell.TH data Exp
22:47:48<lambdabot>Language.Haskell.TH.Syntax data Exp
22:47:49<lament>oh, there is
22:47:53<lament>it's called **
22:48:00<DrSyzygy>:t (**)
22:48:01<lambdabot>forall a. (Floating a) => a -> a -> a
22:48:09<DrSyzygy>> 3.5 ** 1.5
22:48:11<lambdabot> 6.547900426854397
22:48:18<cads>> (PI^PI)
22:48:20<lambdabot> Not in scope: data constructor `PI'Not in scope: data constructor `PI'
22:48:39<cads>oops
22:48:48<roconnor>> 3.5 ** 1.5 :: CReal
22:48:49<lambdabot> 6.547900426854397424771560281553961278073
22:49:17<cads>damn those creals are just uber
22:51:02<Axman6>> pi / (pi+1) :: CReal
22:51:03<lambdabot> 0.7585469929947761453444306890448928641384
22:51:10<Axman6>> pi / (pi-1) :: CReal
22:51:12<lambdabot> 1.4669422069242598599833948132336675731433
22:51:16<Axman6>> pi / (pi-3) :: CReal
22:51:17<lambdabot> 22.1875399177931373093790154577116741282029
22:51:56<_JFT_>CReal?
22:52:08<TomMD>Part of the FFI
22:52:14<TomMD>@hoogle CReal
22:52:14<lambdabot>No results found
22:52:16<copumpkin>CReal is part of numbers
22:52:16<Axman6>uh no
22:52:18<TomMD>damn you hoogle
22:52:21<copumpkin>you're thinking of CDouble
22:52:21<TomMD>oh, ok
22:52:26<TomMD>Right, right
22:52:34<_JFT_>@hoogle CDouble
22:52:35<lambdabot>Foreign.C.Types data CDouble
22:52:38<Axman6>they're arbitrary precision real numbers
22:52:48<Axman6>> showCReal 40 pi
22:52:50<lambdabot> "3.1415926535897932384626433832795028841972"
22:52:52<_JFT_>Axman6: which package provide CReal?
22:52:53<Axman6>> showCReal 60 pi
22:52:54<lambdabot> "3.141592653589793238462643383279502884197169399375105820974945"
22:53:02<copumpkin>numbers
22:53:04<Axman6>Data.Numbers i think
22:53:05<copumpkin>@hackage numbers
22:53:06<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers
22:53:07<Axman6>yeah
22:53:18<_JFT_>Axman6, copumpkin : Thank you!
22:53:22<copumpkin>:)
22:53:25<Axman6>they're very cool
22:53:58<roconnor>> deriv (\x -> cos x *exp x) x
22:53:59<lambdabot> 1 * negate (sin x) * exp x + cos x * (1 * exp x)
22:54:09<_JFT_>I love cabal-install!
22:54:22<Axman6>roconnor: what package is that from?
22:54:27<copumpkin>> deriv (\x -> cos (sin (exp x))) x
22:54:28<lambdabot> 1 * exp x * cos (exp x) * negate (sin (sin (exp x)))
22:54:33<roconnor>@hackage numbers
22:54:34<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numbers
22:54:41<roconnor>and simple reflect
22:54:48<Axman6>ACTION is happy that his TI calculator can do the same thing, and pretty print it
22:54:49<Axman6>ah ok, awesome
22:54:51<roconnor>but numbers has it's own reflect package that does the same.
22:54:58<roconnor>well, sameish
22:55:31<roconnor>the reflect in numbers is probably better than the reflect that lambdabot is using.
22:56:05<Axman6>ha, just replied to someone on twitter who wasn't following me, and now they are
22:57:21<roconnor>Axman6: the neat thing is that the deriv function and the simple reflection of expressions are developed totally independently!
22:57:34<Axman6>:t deriv (\x -> cos (sin (exp x))) ?x
22:57:35<lambdabot>forall a. (?x::a, Floating a) => a
22:57:58<Axman6>roconnor: shame i can't get it working in ghci :9
22:58:00<Axman6>:(*
22:58:20<roconnor>get what working?
22:59:34<Axman6>i've got Data.Number.Dif :m +'d, but it's whinging about x not being being in scope. guess i need to load something else, or make a new variable?
22:59:53<roconnor>you need to load the reflection module
22:59:57<copumpkin>that's simple-reflect
23:00:13<Axman6>ah, ok
23:00:26<roconnor>load up Data.Numbers.Symbolic
23:00:33<roconnor>let x = var "x"
23:00:34<Axman6>hmm, i have that too
23:00:36<Axman6>ah ok
23:00:52<Axman6>hooray :)
23:01:02<roconnor>the simple reflect package that lambdabot uses is different and already has a bunch of one letter variables defined.
23:01:11<Axman6>yeah
23:01:18<hydo>ack! Saizan: what was that magic make-it-work bit again? That conversation has scrolled out of the buffer.
23:01:23<roconnor>but you will find Data.Numbers.Symbolic makes nicer output
23:01:33<hydo>I thought it was -fonly but that's not working.
23:01:35<c_wraith>hydo: I think it was --only
23:01:36<Axman6>but, i can see it'd be a pain if x was defined whenever you loaded op simple reflect
23:01:48<roconnor>@src x
23:01:48<lambdabot>Source not found. Maybe you made a typo?
23:01:49<Axman6>ok, shower time
23:02:54<hydo>c_wraith: yep, that was it. Thanks!
23:11:28<roconnor>@free length
23:11:29<lambdabot>length = length . $map f
23:11:52<amckinley>easy question: is there a way to partially apply the arguments to a value constructor defined with record syntax?
23:12:30<kpreid>amckinley: yes, a value constructor can be used as a normal function
23:12:41<kpreid>you can't partially apply AND use names though
23:12:55<amckinley>kpreid: argh! thanks :)
23:18:34<amckinley>kpreid: so theres no way i could pass a half-initialized ADT between functions and set different pieces of the ADT using record syntax?
23:20:20<hatds>don't try to abuse record syntax :)
23:21:33<amckinley>hatds: :) any better ideas? im populating a kind-of complicated structure with the results of parsing a big ugly text file
23:22:45<roconnor>break your record into different pieces?
23:24:36<amckinley>roconnor: ive already broken it up a lot; i guess i could keep going :P
23:24:57<roconnor>amckinley: also see data.accessor, which is totally awesome.
23:27:06<amckinley>roconnor: oooh, thanks for that
23:27:35<roconnor>I'm told it really improved the nested records in the Chart's library.
23:32:07<kpreid>amckinley: you COULD pass a half-initialized ADT and use record update syntax later, that works fine
23:32:20<kpreid>you just have to avoid using any of the uninitialized fields since they are _|_
23:32:56<Philonous>@hoogle wait
23:32:56<lambdabot>System.Process waitForProcess :: ProcessHandle -> IO ExitCode
23:32:56<lambdabot>Control.Concurrent.QSem waitQSem :: QSem -> IO ()
23:32:56<lambdabot>Control.Concurrent.QSemN waitQSemN :: QSemN -> Int -> IO ()
23:33:12<roconnor>@hoogle delay
23:33:12<lambdabot>Control.Concurrent threadDelay :: Int -> IO ()
23:33:33<Philonous>Thanks
23:37:07<amckinley>hmmm... could i use fold to apply a bunch of args in a list to a half-initialized ADT?
23:37:55<roconnor>amckinley: you can sequence a list of data.accessor.sets .
23:39:15<roconnor>amckinley: http://hackage.haskell.org/packages/archive/data-accessor/0.2.0.2/doc/html/Data-Accessor-Basic.html#v%3Acompose
23:39:27<roconnor>``This is a general function, but it is especially useful for setting many values of different type at once.
23:39:38<amckinley>i guess i couldnt use fold, since the type of the half-initialized adt would change after every application
23:39:55<amckinley>roconnor: thanks again
23:40:03<roconnor>oh, if the types are changing after every update, then you are in trouble.
23:40:38<amckinley>well, its a partially applied function that id be using as the accumulator
23:40:50<amckinley>as in
23:40:59<amckinley>let s = BigAdt firstArg
23:41:22<amckinley>foldl (\t x -> t x) s [ arg2, arg3, etc]
23:44:30<roconnor>what's wrong with writing s arg2 arg3 ... ?
23:45:02<amckinley>because its more like 10 args
23:45:08<copumpkin>oh no, OccurAnal
23:45:10<amckinley>so i want to say something like
23:45:15<amckinley>nums <- many1 $ lexeme $ many1 digit
23:45:35<amckinley>and then peel off one element of nums at a time and apply it
23:46:40<roconnor>amckinley: that doesn't sound type safe as you describe it.
23:47:23<amckinley>roconnor: you're right
23:48:33<amckinley> explode s (x:xs) = s x . explode s xs
23:48:33<amckinley> explode s _ = s
23:48:41<amckinley>gives an infinite type error
23:48:46<roconnor>yes
23:48:53<roconnor>because it isn't type safe
23:49:19<roconnor>how do you know the list contains the correct number of arguments?
23:49:51<amckinley>i thought it wasnt type safe because the type of s will change after every application
23:50:33<roconnor>amckinley: well if it was type safe, it would require an infinite type.
23:50:38<amckinley>but i guess its also not type safe because you have no idea how many applications will actually happen :P
23:50:56<amckinley>roconnor: ok, i give up :) switching to data.accessor
23:51:07<roconnor>data.accessor is awesome
23:54:15<Nehal>import List; numerator (4 % 6) this reduces the ratio first and then returns 2, how do i get the numerator before it is reduced?
23:54:44<Nehal>uh, that should be import Ratio
23:55:51<Jedai>Nehal: You can't
23:55:52<roconnor>you cannot. The % function reduces the ratio.
23:55:59<Nehal>i see
23:56:39<Jedai>Nehal: There are good reasons to do this, it is better to normalize the representation as soon as possible, it avoids many problems and innefficiencies afterward
23:56:39<aavogt>:t Ratio
23:56:40<lambdabot>Not in scope: data constructor `Ratio'
23:57:22<Jedai>Nehal: if you want couple, just use couples
23:57:41<glguy>> fst (4,6)
23:57:43<lambdabot> 4
23:57:56<Nehal>ok
23:58:47<Jedai>Nehal: On the other hand, if you explain why you would like to do that, we may have smarter suggestions
23:59:50<Nehal>Jedai: it's for an assignment, i have to produce an infinite list of rational numbers between 0 and 1, no duplicates allowed... i somehow have to detect duplicates

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