[Haskell] An Alternative Data.List.Zipper
Hi, (I also sent this to libraries@, but without response; I'm posting here for a wider audience.) I'm somewhat of a beginner in Haskell, so take what I say with a grain of salt, please. The ListZipper implementation seems very odd to me, and #haskell seemed to agree with me. The current package implements a Zipper with data Zipper = Zipper ![a] ![a] which allows for empty zippers, among other things. Very strange to me. It also seems unnecessarily strict. There are also no expected typeclasses implemented, like Foldable or Traversable. I thought it would be interesting to try fixing these problems with a much cleaner design, and I'd like to share what I came up with: http://hpaste.org/14030 I'd very much appreciate some criticism of the code so that I can improve it. I'm not sure how best to provide this alternative on Hackage; should we make this merely a newer version of the old library, provide it in a conflicting package, or find a new namespace for it and provide it there? Thanks, Jeff Wheeler ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
This traverses the list three times (reverse, init and last are each linear time): fromListEnd xs = Zipper (reverse $ init xs) (last xs) [] But we only need to do it once: fromListEnd xs = let x:xs' = reverse xs in Zipper xs' x [] I don't *think* this has an effect on strictness/laziness, since both versions are strict in the spine of the list. --Max On Sat, Jan 17, 2009 at 10:33 AM, Jeff Wheeler j...@nokrev.com wrote: Hi, (I also sent this to libraries@, but without response; I'm posting here for a wider audience.) I'm somewhat of a beginner in Haskell, so take what I say with a grain of salt, please. The ListZipper implementation seems very odd to me, and #haskell seemed to agree with me. The current package implements a Zipper with data Zipper = Zipper ![a] ![a] which allows for empty zippers, among other things. Very strange to me. It also seems unnecessarily strict. There are also no expected typeclasses implemented, like Foldable or Traversable. I thought it would be interesting to try fixing these problems with a much cleaner design, and I'd like to share what I came up with: http://hpaste.org/14030 I'd very much appreciate some criticism of the code so that I can improve it. I'm not sure how best to provide this alternative on Hackage; should we make this merely a newer version of the old library, provide it in a conflicting package, or find a new namespace for it and provide it there? Thanks, Jeff Wheeler ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, 2009-01-17 at 10:44 -0800, Max Rabkin wrote: This traverses the list three times (reverse, init and last are each linear time): fromListEnd xs = Zipper (reverse $ init xs) (last xs) [] But we only need to do it once: fromListEnd xs = let x:xs' = reverse xs in Zipper xs' x [] I don't *think* this has an effect on strictness/laziness, since both versions are strict in the spine of the list. Excellent suggestion; your solution is much more readable and faster. I've made the change here: http://hpaste.org/14030#a1 Thanks, Jeff Wheeler ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, 2009-01-17 at 21:55 +0100, Jean-Philippe Bernardy wrote: I think it should admit empty, and the traversable instance should traverse the first list in reverse. I fixed the latter issue so that the behavior is correct (I think). I tested it like this: forM (next $ next $ fromList [1..5]) $ \i - do { print i; return i } 1 2 3 4 5 [1,2] 3 [4,5] which I believe is proper. I'm undecided about allowing them to be empty. I don't know the theory or math behind zippers (I'm sure there are some papers written about it), but it doesn't make much sense to be empty. I got that impression from #haskell, also. Thanks for the comments. :) Jeff Wheeler ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, Jan 17, 2009 at 4:32 PM, Jeff Wheeler j...@nokrev.com wrote: On Sat, 2009-01-17 at 21:55 +0100, Jean-Philippe Bernardy wrote: I think it should admit empty, and the traversable instance should traverse the first list in reverse. I fixed the latter issue so that the behavior is correct (I think). That's correct, but I think you'd be better off defining OpApplicative (or Backward, as I call it) locally and avoiding the two reverses. I'm undecided about allowing them to be empty. I don't know the theory or math behind zippers (I'm sure there are some papers written about it), but it doesn't make much sense to be empty. I got that impression from #haskell, also. If you look at a zipper as a list with a selected element, then it doesn't make sense to talk about a zipper of an empty list. That being said, I'd prefer fromList to have the type [a] - Maybe (Zipper a), and similarly with next and previous. If people want to live dangerously, they can use fromJust. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Re: [Haskell-cafe] ANNOUNCE: Coadjute 0.0.1, generic build tool
matti.niemenmaa+news: Announcing the release of Coadjute, version 0.0.1! Web site: http://iki.fi/matti.niemenmaa/coadjute/ Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coadjute Here's an Arch Linux package for it, http://aur.archlinux.org/packages.php?ID=23237 ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, 2009-01-17 at 17:41 -0500, David Menendez wrote: That's correct, but I think you'd be better off defining OpApplicative (or Backward, as I call it) locally and avoiding the two reverses. I'll have to look into this more; I don't really understand applicatives right now, so I can't use them yet. :) If you look at a zipper as a list with a selected element, then it doesn't make sense to talk about a zipper of an empty list. Apparently a zipper can be empty, as the focus is the rest of the list, not the current element. It seems that my file is not a Zipper, but rather a PointedList (thanks to roconner in #haskell). Therefore, I've changed my file to use the new name throughout, including a new module name. With this change, I think it's now appropriate to post on Hackage. That being said, I'd prefer fromList to have the type [a] - Maybe (Zipper a), and similarly with next and previous. If people want to live dangerously, they can use fromJust. I agree, and I've made this change. I found this annoying on next/previous though, so I've created a tryNext/tryPrevious that'll return an unchanged PointedList if it's already on the end. Here's the new version: http://hpaste.org/14030#a5 Thanks for the feedback, Jeff Wheeler ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, Jan 17, 2009 at 7:49 PM, Jeff Wheeler j...@nokrev.com wrote: On Sat, 2009-01-17 at 17:41 -0500, David Menendez wrote: That's correct, but I think you'd be better off defining OpApplicative (or Backward, as I call it) locally and avoiding the two reverses. I'll have to look into this more; I don't really understand applicatives right now, so I can't use them yet. :) newtype Backwards f a = B { unB :: f a } instance Functor f = Functor (Backwards f) where fmap f = B . fmap f . unB instance Applicative f = Applicative (Backwards f) where pure = B . pure f * x = B (unB f ** unB x) traverseBackwards :: (Traversable t, Applicative f) = (a - f b) - t a - t (f b) traverseBackwards f = unB . traverse (B . f) If you look at a zipper as a list with a selected element, then it doesn't make sense to talk about a zipper of an empty list. Apparently a zipper can be empty, as the focus is the rest of the list, not the current element. It seems that my file is not a Zipper, but rather a PointedList (thanks to roconner in #haskell). This may be terminological confusion. I would have said that a PointedList *is* a zipper. Certainly, from the standpoint that zippers are comonads, you can't have an empty zipper, because you always need to be able to retrieve the selected value. That being said, I'd prefer fromList to have the type [a] - Maybe (Zipper a), and similarly with next and previous. If people want to live dangerously, they can use fromJust. I agree, and I've made this change. I found this annoying on next/previous though, so I've created a tryNext/tryPrevious that'll return an unchanged PointedList if it's already on the end. I would define tryNext in terms of next, rather than the other way around, but I guess it shouldn't make much difference. I'm also not sure that returning the original pointed list is a good idea, since trying to move beyond the boundaries of the zipper will usually be an error. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] Re: Teach theory then Haskell as example
G'day all. Quoting Max Rabkin max.rab...@gmail.com: Good to have a recommendation -- my future CT lecturer has a hard time recommending anything not written by Mac Lane. One more suggestion: Conceptual Mathematics by Lawvere and Schanuel is the gentlest introduction that you're going to find. Cheers, Andrew Bromage ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, 17 Jan 2009, David Menendez wrote: instance Applicative f = Applicative (Backwards f) where pure = B . pure f * x = B (unB f ** unB x) probably should be f * x = B (unB x ** unB f) anyhow, this should be part of Control.Applicative. This may be terminological confusion. I would have said that a PointedList *is* a zipper. This is what I thought, and what how I initally advised Jeff. However after carefully reading both http://en.wikibooks.org/wiki/Haskell/Zippers and http://www.cs.nott.ac.uk/~ctm/Dissect.pdf (Clowns to the left of me, jokers to the right), it is clear that formally a zipper focuses on a sub-list / sub-tree rather than focusing on a particular node of a list or a tree. Hence zippers are not comonads. -- Russell O'Connor http://r6.ca/ ``All talk about `theft,''' the general counsel of the American Graphophone Company wrote, ``is the merest claptrap, for there exists no property in ideas musical, literary or artistic, except as defined by statute.'' ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] Hackage about to reach 1000 releases
Hackage is about to reach the 1000 release mark, 2 years after it went live. That's right: in 2 years we've gone from having only a handful of released projects, to one thousand! Well done everyone! I did some quick visualisation of the rate of new releses, diversity of packages, and community growth over the period: http://archhaskell.wordpress.com/2009/01/18/open-source-haskell-releases-and-growth/ I'm very happy about the diversity of hackage apps, and the pleasing rate of growth of new releases. None of this would have been possible with out thousands of hours of work from the Cabal and Hackage hackers, the compiler teams, and the developers themselves. Keep churning out new and intresting code everyone! -- Don P.S. cabal install ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell] HaskellWiki Update
There has been a lot of spam on HaskellWiki. Since anonymous edits have been switched off, a spammer tactic has been to create hundreds of accounts to evade individual account blocks. To combat this, I have 1. deleted all user accounts that have made no edits; 2. switched off account creation; 3. blocked at least some of the remaining spam accounts. This is obviously not ideal, as there is now no way for new users to edit the wiki. I will investigate appropriate ways to allow account creation. -- Ashley Yakeley ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell] An Alternative Data.List.Zipper
On Sat, Jan 17, 2009 at 9:13 PM, rocon...@theorem.ca wrote: On Sat, 17 Jan 2009, David Menendez wrote: instance Applicative f = Applicative (Backwards f) where pure = B . pure f * x = B (unB f ** unB x) probably should be f * x = B (unB x ** unB f) I always get that backwards. anyhow, this should be part of Control.Applicative. I agree. But until it is, we'll have to make do. This may be terminological confusion. I would have said that a PointedList *is* a zipper. This is what I thought, and what how I initally advised Jeff. However after carefully reading both http://en.wikibooks.org/wiki/Haskell/Zippers and http://www.cs.nott.ac.uk/~ctm/Dissect.pdf (Clowns to the left of me, jokers to the right), it is clear that formally a zipper focuses on a sub-list / sub-tree rather than focusing on a particular node of a list or a tree. Hence zippers are not comonads. Funny, I was just reading that paper earlier today. You're right. I wasn't making enough of a distinction between zippers and structures with one selected element. It's the latter which are comonads. -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[GHC] #2962: Fix space leak in genericLength
#2962: Fix space leak in genericLength -+-- Reporter: thorkilnaur | Owner: Type: bug | Status: new Priority: normal| Component: libraries/base Version: 6.11 | Severity: normal Keywords:| Testcase: Os: Unknown/Multiple | Architecture: Unknown/Multiple -+-- There is a space leak in {{{genericLength}}}: {{{ $ ghc/stage2-inplace/ghc --interactive GHCi, version 6.11.20090116: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude :module +List Prelude List genericLength [1..60] *** Exception: stack overflow Prelude List Prelude List length [1..60] 60 Prelude List }}} The attached patch against the base library provides a fix. Best regards Thorkil -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2962 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2951: Add support for amd64-solaris2 platform
#2951: Add support for amd64-solaris2 platform +--- Reporter: kgardas |Owner: simonmar Type: feature request | Status: new Priority: normal |Milestone: 6.12 branch Component: Compiler | Version: 6.10.1 Severity: normal | Resolution: Keywords: | Difficulty: Unknown Testcase: | Os: Solaris Architecture: x86_64 (amd64) | +--- Comment (by simonmar): I'm confused. `x86_64-pc-solaris2` is not a platform we currently support. I made the first step towards supporting this platform, namely to update `config.guess` to recognise the platform. Why then do you want to map the platform to `i386-pc-solaris`? Won't that go wrong, because gcc is generating code for x86_64? -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2951#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2962: Fix space leak in genericLength
#2962: Fix space leak in genericLength --+- Reporter: thorkilnaur | Owner: Type: bug | Status: new Priority: normal| Milestone: Component: libraries/base|Version: 6.11 Severity: normal| Resolution: Keywords:| Testcase: Os: Unknown/Multiple | Architecture: Unknown/Multiple --+- Comment (by NeilMitchell): The patch is incorrect. If the (+) function isn't strict in both arguments then you are too strict. You could always add genericLength', and add specialisation rules for genericLength on Int/Integer/Float/Double, which gets you all the benefits in the common cases but still preserves the semantics. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2962#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2953: deriving Functor, Foldable, Traversable
#2953: deriving Functor, Foldable, Traversable --+- Reporter: twanvl| Owner: twanvl Type: feature request | Status: new Priority: normal| Milestone: Component: Compiler |Version: 6.11 Severity: normal| Resolution: Keywords:| Testcase: Os: Unknown/Multiple | Architecture: Unknown/Multiple --+- Comment (by twanvl): As a start, I have implemented the deriving for the Functor class only. For some reason the patch is too big to attach, it can be found at [http://twan.home.fmf.nl/files/deriving-functor2.patch.gz]. A patch with testcases is attached. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2953#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2951: Add support for amd64-solaris2 platform
#2951: Add support for amd64-solaris2 platform +--- Reporter: kgardas |Owner: simonmar Type: feature request | Status: new Priority: normal |Milestone: 6.12 branch Component: Compiler | Version: 6.10.1 Severity: normal | Resolution: Keywords: | Difficulty: Unknown Testcase: | Os: Solaris Architecture: x86_64 (amd64) | +--- Comment (by kgardas): It is simple, Solaris on amd64 aka x86_64 platform supports two ABI: one 64bit and one 32bit. Till now using older version of config.guess my amd64/solaris box was recognized as i386-solaris and GHC behaves accordingly and builds well (for i386-solaris2). Since your config.guess update, GHC knows it's configured on amd64-solaris and complains about unsupported platform. So my fix is natural fix to make GHC again believe this is i386-solaris as it supports it all the time. Of course it's very easy for anyone interested just to revert this simple patch and hack on real amd64-solaris platform support. Is it more clear now? -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2951#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2951: Add support for amd64-solaris2 platform
#2951: Add support for amd64-solaris2 platform +--- Reporter: kgardas |Owner: simonmar Type: feature request | Status: new Priority: normal |Milestone: 6.12 branch Component: Compiler | Version: 6.10.1 Severity: normal | Resolution: Keywords: | Difficulty: Unknown Testcase: | Os: Solaris Architecture: x86_64 (amd64) | +--- Comment (by kgardas): I would also like to add my analysis, if you don't have amd64/solaris2 platform at hands. So Solaris supports 2 ABIs, provides gcc 3.4.3 which by default generates 32bit code for i386 ABI. It might be also used to generate 64bit code for amd64 ABI if started with -m64 command-line option. If I'm right, then for GHC build, we do have i386 ABI GHC for Solaris in binary form and so stage1 compiler should also be compiled for i386, but it should be a cross-compiler run on i386 generating code for amd64 ABI. Stage2 compiler should then be amd64 ABI and also in stage2 build and rts build executed gcc should be used with -m64 option to get 64bit binary. Now, the question is just where to hack to make it real. :-) (if I'm right of course) -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2951#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [GHC] #2753: GHC 6.10.1 cannot compile Crypto-4.1.0
#2753: GHC 6.10.1 cannot compile Crypto-4.1.0 -+-- Reporter: thoughtpolice |Owner: Type: bug | Status: new Priority: normal|Milestone: 6.10.2 Component: Compiler | Version: 6.10.1 Severity: critical | Resolution: Keywords:| Difficulty: Unknown Testcase:| Os: Unknown/Multiple Architecture: Unknown/Multiple | -+-- Changes (by guest): * cc: gwe...@gmail.com (added) Comment: Just to chip in: i386 Intrepid Ubuntu, GHC HQ's 6.10 binaries, darcs Crypto. Adding the -freg-graphs option to the sha1test stanza fixed the compilation problem for me. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/2753#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: [Haskell-cafe] ANNOUNCE: gitit 0.2 release - wiki using HAppS, git, pandoc
I think you need to remove your users database (and rebuild it). Compatibility was broken in version 0.3.4 (not sure of number). HTH -- Arnaud Bailly, PhD OQube - Software Engineering http://www.oqube.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Fri, Jan 16, 2009 at 3:10 PM, Bulat Ziganshin bulat.zigans...@gmail.com wrote: Hello david48, Friday, January 16, 2009, 4:16:51 PM, you wrote: Upon reading this thread, I asked myself : what's a monoid ? I had no idea. I read some posts, then google haskell monoid. it would be interesting to google C++ class or Lisp function and compare experience :) The first link for C++ class I find on google is the wikipedia article which I find understandable, has examples and explanations that relate to programming. OTOH, the wikipedia article for monoid is less easy (for me), though now I can follow the first paragraphs. But I don't find on the page how/why/where it relates to programming. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Fri, Jan 16, 2009 at 4:04 PM, Jonathan Cast jonathancc...@fastmail.fm wrote: On Fri, 2009-01-16 at 14:16 +0100, david48 wrote: Part of the problem is that something like a monoid is so general that I can't wrap my head around why going so far in the abstraction. For example, the writer monad works with a monoid; using the writer monad with strings makes sense because the mappend operation for lists is (++), now why should I care that I can use the writer monad with numbers which it will sum ? To accumulate a running count, maybe? A fairly common pattern for counting in imperative languages is int i = 0; while (get a value) i+= count of something in value Using the writer monad, this turns into execWriter $ mapM_ (write . countFunction) $ getValues well thank you for the example, if I may ask something: why would I need to write a running count this way instead of, for example, a non monadic fold, which would probably result in clearer and faster code (IMHO) ? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] some ideas for Haskell', from Python
Hello, 2009/1/16 Immanuel Litzroth immanuel...@gmail.com: I don't understand your comment. 1) If XMonad already uses it the problem is solved, without giving Haskell import new semantics? Right, but there are some restrictions. 2) These guys refer to a method to do plugin work in Haskell http://www.cse.unsw.edu.au/~dons/hs-plugins/ So the problem of dynamically loading plugins should already be solved? Well, mostly yes, but I think that it should be added to the language. Cheers, Artyom Shalkhakov. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
Cory Knapp wrote: Actually, that was part of my point: When I mention Haskell to people, and when I start describing it, they're generally frightened enough by the focus on pure code and lazy evaluation-- add to this the inherently abstract nature, and we can name typeclasses cuddlyKitten, and the language is still going to scare J. R. Programmer. By inherently mathematical nature, I didn't mean names like monoid and functor, I meant *concepts* like monoid and functor. Not that either of them are actually terribly difficult; the problem is that they are terribly abstract. That draws a lot of people (especially mathematicians), but most people who aren' drawn by that are hugely put off-- whatever the name is. So, I guess my point is that the name is irrelevant: the language is going to intimidate a lot of people who are intimidated by the vocabulary. Oh, I don't know. I have no idea what the mathematical definition of functor is, but as far as I can tell, the Haskell typeclass merely allows you to apply a function simultaneously to all elements of a collection. That's pretty concrete - and trivial. If it weren't for the seemingly cryptic name, nobody would think twice about it. (Not sure exactly what you'd call it though...) A monoid is a rather more vague concept. (And I'm still not really sure why it's useful on its own. Maybe I just haven't had need of it yet?) I think, as somebody suggested about monad, the name does tend to inspire a feeling of hey, this must be really complicated so that even after you've understood it, you end up wondering whether there's still something more to it than that. But yes, some people are definitely put off by the whole abstraction of abstractions of abstraction thing. I think we probably just need some more concrete examples to weight it down and make it seem like something applicable to the real world. (Thus far, I have convinced exactly *one* person to start learning Haskell. This person being something of a maths nerd, their main complaint was not about naming or abstraction, but about the implicitness of the language, and the extreme difficulty of visually parsing it. Perhaps not surprising comming from a professional C++ programmer...) At the same time, I think everyone is arguing *for* better documentation. And you're probably right: better documentation will bring the abstract nonsense down to earth somewhat. Amen! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments from OCaml Hacker Brian Hurt
The great that's why is as follows: when you have an abstraction, then it is sufficient to hold the abstraction in mind instead of the whole concrete implementation. That's the whole purpose of abstraction, after all, be it maths or programming. Let me illustrate this. Suppose you are developing a library that, for instance, has a notion of settings and is able to combine two settings with several strategies for resolving conflicts between settings with duplicate keys: take the first setting, the second, none, or make a setting with multiple values. For example, an alternative GetOpt. Suppose you don't know what a monoid is and don't even know that such an abstraction exists. Now, when you're reasoning about the library, you have to think If I combine 3 settings, should the order of combination matter? Hmm, would be nice if it didn't. Also, what should I return if someone queries for a non-existent key in the settings? Should I return an empty list, or a Nothing, or throw an error, or what? Do empty settings make sense? etc. If you're smart and lucky, you will most probably get most things right and inconsciously create a settings monoid. Now, if you know what a monoid is, you immediately recognize that your settings should be a monoid by nature, and now you have absolutely no doubt that you should make the combining operation associative and provide a unit; and you use this monoid abstraction all the time you are designing this library. Now, you don't think about whether you should throw an error or return a Nothing for an empty key; but instead you think about which result would behave like a unit for the monoid, being motivated by mathematical principles rather than pure intuition. You end up designing a mathematically sound library whose principles make sence and has no design flaws, at least in the mathematically sound part, even if you never actually use the word monoid in the documentation. Also, read this post by sigfpe that motivated me to learn abstract algebra in depth (I am yet in the beginning, however), and, overall, this is a breathtaking post: http://sigfpe.blogspot.com/2008/11/approach-to-algorithm-parallelisation.html - this is where I started to appreciate the power of mathematical abstractions even more. 2009/1/17 david48 dav.vire+hask...@gmail.com: All of this is still lacking the great why : why/how an abstraction so generic can be useful. I'm starting to believe that the only reason to make a datatype an instance of Monoid is... why not ! since it's not hard to find an associative operation and a neutral element. -- Eugene Kirpichov ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
2009/1/17 Andrew Coppin andrewcop...@btinternet.com: Cory Knapp wrote: Actually, that was part of my point: When I mention Haskell to people, and when I start describing it, they're generally frightened enough by the focus on pure code and lazy evaluation-- add to this the inherently abstract nature, and we can name typeclasses cuddlyKitten, and the language is still going to scare J. R. Programmer. By inherently mathematical nature, I didn't mean names like monoid and functor, I meant *concepts* like monoid and functor. Not that either of them are actually terribly difficult; the problem is that they are terribly abstract. That draws a lot of people (especially mathematicians), but most people who aren' drawn by that are hugely put off-- whatever the name is. So, I guess my point is that the name is irrelevant: the language is going to intimidate a lot of people who are intimidated by the vocabulary. Oh, I don't know. I have no idea what the mathematical definition of functor is, but as far as I can tell, the Haskell typeclass merely allows you to apply a function simultaneously to all elements of a collection. That's pretty concrete - and trivial. If it weren't for the seemingly cryptic name, nobody would think twice about it. (Not sure exactly what you'd call it though...) No, a functor is a more wide notion than that, it has nothing to do with collections. An explanation more close to truth would be A structure is a functor if it provides a way to convert a structure over X to a structure over Y, given a function X - Y, while preserving the underlying 'structure', where preserving structure means being compatible with composition and identity. Collections are one particular case. Another case is just functions with fixed domain A: given a structure of type [A-]X and a function of type X - Y, you may build an [A-]Y. Yet another case are monads (actually, the example above is the Reader monad): given a monadic computation of type 'm a' and a function a - b, you may get a computation of type m b: instance (Monad m) = Functor m where fmap f ma = do a - ma; return (f a) There are extremely many other examples of functors; they are as ubiquitous as monoids and monads :) -- Eugene Kirpichov ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
Eugene Kirpichov wrote: No, a functor is a more wide notion than that, it has nothing to do with collections. An explanation more close to truth would be A structure is a functor if it provides a way to convert a structure over X to a structure over Y, given a function X - Y, while preserving the underlying 'structure', where preserving structure means being compatible with composition and identity. As far as I'm aware, constraints like while preserving the underlying structure are not expressible in Haskell. instance (Monad m) = Functor m where fmap f ma = do a - ma; return (f a) While that's quite interesting from a mathematical point of view, how is this useful for programming purposes? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
2009/1/17 Andrew Coppin andrewcop...@btinternet.com: Eugene Kirpichov wrote: No, a functor is a more wide notion than that, it has nothing to do with collections. An explanation more close to truth would be A structure is a functor if it provides a way to convert a structure over X to a structure over Y, given a function X - Y, while preserving the underlying 'structure', where preserving structure means being compatible with composition and identity. As far as I'm aware, constraints like while preserving the underlying structure are not expressible in Haskell. Yes, but they are expressible in your mind so that you can recognize a functor and design you program so that it does satisfy this constraint, thus removing a large faulty piece of the design space. Also, you can write a QuickCheck test for fmap (f . g) = fmap f . fmap g and fmap id = id. instance (Monad m) = Functor m where fmap f ma = do a - ma; return (f a) While that's quite interesting from a mathematical point of view, how is this useful for programming purposes? In the same sense as monoids are, see my previous message. If you mean the usefulness of a Functor typeclass in Haskell, it's in the fact that everywhere where you'd like to convert a structure over X to a structure over Y (for example, the result of a monadic computation), you simply write 'fmap f structure' and it works the right way, if the structure has an instance for Functor (many structures do). I know I'm being a bit abstract, but that's the way I percept it. do filename - toLowerCase `fmap` readLine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
On Sat, Jan 17, 2009 at 5:04 AM, Andrew Coppin andrewcop...@btinternet.comwrote: Eugene Kirpichov wrote: No, a functor is a more wide notion than that, it has nothing to do with collections. An explanation more close to truth would be A structure is a functor if it provides a way to convert a structure over X to a structure over Y, given a function X - Y, while preserving the underlying 'structure', where preserving structure means being compatible with composition and identity. As far as I'm aware, constraints like while preserving the underlying structure are not expressible in Haskell. Well, they're expressible *about* Haskell. I.e., for functors we require: fmap id = id fmap (f . g) = fmap f . fmap g The first property is how we write preserving underlying structure, but this has a precise, well-defined meaning that we can say a given functor obeys or it does not (and if it does not, we say that it's a bad instance). But you are correct that Haskell does not allow us to require proofs of such properties. And indeed, some people break those properties in various ways, which some consider okay if the breakage is not observable from outside a given abstraction barrier. I'm on the fence about that... Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
Hello Luke, Saturday, January 17, 2009, 3:16:06 PM, you wrote: fmap id = id fmap (f . g) = fmap f . fmap g The first property is how we write preserving underlying structure, but this has a precise, well-defined meaning that we can say a given functor obeys or it does not (and if it does not, we say that it's a bad instance). But you are correct that Haskell does not allow us to require proofs of such properties. not haskell itself, but QuickCheck allows. we may even consider lifting these properties to the language level -- Best regards, Bulatmailto:bulat.zigans...@gmail.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 1:41 AM, david48 dav.vire+hask...@gmail.comdav.vire%2bhask...@gmail.com wrote: On Fri, Jan 16, 2009 at 3:10 PM, Bulat Ziganshin bulat.zigans...@gmail.com wrote: Hello david48, Friday, January 16, 2009, 4:16:51 PM, you wrote: Upon reading this thread, I asked myself : what's a monoid ? I had no idea. I read some posts, then google haskell monoid. it would be interesting to google C++ class or Lisp function and compare experience :) The first link for C++ class I find on google is the wikipedia article which I find understandable, has examples and explanations that relate to programming. OTOH, the wikipedia article for monoid is less easy (for me), though now I can follow the first paragraphs. But I don't find on the page how/why/where it relates to programming. So you're saying it should be better documented in Haskell what a Monoid is. Did you say you searched for C++ class why not Haskell Monoid then? The first correct google hit that didn't think I meant Monads, takes you straight to the GHC documentation for Data.Monoid. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] OS X build failure of Gtk2Hs from MacPorts
/opt/local/bin/ghc +RTS -RTS -c tools/hierarchyGen/TypeGen.hs -o tools/hierarchyGen/TypeGen.o -O -itools/hierarchyGen -package-conf package.conf.inplace -hide-all-packages -package base package.conf.inplace: openBinaryFile: does not exist (No such file or directory) /opt/local/bin/ghc +RTS -RTS -c tools/callbackGen/HookGenerator.hs -o tools/callbackGen/HookGenerator.o -O -I. -itools/callbackGen -package-conf package.conf.inplace -hide-all-packages -package base package.conf.inplace: openBinaryFile: does not exist (No such file or directory) rm -rf glib/System/Glib.o glib/System/Glib_split/; mkdir -p glib/System/Glib_split /opt/local/bin/ghc +RTS -RTS -split-objs -c glib/System/Glib.hs -o glib/System/Glib.o -O -fffi -iglib -package-conf package.conf.inplace -hide-all-packages -ignore-package glib -package base -package-name glib-0.9.13 '-#includeglib-object.h' -I/opt/local/include/glib-2.0 -I/opt/local/lib/glib-2.0/include -I/opt/local/include on the commandline: Warning: -fffi is deprecated: use -XForeignFunctionInterface or pragma {-# LANGUAGE ForeignFunctionInterface#-} instead package.conf.inplace: openBinaryFile: does not exist (No such file or directory) make[1]: *** [glib/System/Glib.o] Error 1 make: *** [all] Error 2 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
Thinking that Functor allows you to apply a function to all elements in a collection is a good intuitive understanding. But fmap also allows applying a function on elements of things that can't really be called collections, e.g., the continuation monad. -- Lennart On Sat, Jan 17, 2009 at 11:17 AM, Andrew Coppin andrewcop...@btinternet.com wrote: Cory Knapp wrote: Actually, that was part of my point: When I mention Haskell to people, and when I start describing it, they're generally frightened enough by the focus on pure code and lazy evaluation-- add to this the inherently abstract nature, and we can name typeclasses cuddlyKitten, and the language is still going to scare J. R. Programmer. By inherently mathematical nature, I didn't mean names like monoid and functor, I meant *concepts* like monoid and functor. Not that either of them are actually terribly difficult; the problem is that they are terribly abstract. That draws a lot of people (especially mathematicians), but most people who aren' drawn by that are hugely put off-- whatever the name is. So, I guess my point is that the name is irrelevant: the language is going to intimidate a lot of people who are intimidated by the vocabulary. Oh, I don't know. I have no idea what the mathematical definition of functor is, but as far as I can tell, the Haskell typeclass merely allows you to apply a function simultaneously to all elements of a collection. That's pretty concrete - and trivial. If it weren't for the seemingly cryptic name, nobody would think twice about it. (Not sure exactly what you'd call it though...) A monoid is a rather more vague concept. (And I'm still not really sure why it's useful on its own. Maybe I just haven't had need of it yet?) I think, as somebody suggested about monad, the name does tend to inspire a feeling of hey, this must be really complicated so that even after you've understood it, you end up wondering whether there's still something more to it than that. But yes, some people are definitely put off by the whole abstraction of abstractions of abstraction thing. I think we probably just need some more concrete examples to weight it down and make it seem like something applicable to the real world. (Thus far, I have convinced exactly *one* person to start learning Haskell. This person being something of a maths nerd, their main complaint was not about naming or abstraction, but about the implicitness of the language, and the extreme difficulty of visually parsing it. Perhaps not surprising comming from a professional C++ programmer...) At the same time, I think everyone is arguing *for* better documentation. And you're probably right: better documentation will bring the abstract nonsense down to earth somewhat. Amen! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 7:33 AM, Lennart Augustsson lenn...@augustsson.netwrote: Thinking that Functor allows you to apply a function to all elements in a collection is a good intuitive understanding. But fmap also allows applying a function on elements of things that can't really be called collections, e.g., the continuation monad. I hadn't even thought about fmap for continuations... interesting! It falls out of the logic though doesn't it? I'm not one to throw all the cool mathematical and logical thinking out for simpler terms or not covering the full usefulness of certain abstractions. I know Haskell allows for lazy evaluation (as an implementation of non-strictness) but Haskell programmers are NOT allowed to be lazy :-) Try learning the terms that are there... and ask for help if you need help... most of us are pretty helpful! Improving documentation can pretty much *always* be done on any project, and it looks like that's coming out of this long thread that won't die, so kudos to the ones being the gadflies in this instance. It really looked at first like a long troll, but I think something very useful is going to come out of this! Dave -- Lennart On Sat, Jan 17, 2009 at 11:17 AM, Andrew Coppin andrewcop...@btinternet.com wrote: Cory Knapp wrote: Actually, that was part of my point: When I mention Haskell to people, and when I start describing it, they're generally frightened enough by the focus on pure code and lazy evaluation-- add to this the inherently abstract nature, and we can name typeclasses cuddlyKitten, and the language is still going to scare J. R. Programmer. By inherently mathematical nature, I didn't mean names like monoid and functor, I meant *concepts* like monoid and functor. Not that either of them are actually terribly difficult; the problem is that they are terribly abstract. That draws a lot of people (especially mathematicians), but most people who aren' drawn by that are hugely put off-- whatever the name is. So, I guess my point is that the name is irrelevant: the language is going to intimidate a lot of people who are intimidated by the vocabulary. Oh, I don't know. I have no idea what the mathematical definition of functor is, but as far as I can tell, the Haskell typeclass merely allows you to apply a function simultaneously to all elements of a collection. That's pretty concrete - and trivial. If it weren't for the seemingly cryptic name, nobody would think twice about it. (Not sure exactly what you'd call it though...) A monoid is a rather more vague concept. (And I'm still not really sure why it's useful on its own. Maybe I just haven't had need of it yet?) I think, as somebody suggested about monad, the name does tend to inspire a feeling of hey, this must be really complicated so that even after you've understood it, you end up wondering whether there's still something more to it than that. But yes, some people are definitely put off by the whole abstraction of abstractions of abstraction thing. I think we probably just need some more concrete examples to weight it down and make it seem like something applicable to the real world. (Thus far, I have convinced exactly *one* person to start learning Haskell. This person being something of a maths nerd, their main complaint was not about naming or abstraction, but about the implicitness of the language, and the extreme difficulty of visually parsing it. Perhaps not surprising comming from a professional C++ programmer...) At the same time, I think everyone is arguing *for* better documentation. And you're probably right: better documentation will bring the abstract nonsense down to earth somewhat. Amen! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: HTTPbis / HTTP-4000.x package available
There's however still no framework which supports both HTTP client and server functions using the same Request and Response data type, right? I don't know whether I am the only one who needs this (e.g. for the Real Monad Transformer). E.g. a proxy would need this, too. I've wanted this for a while now. Me Too. Tim Newsham http://www.thenewsh.com/~newsham/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Efficient Factoring Out of Constants
Hi, I¹ve been thinking about factoring constants out of iterations and have spotted another place in my code where I can make use of this. See the two examples below the first example iterates over the mcSimulate function this has changed a little bit but essentially still recurses around passing in two constants, and two variables that are changed each time it is called it has the following form: mcSimulate (startStock, endTime, seedForSeed, runningSum) = ( startStock, endTime, newSeedForSeed, newRunningSum ) I figured I¹m passing around the constants startStock and endTime so looked factor these out producing the second example below. My concern is that although iterate function now only handles two variables, it¹s still passing around 1 tuple, which under the bonnet is likely to be represented in machine code as a pointer? Humor me here a little I know I¹m thinking of this in terms of C++, but I¹m guessing the final byte code will adhere to this: Thus each time mcSimulate is called a machine code subroutine will be passed a memory address to the input data. Now, the crux of this is, will it make a COPY of the old input data, BUT with the newSeedForSeed and newRunningSum, to pass to the next iteration? If this is the case each iteration does two useless copies of startStock and endTime? Here the second example should produce better code because nothing constant is copied from 1 iteration to the next. However if the compiler is smarter and simply REPLACES the modified data the second example buys us nothing. However, again, depending very much on the compiler, the second example may actually be less efficient. Let¹s say the compiler is super smart and doesn¹t copy around the startStock and endTime on each iteration in the first example. Then we¹ve gained nothing. However the second example Will call 3 functions each iteration: mcWrapper - mcSimulate - getStateInfo In the second example we probably have something like 6 JMP¹ statements in machine code 3 to jump in to each function, and 3 to jump back out. In the first we have 2 one to jump us into mcSimulate and one to return. So each iteration executes 4 more JMPs in the second example. All others things being equal this will produce slightly less efficient code. Now I know I¹m speculating like crazy, and perhaps I¹m drunk with efficiency here, but it would seem to me that whatever way it works there will be a certain critical mass of constant data that you can carry around that once breached (i.e. When the copy operations exceed the CPU time taken for the 4 extra JMPs) you will be better off factoring the constant data out. That is assuming any of my analysis is correct :-) If anyone has any insight into how this might looked once compiled down to machine code, or has an opinion one which example below makes for better Haskell, I¹d be grateful for any comments, advice or discussion. Cheers, Phil. Note: I recognize the use of getSum and getStateInfo could be polished using data structures instead, and the use of !! will not produce strict evaluation. - getSum :: (Double, Double, Word64, Double) - Double getSum (startStock, endTime, seedForSeed, runningSum) = runningSum getAveragePayoff :: Double - Double - Int - Word64 - Double getAveragePayoff startStock endTime iterations seedForSeed = average where average = (getSum $ (iterate mcSimulate (startStock, endTime, seedForSeed, 0)) !! iterations ) / fromIntegral iterations --- getStateInfo :: (Double, Double, Word64, Double) - (Word64,Double) getStateInfo (startStock, endTime, seedForSeed, runningSum) = (seedForSeed, runningSum) getAveragePayoff :: Double - Double - Int - Word64 - Double getAveragePayoff startStock endTime iterations seedForSeed = average where average = (snd $ (iterate mcWrapper (seedForSeed,0)) !! iterations ) / fromIntegral iterations where mcWrapper = \(seed,runningSum) - getStateInfo $ mcSimulate ( startStock, endTime, seed, runningSum ) On 16/01/2009 01:41, Phil pbeadl...@mail2web.com wrote: On 16/01/2009 01:28, Luke Palmer lrpal...@gmail.com wrote: Compile-time constants could be handled by simple top-level bindings. This technique is specifically for the case you are after: mcSimulate :: Double - Double - Word64 - [Double] mcSimulate startStock endTime seedForSeed = go seedForSeed where go = fst expiryStock : go newSeedForSeed where expiryStock = iterate evolveUnderlying (startStock, ranq1Init seedForSeed) !! truncate (endTime/timeStep) newSeedForSeed = seedForSeed + 246524 See what's going on there? I don't know about that nested where. In Real Life I would probably use a let instead for expiryStock and newSeedForSeed. Luke Ahh, I get it now, that¹s pretty neat - go¹ is only updating the seedForSeed and the expiryStock, the inner where¹ clause keeps everything else constant each time it is
[Haskell-cafe] Re: Efficient Factoring Out of Constants
On Sat, Jan 17, 2009 at 9:46 AM, Phil pbeadl...@mail2web.com wrote: In the second example we probably have something like 6 'JMP' statements in machine code – 3 to jump in to each function, and 3 to jump back out. In the first we have 2 – one to jump us into mcSimulate and one to return. So each iteration executes 4 more JMPs in the second example. All others things being equal this will produce slightly less efficient code. Wow. I strongly suggest you forget about efficiency completely and become a proficient high-level haskeller, and then dive back in. Laziness changes many runtime properties, and renders your old ways of thinking about efficiency almost useless. If you are interested, though, you can use the ghc-core tool on hackage to look at the core (lowish-level intermediate language) and even the generated assembly for minimal cases. It's dense, but interesting if you have the time to study it. Others will know more about this specific speculation than I. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] ANN: HTTPbis / HTTP-4000.x package available
On Fri, 2009-01-16 at 17:57 +0300, Bulat Ziganshin wrote: Hello Sigbjorn, Friday, January 16, 2009, 5:42:06 PM, you wrote: first question: are these packages (http, curl, curl-shell, webclient) windows-compatible? second - that is advantages of using http (or webclient) over curl? I don't know enough about the others to do a proper comparison, but one data point is that for cabal-install we picked the HTTP package because it *does* work on Windows and does not need any C libraries, making it easy to deploy. [Packages that require external C libraries are possible on Windows of course but are a pain. For cabal-install we also use the zlib package which does need the zlib C lib. Fortunately the zlib C lib is sufficiently simple that it can be built by Cabal and thus it is possible to have it bundled with the zlib Haskell package.] I've not looked at the API of the other packages but the HTTP package provides the Browser module which makes making sequences of requests fairly easy. It handles proxies, authentication, redirection etc. With the latest release it should also be rather quicker than it used to be, and it fixes problems we used to have with some proxies. Speaking of proxies, I've been looking into how to find the right proxy to use on Windows systems. Turns out that to do it properly you need a JavaScript interpreter! Yes, really. Apparently we have Netscape to thank for that decision. The easiest way appears to be to link to the MS WinHTTP lib which provides a couple functions for doing this: http://hackage.haskell.org/trac/hackage/ticket/460 Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Re[2]: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 4:08 PM, David Leimbach leim...@gmail.com wrote: So you're saying it should be better documented in Haskell what a Monoid is. Did you say you searched for C++ class why not Haskell Monoid then? The first correct google hit that didn't think I meant Monads, takes you straight to the GHC documentation for Data.Monoid. Read my first post on the thread, that's exactly what I did ( and then complained that the doc for Data.Monoid was close to useless ) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Network CGI : outputFPS ByteString problem
Hello, When I try to render a byteString template using outputFPS like this : outputBsTemplate :: StringTemplate ByteString - CGI CGIResult outputBsTemplate template = let bs = renderFPS template in outputFPS bs I get this error : Couldn't match expected type `Data.ByteString.Lazy.Internal.ByteString' against inferred type `ByteString' Is this a library problem? Is the CGI bound with a too specific ByteString ? Or am I doing something terrible wrong ? thanks in advance, Pieter -- Pieter Laeremans pie...@laeremans.org The future is here. It's just not evenly distributed yet. W. Gibson ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Network CGI : outputFPS ByteString problem
On Sat, Jan 17, 2009 at 11:09 AM, Pieter Laeremans pie...@laeremans.orgwrote: Hello, When I try to render a byteString template using outputFPS like this : outputBsTemplate :: StringTemplate ByteString - CGI CGIResult outputBsTemplate template = let bs = renderFPS template in outputFPS bs I get this error : Couldn't match expected type `Data.ByteString.Lazy.Internal.ByteString' against inferred type `ByteString' It's expecting a Lazy bytestring and you're giving it a Strict one. Simplest fix: import Data.ByteString.Lazy instead. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] New blog on Haskell and Haskell in Visualization
Just started up a blog on my own random lumberings through Haskell and the visualizations I've produced in Haskell. Have plenty of content on backlog, so I should be updating regularly. That's about all! http://vis.renci.org/jeff/ -- Jeff ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Compiling regex-posix-0.93.2 on windows
On Fri, 2009-01-16 at 21:17 +, Chris Kuklewicz wrote: And regex-posix has a very old school Setup.hs file with a small addition: #!/usr/bin/env runhaskell -- I usually compile this with ghc --make -o setup Setup.hs import Distribution.Simple(defaultMainWithHooks, defaultUserHooks) main = do putStrLn msg defaultMainWithHooks defaultUserHooks msg = This links to the standard c library version of regular expressions.\n\ \The corresponding c header file is regex.h and there is a chance you\n\ \will need to edit the end of the regex-posix.cabal file to find the\n\ \include directory and/or library.\n Hmmm...the next version will probably need to mention the cabal command line flags as well. Perhaps you'd like to help us implement this ticket: Check for required C libraries during configure http://hackage.haskell.org/trac/hackage/ticket/262 As part of that ticket we should make sure the error message explains what it was that the package needed and what to do if they are in a non-standard location. The implementation basically just needs to do exactly what autoconf does in this circumstance, compile a little .c program. We have one advantage which is that we can probably do it faster in the best case since we ought to be able to make one .c program and try linking it against everything, rather than doing one compile for each C lib and C header. Of course if it fails then we have to go and do it for each one individually to figure out which is the cause of the problem. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient Factoring Out of Constants
On 17/01/2009 16:55, Luke Palmer lrpal...@gmail.com wrote: Wow. I strongly suggest you forget about efficiency completely and become a proficient high-level haskeller, and then dive back in. Laziness changes many runtime properties, and renders your old ways of thinking about efficiency almost useless. If you are interested, though, you can use the ghc-core tool on hackage to look at the core (lowish-level intermediate language) and even the generated assembly for minimal cases. It's dense, but interesting if you have the time to study it. Others will know more about this specific speculation than I. Luke [Phil] Heh heh totally accept what your saying, I am obsessing over details here. I¹ve ran some empirical tests to get some crude insight (just using the linux¹s time program), I expected the differences to be small for the amount of data I was passing around, but I was surprised. I modified the code ever so slightly to use data structures to pass around the data. Thus got rid of the getSum and getStateInfo functions. In the first unfactored example everything was passed around in one structure. In the second example I had two structures; one for constant data and one for state date. Thus doesn¹t really change the problem it just means that in the unfactored example mcSimulate takes one parameter (holding data constant and variable state data) and in the factored example it takes two parameters. The rest of the code remained more-or-less identical to my original post. Running both programs at the same time on an otherwise unloaded CPU gave a very consistent result over numerous trials that for 1 million calls to mcSimulate, the unfactored example took approx 1m44s and the factored example took 1m38 which is a fairly significant difference. So whilst I can¹t offer any exact explanation, it is clear that factoring out even a few parameters taking up little memory produces a significant performance increase. This would suggest that my JMP¹ analysis is not right and that the compiler is able to optimize the factored version better. If anyone else fancies offering up their 2 cents on what the compiler is doing, I¹d still be interested, but the empirical evidence alone is enough for me to be swayed to factoring all static parameters in an iteration out of the iteration and into a wrapper. Phil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient Factoring Out of Constants
A very short time ago Simon Marlow (if I recall correctly) commented on this topic: he told that this transformation usually improves efficiency pretty much, but sometimes it leads to some problems and it shouldn't be done by the compiler automatically. Search the recent messages for 'map' and one of them will have an answer :) 2009/1/17 Phil pbeadl...@mail2web.com: On 17/01/2009 16:55, Luke Palmer lrpal...@gmail.com wrote: Wow. I strongly suggest you forget about efficiency completely and become a proficient high-level haskeller, and then dive back in. Laziness changes many runtime properties, and renders your old ways of thinking about efficiency almost useless. If you are interested, though, you can use the ghc-core tool on hackage to look at the core (lowish-level intermediate language) and even the generated assembly for minimal cases. It's dense, but interesting if you have the time to study it. Others will know more about this specific speculation than I. Luke [Phil] Heh heh – totally accept what your saying, I am obsessing over details here. I've ran some empirical tests to get some crude insight (just using the linux's time program), I expected the differences to be small for the amount of data I was passing around, but I was surprised. I modified the code ever so slightly to use data structures to pass around the data. Thus got rid of the getSum and getStateInfo functions. In the first unfactored example everything was passed around in one structure. In the second example I had two structures; one for constant data and one for state date. Thus doesn't really change the problem it just means that in the unfactored example mcSimulate takes one parameter (holding data constant and variable state data) and in the factored example it takes two parameters. The rest of the code remained more-or-less identical to my original post. Running both programs at the same time on an otherwise unloaded CPU gave a very consistent result over numerous trials that for 1 million calls to mcSimulate, the unfactored example took approx 1m44s and the factored example took 1m38 – which is a fairly significant difference. So whilst I can't offer any exact explanation, it is clear that factoring out even a few parameters taking up little memory produces a significant performance increase. This would suggest that my 'JMP' analysis is not right and that the compiler is able to optimize the factored version better. If anyone else fancies offering up their 2 cents on what the compiler is doing, I'd still be interested, but the empirical evidence alone is enough for me to be swayed to factoring all static parameters in an iteration out of the iteration and into a wrapper. Phil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Slow Text.JSON parser
Hi, Somebody told me about Parsec 3, which uses a Stream type class so it can parse any data type. This sounded like the right way to do encoding independent parsing, so I decided to see how it would work to parse UTF8 JSON. Sadly I could not use Text.JSON.Parsec directly, because it uses the old Parsec CharParser type. So I copied to code, and also replaced p_number with the floating parser from Text.Parsec.Token, because Text.JSON.Parsec uses readFloat (a dirty hack imho) which works only on String. If Text.JSON.Parsec was written for Parsec 3, the only thing to write to get UTF8 JSON parsing would be: instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons I did not do any performance measuring yet, I was glad I got it working. Any comments on the code is appreciated! greetings, Sjoerd Visscher {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-} import qualified Data.String.UTF8 as U import qualified Data.ByteString as B import Text.Parsec hiding (many, optional, (|)) import Control.Applicative import Text.JSON.Types import Control.Monad import Data.Char import Numeric instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons type CharParser st = Parsec (U.UTF8 B.ByteString) st parseFile :: FilePath - IO (Either ParseError JSValue) parseFile fileName = do bs - B.readFile fileName return $ runParser json () fileName (U.fromRep bs) parseString :: String - Either ParseError JSValue parseString s = runParser json () (unknown) (U.fromString s) json :: CharParser () JSValue json = spaces * p_value tok :: CharParser () a - CharParser () a tok p = p * spaces p_value :: CharParser () JSValue p_value = (JSNull $ p_null) | (JSBool $ p_boolean) | (JSArray $ p_array) | (JSString$ p_js_string) | (JSObject$ p_js_object) | (JSRational False $ p_number) ? JSON value p_null :: CharParser () () p_null= tok (string null) return () p_boolean:: CharParser () Bool p_boolean = tok ( (True $ string true) | (False $ string false) ) p_array :: CharParser () [JSValue] p_array = between (tok (char '[')) (tok (char ']')) $ p_value `sepBy` tok (char ',') p_string :: CharParser () String p_string = between (tok (char '')) (char '') (many p_char) where p_char= (char '\\' p_esc) | (satisfy (\x - x /= '' x /= '\\')) p_esc = ('' $ char '') | ('\\' $ char '\\') | ('/' $ char '/') | ('\b' $ char 'b') | ('\f' $ char 'f') | ('\n' $ char 'n') | ('\r' $ char 'r') | ('\t' $ char 't') | (char 'u' * p_uni) ? escape character p_uni = check = count 4 (satisfy isHexDigit) where check x | code = max_char = pure (toEnum code) | otherwise = empty where code = fst $ head $ readHex x max_char = fromEnum (maxBound :: Char) p_object :: CharParser () [(String,JSValue)] p_object = between (tok (char '{')) (tok (char '}')) $ p_field `sepBy` tok (char ',') where p_field = (,) $ (p_string * tok (char ':')) * p_value p_number :: CharParser () Rational p_number = tok floating where floating :: CharParser () Rational floating= do{ n - decimal ; fract - option 0 fraction ; expo - option 1 exponent' ; return ((fromInteger n + fract)*expo) } fraction= do{ char '.' ; digits - many1 digit ? fraction ; return (foldr op 0 digits) } ? fraction where op d f= (f + fromIntegral (digitToInt d))/10 exponent' = do{ oneOf eE ; f - sign ; e - decimal ? exponent ; return (power (f e)) } ? exponent where power e | e 0 = 1/power(-e) | otherwise = fromInteger (10^e) sign= (char '-' return negate) | (char '+' return id) | return id decimal = number 10 digit number base baseDigit = do{ digits - many1 baseDigit
Re: Re[2]: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 9:16 AM, david48 dav.vire+hask...@gmail.comdav.vire%2bhask...@gmail.com wrote: On Sat, Jan 17, 2009 at 4:08 PM, David Leimbach leim...@gmail.com wrote: So you're saying it should be better documented in Haskell what a Monoid is. Did you say you searched for C++ class why not Haskell Monoid then? The first correct google hit that didn't think I meant Monads, takes you straight to the GHC documentation for Data.Monoid. Read my first post on the thread, that's exactly what I did ( and then complained that the doc for Data.Monoid was close to useless ) Sorry missed it! This is an exceptionally long thread! :-) I agree Data.Monoid's docs don't give you much to work with. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 1:47 AM, david48 dav.vire+hask...@gmail.com wrote: why would I need to write a running count this way instead of, for example, a non monadic fold, which would probably result in clearer and faster code? Maybe my post here will answer some questions like that: http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] runghc Setup.hs doitall
Hi guys: I don´t know how difficult really is, but it seens that it could be done because all the necessary elements are there (except perhaps the mapping package name-hackage url): Why hasn´t been done yet Is unknown to me. It would be very useful and a big save of time to have a cabal commad chech-dependencies-and-install-them-by-downloading-them-from-hackage-then-configure-build-and-install-this-package?. The unix installers do is t from binaries and are obsolete, so I have to do it manually with cabal everytime when i download a new compiler version from haskell.org. Cheers Alberto. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] runghc Setup.hs doitall
Am Samstag, 17. Januar 2009 23:20 schrieb Alberto G. Corona: Hi guys: I don´t know how difficult really is, but it seens that it could be done because all the necessary elements are there (except perhaps the mapping package name-hackage url): Why hasn´t been done yet Is unknown to me. It would be very useful and a big save of time to have a cabal commad chech-dependencies-and-install-them-by-downloading-them-from-hackage-then- configure-build-and-install-this-package?. The unix installers do is t from binaries and are obsolete, so I have to do it manually with cabal everytime when i download a new compiler version from haskell.org. Cheers Alberto. Use cabal-install: cabal update cabal install foo checks for dependencies, downloads and builds them automatically (if possible). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Slow Text.JSON parser
It occurs to me you could also use attoparsec, which is specifically optimised for bytestring processing. sjoerd: Hi, Somebody told me about Parsec 3, which uses a Stream type class so it can parse any data type. This sounded like the right way to do encoding independent parsing, so I decided to see how it would work to parse UTF8 JSON. Sadly I could not use Text.JSON.Parsec directly, because it uses the old Parsec CharParser type. So I copied to code, and also replaced p_number with the floating parser from Text.Parsec.Token, because Text.JSON.Parsec uses readFloat (a dirty hack imho) which works only on String. If Text.JSON.Parsec was written for Parsec 3, the only thing to write to get UTF8 JSON parsing would be: instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons I did not do any performance measuring yet, I was glad I got it working. Any comments on the code is appreciated! greetings, Sjoerd Visscher {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-} import qualified Data.String.UTF8 as U import qualified Data.ByteString as B import Text.Parsec hiding (many, optional, (|)) import Control.Applicative import Text.JSON.Types import Control.Monad import Data.Char import Numeric instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons type CharParser st = Parsec (U.UTF8 B.ByteString) st parseFile :: FilePath - IO (Either ParseError JSValue) parseFile fileName = do bs - B.readFile fileName return $ runParser json () fileName (U.fromRep bs) parseString :: String - Either ParseError JSValue parseString s = runParser json () (unknown) (U.fromString s) json :: CharParser () JSValue json = spaces * p_value tok :: CharParser () a - CharParser () a tok p = p * spaces p_value :: CharParser () JSValue p_value = (JSNull $ p_null) | (JSBool $ p_boolean) | (JSArray $ p_array) | (JSString$ p_js_string) | (JSObject$ p_js_object) | (JSRational False $ p_number) ? JSON value p_null :: CharParser () () p_null= tok (string null) return () p_boolean:: CharParser () Bool p_boolean = tok ( (True $ string true) | (False $ string false) ) p_array :: CharParser () [JSValue] p_array = between (tok (char '[')) (tok (char ']')) $ p_value `sepBy` tok (char ',') p_string :: CharParser () String p_string = between (tok (char '')) (char '') (many p_char) where p_char= (char '\\' p_esc) | (satisfy (\x - x /= '' x /= '\\')) p_esc = ('' $ char '') | ('\\' $ char '\\') | ('/' $ char '/') | ('\b' $ char 'b') | ('\f' $ char 'f') | ('\n' $ char 'n') | ('\r' $ char 'r') | ('\t' $ char 't') | (char 'u' * p_uni) ? escape character p_uni = check = count 4 (satisfy isHexDigit) where check x | code = max_char = pure (toEnum code) | otherwise = empty where code = fst $ head $ readHex x max_char = fromEnum (maxBound :: Char) p_object :: CharParser () [(String,JSValue)] p_object = between (tok (char '{')) (tok (char '}')) $ p_field `sepBy` tok (char ',') where p_field = (,) $ (p_string * tok (char ':')) * p_value p_number :: CharParser () Rational p_number = tok floating where floating :: CharParser () Rational floating= do{ n - decimal ; fract - option 0 fraction ; expo - option 1 exponent' ; return ((fromInteger n + fract)*expo) } fraction= do{ char '.' ; digits - many1 digit ? fraction ; return (foldr op 0 digits) } ? fraction where op d f= (f + fromIntegral (digitToInt d))/10 exponent' = do{ oneOf eE ; f - sign ; e - decimal ? exponent ; return (power (f e)) } ? exponent where power e | e 0 = 1/power(-e) | otherwise = fromInteger
Re: [Haskell-cafe] OS X build failure of Gtk2Hs from MacPorts
Jeff, I'm not sure if this is causing the problem you're referring to, but MacPorts is at GHC 6.10 while Gtk2Hs doesn't support that yet. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OS X build failure of Gtk2Hs from MacPorts
That would probably be the problem, then, yes. I'm still using GHC 6.8.3 in most of my code, but MacPorts doesn't respect the existing installation of GHC 6.8.3 that I installed via the DMG package on http://haskell.org/ghc On Sat, Jan 17, 2009 at 5:56 PM, Yitzchak Gale g...@sefer.org wrote: Jeff, I'm not sure if this is causing the problem you're referring to, but MacPorts is at GHC 6.10 while Gtk2Hs doesn't support that yet. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient Factoring Out of Constants
On 17/01/2009 20:45, Eugene Kirpichov ekirpic...@gmail.com wrote: A very short time ago Simon Marlow (if I recall correctly) commented on this topic: he told that this transformation usually improves efficiency pretty much, but sometimes it leads to some problems and it shouldn't be done by the compiler automatically. Search the recent messages for 'map' and one of them will have an answer :) Thanks for the tip - I'll have a look for this. I've also tried a third test using the two possibilities below, both have separate structures for variable and constant data, but the second example explicitly factors out passing this around as in previous examples. Here there is no discernable difference between the two methods' timed results, if anything the first one which is not explicitly factored out had a slight edge in tests. Therefore it would seem that providing you separate the constant and variable data out into the separate parameters, the compiler will do the rest for you. This suggests that the compiler is indeed smart; the staticData is not copied from iteration to iteration providing the whole structure is constant, but when you mix and match within a structure itself the compiler isn't smart enough to factor out the constant members. I suppose a conclusive test would be to add a very large amount of constant data to the structure to see if results were still similar. Note: strictIdx is just a strict version of !!: getAveragePayoff :: Double - Double - Int - Word64 - Double getAveragePayoff startStock endTime iterations seedForSeed = average where staticData = MCStatic startStock endTime average = ( runningSum $ snd $ strictIdx iterations ( iterate mcSimulate (staticData, (MCState seedForSeed 0)) ) ) / fromIntegral iterations ___ getAveragePayoff :: Double - Double - Int - Word64 - Double getAveragePayoff startStock endTime iterations seedForSeed = average where staticData = MCStatic startStock endTime average = ( runningSum $ strictIdx iterations ( iterate mcWrapper (MCState seedForSeed 0) ) ) / fromIntegral iterations where mcWrapper = \stateData - snd $ mcSimulate (staticData, stateData) On 17/01/2009 20:45, Eugene Kirpichov ekirpic...@gmail.com wrote: A very short time ago Simon Marlow (if I recall correctly) commented on this topic: he told that this transformation usually improves efficiency pretty much, but sometimes it leads to some problems and it shouldn't be done by the compiler automatically. Search the recent messages for 'map' and one of them will have an answer :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OS X build failure of Gtk2Hs from MacPorts
I personally spurned MacPorts for this reason (and others). I've had good success using the GTK+ Aqua framework from http://www.gtk- osx.org/ and manually compiling pkg-config and gtk2hs from the darcs repository. The only trick was to set PKG_CONFIG_PATH appropriately before running gtk2hs' configure script: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/Library/Frameworks/ Cairo.framework/Resources/dev/lib/pkgconfig:/Library/Frameworks/ GLib.framework/Resources/dev/lib/pkgconfig:/Library/Frameworks/ Gtk.framework/Resources/dev/lib/pkgconfig Also had to --disable-gio to gtk2hs' configure. -Ross On Jan 17, 2009, at 5:58 PM, Jeff Heard wrote: That would probably be the problem, then, yes. I'm still using GHC 6.8.3 in most of my code, but MacPorts doesn't respect the existing installation of GHC 6.8.3 that I installed via the DMG package on http://haskell.org/ghc On Sat, Jan 17, 2009 at 5:56 PM, Yitzchak Gale g...@sefer.org wrote: Jeff, I'm not sure if this is causing the problem you're referring to, but MacPorts is at GHC 6.10 while Gtk2Hs doesn't support that yet. Regards, Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Slow Text.JSON parser
Attoparsec does not have something like the Stream class, so I do not see how I could do UTF8 parsing easily. On Jan 17, 2009, at 11:50 PM, Don Stewart wrote: It occurs to me you could also use attoparsec, which is specifically optimised for bytestring processing. sjoerd: Hi, Somebody told me about Parsec 3, which uses a Stream type class so it can parse any data type. This sounded like the right way to do encoding independent parsing, so I decided to see how it would work to parse UTF8 JSON. Sadly I could not use Text.JSON.Parsec directly, because it uses the old Parsec CharParser type. So I copied to code, and also replaced p_number with the floating parser from Text.Parsec.Token, because Text.JSON.Parsec uses readFloat (a dirty hack imho) which works only on String. If Text.JSON.Parsec was written for Parsec 3, the only thing to write to get UTF8 JSON parsing would be: instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons I did not do any performance measuring yet, I was glad I got it working. Any comments on the code is appreciated! greetings, Sjoerd Visscher {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-} import qualified Data.String.UTF8 as U import qualified Data.ByteString as B import Text.Parsec hiding (many, optional, (|)) import Control.Applicative import Text.JSON.Types import Control.Monad import Data.Char import Numeric instance (Monad m, U.UTF8Bytes string index) = Stream (U.UTF8 string) m Char where uncons = return . U.uncons type CharParser st = Parsec (U.UTF8 B.ByteString) st parseFile :: FilePath - IO (Either ParseError JSValue) parseFile fileName = do bs - B.readFile fileName return $ runParser json () fileName (U.fromRep bs) parseString :: String - Either ParseError JSValue parseString s = runParser json () (unknown) (U.fromString s) json :: CharParser () JSValue json = spaces * p_value tok :: CharParser () a - CharParser () a tok p = p * spaces p_value :: CharParser () JSValue p_value = (JSNull $ p_null) | (JSBool $ p_boolean) | (JSArray $ p_array) | (JSString$ p_js_string) | (JSObject$ p_js_object) | (JSRational False $ p_number) ? JSON value p_null :: CharParser () () p_null= tok (string null) return () p_boolean:: CharParser () Bool p_boolean = tok ( (True $ string true) | (False $ string false) ) p_array :: CharParser () [JSValue] p_array = between (tok (char '[')) (tok (char ']')) $ p_value `sepBy` tok (char ',') p_string :: CharParser () String p_string = between (tok (char '')) (char '') (many p_char) where p_char= (char '\\' p_esc) | (satisfy (\x - x /= '' x /= '\\')) p_esc = ('' $ char '') | ('\\' $ char '\\') | ('/' $ char '/') | ('\b' $ char 'b') | ('\f' $ char 'f') | ('\n' $ char 'n') | ('\r' $ char 'r') | ('\t' $ char 't') | (char 'u' * p_uni) ? escape character p_uni = check = count 4 (satisfy isHexDigit) where check x | code = max_char = pure (toEnum code) | otherwise = empty where code = fst $ head $ readHex x max_char = fromEnum (maxBound :: Char) p_object :: CharParser () [(String,JSValue)] p_object = between (tok (char '{')) (tok (char '}')) $ p_field `sepBy` tok (char ',') where p_field = (,) $ (p_string * tok (char ':')) * p_value p_number :: CharParser () Rational p_number = tok floating where floating :: CharParser () Rational floating= do{ n - decimal ; fract - option 0 fraction ; expo - option 1 exponent' ; return ((fromInteger n + fract)*expo) } fraction= do{ char '.' ; digits - many1 digit ? fraction ; return (foldr op 0 digits) } ? fraction where op d f= (f + fromIntegral (digitToInt d))/10 exponent' = do{ oneOf eE ; f - sign ; e - decimal ? exponent ; return (power (f e)) } ? exponent where power e | e 0 = 1/power(-e) | otherwise = fromInteger (10^e) sign= (char '-'
[Haskell-cafe] ANN: hledger 0.3 released
I'm pleased to announce another hledger release. Happy new year, all! hledger is a partial haskell clone of John Wiegley's ledger text-based accounting tool. It generates transaction balance reports from a plain text ledger file, and demonstrates a functional implementation of ledger. For more information, see hledger's home page: http://joyful.com/hledger News for 0.3 Fixes: * count timelog sessions on the day they end, like ledger, for now * when options are repeated, use the last instead of the first * builds with ghc 6.10 as well as 6.8 * runs much faster than 0.2:: $ bench hledger-0.2 hledger ledger || hledger-0.2 | hledger | ledger ==++=+=+=== -f 2008.ledger -s balance ||2.59 |0.26 | 0.11 -f 1entries.ledger -s balance || 566.68 |2.72 | 0.96 Features: * a simple ui for interactive report browsing: hledger ui * accept smart dates everywhere (MMDD, Y/M/D, Y, M/D, D, jan, today, last week etc.) * --period/-p flag accepting period expressions like in 2008, weekly from last month.. * -W/-M/-Y convenience flags to summarise register weekly, monthly, yearly * --depth and -E flags also affect summarised register reports (including depth=0) * --display/-d flag supporting date predicates (like d[DATE], d=[DATE]) * !include directive to include additional ledger files * !account directive to set a default parent account * Added support for reading historical prices from files * timelog and ledger entries can be intermixed in one file * modifier and periodic entries can appear anywhere (but are still ignored) * help and readme improvements Contributors: * Simon Michael * Nick Ingolia * Tim Docker * Corey O'Connor the vty team Stats: * Known errors: 1 * Tests: 58 * Lines of non-test code: 2123 Installation hledger requires GHC. It is known to build with 6.8 and 6.10. If you have cabal-install, do:: cabal update cabal install hledger Otherwise, unpack the latest tarball from http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hledger and do:: runhaskell Setup.hs configure runhaskell Setup.hs build sudo runhaskell Setup.hs install This will complain about any missing libraries, which you can download and install manually from hackage.haskell.org. (The Build-Depends: in hledger.cabal has the full package list.) To get the latest development code do:: darcs get http://joyful.com/repos/hledger ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: Coadjute 0.0.1, generic build tool
Announcing the release of Coadjute, version 0.0.1! Web site: http://iki.fi/matti.niemenmaa/coadjute/ Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coadjute Coadjute is a generic build tool, intended as an easier to use and more portable replacement for make. It’s not tailored toward any particular language, and is not meant to replace tools which target a specific environment (such as ghc --make or Cabal, taking Haskell as an example). I've been sitting on this for a couple of months now and figured I might as well push it out since it seems to be in relative working order. I've used it on my web site since July and it hasn't resulted in data loss yet. Still, it's a 0.0 version so no guarantees. ;-) A bit of advertising: Portability is striven towards in two ways: * You don’t have to deal with the idiosyncrasies of many make implementations (well, people don’t, but they call their GNU Make files makefiles instead of GNUmakefiles, which causes misunderstandings). * You have Haskell at your disposal, and are encouraged to use that whenever possible instead of system-specific binaries like the POSIX commands we all know and love. Comes with support for: * Parallel task performing. * Advanced out-of-dateness detection: o Choice between timestamps and hashes. o Keeping track of what arguments have been passed. * Haskell! Have a look at the Haddock documentation for a few simple examples and do feel free to comment over at haskell-cafe—or privately, if that's your preference. Any kind of discussion is welcome! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Coadjute 0.0.1, generic build tool
2009/1/18 Matti Niemenmaa matti.niemenmaa+n...@iki.fi: Announcing the release of Coadjute, version 0.0.1! Hi, trying to build on GHC 6.10.1 I get: Building regex-dfa-0.91... Text/Regex/DFA/Common.hs:6:7: Could not find module `Data.IntMap': it is a member of package containers-0.2.0.0, which is hidden cabal: Error: some packages failed to install: Coadjute-0.0.1 depends on regex-dfa-0.91 which failed to install. regex-dfa-0.91 failed during the building phase. The exception was: exit: ExitFailure 1 Web site: http://iki.fi/matti.niemenmaa/coadjute/ Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coadjute Coadjute is a generic build tool, intended as an easier to use and more portable replacement for make. It's not tailored toward any particular language, and is not meant to replace tools which target a specific environment (such as ghc --make or Cabal, taking Haskell as an example). I've been sitting on this for a couple of months now and figured I might as well push it out since it seems to be in relative working order. I've used it on my web site since July and it hasn't resulted in data loss yet. Still, it's a 0.0 version so no guarantees. ;-) A bit of advertising: Portability is striven towards in two ways: * You don't have to deal with the idiosyncrasies of many make implementations (well, people don't, but they call their GNU Make files makefiles instead of GNUmakefiles, which causes misunderstandings). * You have Haskell at your disposal, and are encouraged to use that whenever possible instead of system-specific binaries like the POSIX commands we all know and love. Comes with support for: * Parallel task performing. * Advanced out-of-dateness detection: o Choice between timestamps and hashes. o Keeping track of what arguments have been passed. * Haskell! Have a look at the Haddock documentation for a few simple examples and do feel free to comment over at haskell-cafe—or privately, if that's your preference. Any kind of discussion is welcome! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Ilmari Vacklin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Coadjute 0.0.1, generic build tool
matti.niemenmaa+news: Announcing the release of Coadjute, version 0.0.1! Web site: http://iki.fi/matti.niemenmaa/coadjute/ Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Coadjute Here's an Arch Linux package for it, http://aur.archlinux.org/packages.php?ID=23237 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: Coadjute 0.0.1, generic build tool
ilmari.vacklin: 2009/1/18 Matti Niemenmaa matti.niemenmaa+n...@iki.fi: Announcing the release of Coadjute, version 0.0.1! Hi, trying to build on GHC 6.10.1 I get: Building regex-dfa-0.91... Text/Regex/DFA/Common.hs:6:7: Could not find module `Data.IntMap': it is a member of package containers-0.2.0.0, which is hidden cabal: Error: some packages failed to install: Coadjute-0.0.1 depends on regex-dfa-0.91 which failed to install. regex-dfa-0.91 failed during the building phase. The exception was: exit: ExitFailure 1 regex-dfa needs this patch, attached. Or use the native package for it on your distro ... :) -- Don --- regex-dfa.cabal.old 2009-01-17 16:10:53.0 -0800 +++ regex-dfa.cabal 2009-01-17 16:12:26.0 -0800 @@ -13,7 +13,7 @@ Description:The lazy DFA engine, based on CTKLight, for regex-base Category: Text Tested-With:GHC -Build-Depends: regex-base = 0.80, base = 2.0, parsec, mtl +Build-Depends: regex-base = 0.80, containers, base = 2.0, bytestring, parsec, mtl, array -- Data-Files: -- Extra-Source-Files: -- Extra-Tmp-Files: @@ -37,7 +37,7 @@ -- HS-Source-Dirs: . Extensions: MultiParamTypeClasses, FunctionalDependencies -- GHC-Options:-Wall -GHC-Options:-Wall -Werror -O2 +GHC-Options:-Wall -O2 -- GHC-Options:-Wall -ddump-minimal-imports -- GHC-Prof-Options: -- Hugs-Options: ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments from OCaml Hacker Brian Hurt
G'day all. Quoting Gracjan Polak gracjanpo...@gmail.com: I remember my early CS algebra courses. I met cool animals there: Group, Ring, Vector Space. Those beasts were very strong, but also very calm at the same time. Although I was a bit shy at first, after some work we became friends. I don't know about you, bu the word module threw me. That is probably the one name from algebra that clashes with computer science too much. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
On Saturday 17 January 2009 8:28:05 am Bulat Ziganshin wrote: Hello Luke, Saturday, January 17, 2009, 3:16:06 PM, you wrote: fmap id = id fmap (f . g) = fmap f . fmap g The first property is how we write preserving underlying structure, but this has a precise, well-defined meaning that we can say a given functor obeys or it does not (and if it does not, we say that it's a bad instance). But you are correct that Haskell does not allow us to require proofs of such properties. not haskell itself, but QuickCheck allows. we may even consider lifting these properties to the language level QuickCheck doesn't allow you to prove that the properties hold, though. It can only prove that they don't hold, and consequently give you confidence that they do hold when the tests fail to prove that they don't. To prove that they hold, you need something more like ESC/Haskell, catch or a fancier type system than the one Haskell (or even GHC) has. -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: HTTPbis / HTTP-4000.x package available
Hi Sigbjorn, On Thu, Jan 15, 2009 at 10:36:35PM -0800, Sigbjorn Finne wrote: I've yet to gain access to www.haskell.org and update http://www.haskell.org/http, Perhaps this would be a good point to move the website to the community server? Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
G'day all. Quoting John Goerzen jgoer...@complete.org: If I see Appendable I can guess what it might be. If I see monoid, I have no clue whatsoever, because I've never heard of a monoid before. Any sufficiently unfamiliar programming language looks like line noise. That's why every new language needs to use curly braces. If you're learning Haskell, which communicates the idea more clearly: * Appendable or * Monoid I can immediately figure out what the first one means. No you can't. It is in no way clear, for example, that Integers with addition are Appendable. I'm not saying that Monoid is the most pragmatically desirable term, merely that Appendable is misleading. And FWIW, I agree with everyone who has commented that the documentation is inadequate. It'd be nice if there was some way to contribute better documentation without needing checkin access to the libraries. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Hackage about to reach 1000 releases
Hackage is about to reach the 1000 release mark, 2 years after it went live. That's right: in 2 years we've gone from having only a handful of released projects, to one thousand! Well done everyone! I did some quick visualisation of the rate of new releses, diversity of packages, and community growth over the period: http://archhaskell.wordpress.com/2009/01/18/open-source-haskell-releases-and-growth/ I'm very happy about the diversity of hackage apps, and the pleasing rate of growth of new releases. None of this would have been possible with out thousands of hours of work from the Cabal and Hackage hackers, the compiler teams, and the developers themselves. Keep churning out new and intresting code everyone! -- Don P.S. cabal install ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Comments from OCaml Hacker Brian Hurt
G'day all. Dan Weston wrote: Richard Feinman once said: if someone says he understands quantum mechanics, he doesn't understand quantum mechanics. But what did he know... Presumably not quantum mechanics. Cheers, Andrew Bromage ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell and C++ program
On Thu, 2009-01-15 at 13:40 +0100, Apfelmus, Heinrich wrote: Eugene Kirpichov wrote: Well, your program is not equivalent to the C++ version, since it doesn't bail on incorrect input. Oops. That's because my assertion show . read = id is wrong. We only have read . show = id show . read = id (in the less defined than sense) No, you only have read . show = id which often doesn't hold in practice. show . read /= id Assuming the first identity holds, you do of course have show . read . show = show and this probably holds even in most cases where read . show = id does not hold. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANN: language-sh-0.0.3.1
Hi everyone, I'm pleased to announce a new package I've just uploaded to hackage: language-sh. It's a set of modules for parsing, manipulating, and printing sh-style shell scripts. It's being developed alongside shsh, the Simple Hakell Shell (available at http://code.haskell.org/shsh/, but it's still missing a few features before I'm ready to release it). I have two goals with this project (shsh, that is - I don't actually have plans for Language.Sh by itself, except that some people suggested it could be useful on its own). First, making possible portable test suits that run on Windows as well as on Unix. The second is a bit more difficult, but ultimately I hope shsh can become a viable command-line shell for Windows. I would love any comments, suggestions, criticisms, and especially patches! Please let me know what you think! http://hackage.haskell.org/cgi-bin/hackage-scripts/package/language-sh-0.0.3.1 Cheers, steve hicks ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Slow Text.JSON parser
Maybe. Handling the common cases reasonably well is probably worth doing first (+profiling) before opting for a heartlung transplant.. To wit, I've trivially improved the handling of string and integer lits in version 0.4.3 (just released.) It cuts down the running times by a factor of 2-3 on larger inputs -- http://hackage.haskell.org/cgi-bin/hackage-scripts/package/json Not saying that there aren't additional wins to be had :) hth --sigbjorn On 1/17/2009 14:50, Don Stewart wrote: It occurs to me you could also use attoparsec, which is specifically optimised for bytestring processing. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: ANN: leapseconds-announced-2009
On Sun, Jan 18, 2009 at 00:00, Ashley Yakeley ash...@semantic.org wrote: Bjorn Buckwalter wrote: leapseconds-announced is a pragmatic, if imperfect, improvement over my past practices. It provides a LeapSecondTable with all leap seconds announced to date (hence the name). Once the IERS announces[3] another leap second the package will need an update and all code using it a recompile. While this precludes its use in long-running production applications it is eminently adequate for my one-off uses or for applications that can afford to recompile infrequently. You should consider using the tz database, which provides a leap-seconds table in the right/UTC timezone (and much other useful information). Thanks for the pointer. My source is the Earth Orientation Parameter (EOP) data at http://www.celestrak.com/SpaceData/; specifically I autogenerate the module from http://www.celestrak.com/SpaceData/eop19620101.txt. Probably looks more complicated than necessary but I'm parsing the file anyway for other purposes. -Bjorn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: ANN: leapseconds-announced-2009
On Sun, 2009-01-18 at 00:34 -0500, Bjorn Buckwalter wrote: Thanks for the pointer. My source is the Earth Orientation Parameter (EOP) data at http://www.celestrak.com/SpaceData/; specifically I autogenerate the module from http://www.celestrak.com/SpaceData/eop19620101.txt. Probably looks more complicated than necessary but I'm parsing the file anyway for other purposes. With tz, though, you could discover the table at run-time and so be more likely to be up to date. -- Ashley Yakeley ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functors [Comments from OCaml Hacker Brian Hurt]
On Sat, 2009-01-17 at 12:04 +, Andrew Coppin wrote: Eugene Kirpichov wrote: No, a functor is a more wide notion than that, it has nothing to do with collections. An explanation more close to truth would be A structure is a functor if it provides a way to convert a structure over X to a structure over Y, given a function X - Y, while preserving the underlying 'structure', where preserving structure means being compatible with composition and identity. As far as I'm aware, constraints like while preserving the underlying structure are not expressible in Haskell. instance (Monad m) = Functor m where fmap f ma = do a - ma; return (f a) While that's quite interesting from a mathematical point of view, how is this useful for programming purposes? Good Lord. fmap (as above) is *at least* useful enough to be in the standard library! (Control.Monad.liftM). Contrary to what some people seem to think, every single function in Haskell's standard library was included because enough people found it actually *useful* enough to add. Here's the first example I found, searching the source code for my macro language interpreter:[1] Macro-call interpolation has syntax §(expression), parsed by do char '§' lexParens $ Interpolation $ parseExpr = do char '§' lexParens $ fmap Interpolation $ parseExpr = do [2] char '§' fmap Interpolation $ lexParens $ parseExpr Useful enough? jcc [1] The only simplifications applied were (a) ignoring an interpolation syntax substantially more complicated, and (b) re-naming the relevant constructor. [2] Valid because lexParens is a natural transformation. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, 2009-01-17 at 11:07 +, Andrew Coppin wrote: Anton van Straaten wrote: Niklas Broberg wrote: I still think existential quantification is a step too far though. :-P Seriously, existential quantification is a REALLY simple concept, that you would learn week two (or maybe three) in any introductory course on logic. In fact, I would argue that far more people probably know what existential quantification is than that know what a monoid is. :-) Andrew's core objection here seems reasonable to me. It was this: {-# LANGUAGE ExistentialQuantification #-} is an absurd name and should be changed to something that, at a minimum, tells you it's something to do with the type system. But I suspect I part company from Andrew in thinking that something like ExistentiallyQuantifiedTypes would be a perfectly fine alternative. I would suggest that ExistentiallyQuantifiedTypeVariables would be an improvement on just ExistentialQuantification - but I'd still prefer the less cryptic HiddenTypeVariables. (Since, after all, that's all this actually does.) Consider the expression (I hate this expression) case error Urk! of x - error Yak! When you translate this into System F, you have to come up with a fresh type variable for the type of x, even though that variable is unused in the type of the entire expression. Which is what HiddenTypeVariables brings to my mind every time you use it. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, 2009-01-17 at 10:47 +0100, david48 wrote: On Fri, Jan 16, 2009 at 4:04 PM, Jonathan Cast jonathancc...@fastmail.fm wrote: On Fri, 2009-01-16 at 14:16 +0100, david48 wrote: Part of the problem is that something like a monoid is so general that I can't wrap my head around why going so far in the abstraction. For example, the writer monad works with a monoid; using the writer monad with strings makes sense because the mappend operation for lists is (++), now why should I care that I can use the writer monad with numbers which it will sum ? To accumulate a running count, maybe? A fairly common pattern for counting in imperative languages is int i = 0; while (get a value) i+= count of something in value Using the writer monad, this turns into execWriter $ mapM_ (write . countFunction) $ getValues well thank you for the example, if I may ask something: why would I need to write a running count this way instead of, for example, a non monadic fold, which would probably result in clearer and faster code (IMHO) ? I agree with you, for this special case. (Did I remember to post the simpler solution: sum $ map countFunction $ getValues somewhere in this thread?) But, just like the (utterly useless) C++ example translated to Haskell in another thread, the monadic form provides a framework you can fill out with larger code fragments. So if the while loop above was replaced with a larger control structure, maybe recursion over a custom tree type, then standard recusion operators, such as folds, may be inapplicable. In that case, moving to a Writer monad can get you some of the advantage back, so you don't end up passing your accumulator around everywhere by hand. jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Comments from OCaml Hacker Brian Hurt
Andrew Coppin andrewcop...@btinternet.com wrote: I would suggest that ExistentiallyQuantifiedTypeVariables would be an improvement [...] That must be a joke. Typing the long extension names in LANGUAGE pragmas over and over again is tiring and annoying enough already. We really don't need even longer names, and your improvement fills up almost half of the width of an 80 characters terminal. I can't await the next Haskell standard, where at last all those extensions are builtin. For the remaining extensions, I strongly suggest abbreviations and a more convenient way to specify them. For example an import-like statement: uses MPTC uses FlexInst instead of: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife = sex) http://blog.ertes.de/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] real haskell difficulties (at least for me)
Duncan Coutts wrote: It may well be tempting to plague maintainers until they fix their packages however in practise it will not work. We want a low barrier to entry for packages on hackage and we do not want to annoy package maintainers to the point where they decide to stop using hackage at all. +1. As a package maintainer, I love to get feedback (especially when things are broken) but I don't like being harassed. I get lots of email from all over and in order to make sure the most important things are seen soonest, routine email from bots often finds its way into filtering and rerouting... which means, whether intended or not, it often gets ignored or overlooked. After a decade or so in this game, one of the big tricks with project management (and kid yourself not, this *is* PM what Duncan et al. are so kind to take on for us) is how to balance interaction between the developers, the managers, and the clientele. The biggest trick is in that key word: interaction. When people feel put upon, ignored, or talked at (instead of talked to) then they're not interacting, not communicating, not being a part of the community. And when people aren't communicating they feel unappreciated. In the F/OSS world that means they stop contributing. Just like with friendships, jobs, and life in general, it takes a lot more work to find new developers than it does to keep the ones you have. Since life happens and you can't stop entropy, that means in turn that barriers to entry must be as low as is reasonable[1]. One of the things I've always liked about Hackage is how low the barriers are. I've also been a CPAN developer for many years, but I haven't released as much Perl code as Haskell code because it takes more work to publish a CPAN module than it does to publish a Hackage package. (Even after having accounts in both systems, of which again Hackage is easier.) Rather than just being a stick in the mud, here are some suggestions for what I, as a developer, would like to see in Hackage/Cabal/FooBlatz's future. First, I would like (via opt-in) to get periodic aggregated notice about failed builds. The simplest version of this would be sending out emails when the HackageDB build fails, rather than needing to remember to check back a while after uploading a new version. It would be nice to extend this to collect cabal-install failures, though that can get tricky about how not to harass the clientele. Minimally these aggregated reports should indicate the package and version, the problem, the Haskell compiler and its version, as well as the OS. Since some packages have many dependencies or make heavy use of the FFI, CPP, or have architecture dependent differences, it would be nice to be able to set per-package preferences to get additional information like OS version, dependency versions, CPU info, build logs, etc. Since it can be hard to set up sandboxes for every configuration, it'd also be nice if clients could opt in to send contact email as well, if they're willing to back-and-forth with the developer to fix things in the event of bugs. Second, and this would take more work, I would like it if the Haddock documentation for packages could be given a wiki-like and/or reddit-like interface so that people could make comments about what is unclear or needs better documentation as well as offering spelling/grammar/punctuation suggestions[2]. Viewers should be able to set preferences for whether they want to see the real/current documentation, or whether they want to see the commented/modified version (hiding things below a certain depth or rank for reddit-like). While building errors are an obvious point of failure, we know the design space and just need to find an elegant minimalistic solution there. I think the documentation problem is just as important a point of failure, if not more so because it is discussed less often. The solution here is harder since the design space hasn't been so thoroughly charted by previous languages. But given the very community-oriented nature of Haskell programming, it's a shame that we don't yet have a community-oriented solution to the documentation problem. The big trick will be how to both segregate and integrate community feedback and the official documentation (which should always be under the maintainer's control, hence the wiki/reddit should also be opt-in), in addition to issues about how package versioning interacts with the comments. At the same time, like QuickCheck, this strikes me as a ripe domain for killer app breakthroughs. Perhaps one of the folks working on wiki and web development tools in Haskell would like to make a name for themselves? [1] Which does not mean as low as is possible. When the barriers are too low the community can expand too quickly for the leaders to keep things functioning smoothly and cohesively. Just as with biology and finance, these population booms are just as
Re: [Haskell-cafe] Slow Text.JSON parser
Ketil Malde wrote: Sjoerd Visscher sjo...@w3future.com writes: JSON is a UNICODE format, like any modern format is today. ByteStrings are not going to work. Well, neither is String as used in the code I responded to. I'm not intimately familiar with JSON, but I believe ByteStrings would work on UTF-8 input, and both ByteString and String would fail on UTF-16 and UTF-32. ByteStrings can handle Unicode just fine, provided the right (de)serialization tools: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-light http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-string -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Sat, Jan 17, 2009 at 11:19 PM, Dan Piponi dpip...@gmail.com wrote: On Sat, Jan 17, 2009 at 1:47 AM, david48 dav.vire+hask...@gmail.com wrote: why would I need to write a running count this way instead of, for example, a non monadic fold, which would probably result in clearer and faster code? Maybe my post here will answer some questions like that: http://sigfpe.blogspot.com/2009/01/haskell-monoids-and-their-uses.html Just wow. Very very nice post. one to keep in the wikis. Thank you *very* much, Dan, for writing this. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe