[Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
From: Martin Vlk [mailto:[EMAIL PROTECTED] http://www-i2.informatik.rwth-aachen.de/Staff/Current/michaelw/sttt-ml-haske ll.pdf This quote from the paper resonated with me: Also, if imperative elements of a given application were not taken into account during its design but turn out to be necessary later on, often major parts have to be redesigned or (at least) reimplemented, especially because types change significantly. A simple but recurring example is to add printing of status information to an otherwise purely functional algorithm. In the worst case this could result in having to rewrite the algorithm in a monadic style, but also to rewrite its callers (and transitively their callers as well), plus adjusting all type annotations on the way. Even when using opaque accessors to data structures, the required changes cannot necessarily be limited to a single module, but affect large parts of the system. The difficulty seems to be when you want to turn code that was initially pure into monadic code: it requires a fairly substantial rewrite. Once in a monadic style, I expect it is much easier to add various monadic/imperative enhancements. I've experienced this recently, where I've converted an algorithm from a purely functional version, using immutable arrays, to a monadic version using destructive arrays. I introduced errors with the conversion, and the unit test suite that I had for the pure version also had to be converted to a monadic style, in order to test the now-monadic code. So having to perform this conversion is clearly undesirable. I'm reminded of Wadler's Monads for functional programming (http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/marktoberdorf.pdf ) where he illustrates how easy it is to extend a program written in a mondadic style. So this begs the question: how much should we stick to a purely functional style? Should we advocate the adoption of a more monadic style from the outset, for programmers new to Haskell too? Alistair. - * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Haskell poker server
From: Cale Gibbard [mailto:[EMAIL PROTECTED] Well, here's an attempt at a start on a similar mechanism for Haskell: -- (start Packet.hs) module Packet where import Data.Bits import Data.Word class Packet a where readPacket :: [Word8] - (a, [Word8]) ... There's a request on LtU for a similar ability (somewhat wider in scope, perhaps): http://lambda-the-ultimate.org/node/view/938 There must be a gap in the market :-) Alistair. - * Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. * ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
Erlang does this nicely, I replied to the LtU thread. I positively got the impression that nobody was parsing binary data in Haskell ;). On Aug 30, 2005, at 12:29 PM, Bayley, Alistair wrote: There's a request on LtU for a similar ability (somewhat wider in scope, perhaps): http://lambda-the-ultimate.org/node/view/938 There must be a gap in the market :-) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
On Tue, Aug 30, 2005 at 12:41:20PM +0200, Joel Reymont wrote: Erlang does this nicely, I replied to the LtU thread. I positively got the impression that nobody was parsing binary data in Haskell ;). I am doing this quite often, I apologize for not sharing my experience and promise to improve ;-) BTW, if efficiency is not a primary concern, Parsec can be quite nice for decoding binary messages of many protocols. Best regards Tomasz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
Can I beg for examples? On Aug 30, 2005, at 1:29 PM, Tomasz Zielonka wrote: BTW, if efficiency is not a primary concern, Parsec can be quite nice for decoding binary messages of many protocols. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
On Tue, 30 Aug 2005, Tomasz Zielonka wrote: On Tue, Aug 30, 2005 at 12:41:20PM +0200, Joel Reymont wrote: Erlang does this nicely, I replied to the LtU thread. I positively got the impression that nobody was parsing binary data in Haskell ;). I am doing this quite often, I apologize for not sharing my experience and promise to improve ;-) BTW, if efficiency is not a primary concern, Parsec can be quite nice for decoding binary messages of many protocols. I'd quite like to see some benchmarks for Parsec parsers compiled with jhc, I can't help thinking that the optimisations involved would make them go much faster. Not really practical right here and right now AFAIK, but hey. -- [EMAIL PROTECTED] Ivanova is always right. I will listen to Ivanova. I will not ignore Ivanova's recomendations. Ivanova is God. And, if this ever happens again, Ivanova will personally rip your lungs out! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
On Aug 30, 2005, at 12:13 PM, Bayley, Alistair wrote:From: Duncan Coutts [mailto:[EMAIL PROTECTED]] This is often a misconception, that just because you find you need to'do' something in the middle of your algorithm, that you need to convert it wholly to monadic style. Yes. However, Wadler makes a convincing (at least to me) case that themonadic style is easier to extend. The code changes for the monadic styleappear to be more localised.Something else I noticed about my non-monadic code was the way I wasthreading state through functions. I was tempted to introduce a State monadto make this easier to manage, but then I decided to try mutable arraysinstead, so that experiment was not attempted. So it might well have beenbetter in monadic style anyway, even with immutable arrays.I'm conscious that for most (?) monads, monadic code can be invoked fromnon-monadic code. I'm only aware of the IO monad as a one-way trap. Sochanging code from pure to monadic doesn't necessarily involve program-widechanges, unless the monad you're introducing happens to be IO. In my arrayexample, I introduced STArrays, but the main interface remained pure(non-monadic), which was my goal.I was also wondering what the disadvantages of monadic style are? Are therecompiler optimisations which are not possible with monadic code?Both the advantage and the disadvantage is that you break lazy evaluation. 90% of the time lazyness is your friend and monadifying your code can break some nice features, but there is an occasional 10% of the time when it's useful to break lazyness.On a side note, whenever I find myself tempted to pass state around, I consider whether using CPS is better... It provides some method of ordering code, but doesn't break lazyness.Just 2¢ from a relative newbie.Bob___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
There seems to be a misconception in this thread that there is something non-functional or imperative about using monads. That is simply not true. When what you are trying to write is most naturally and clearly expressed as a series of steps - there is no reason not to use a monad. Even when a function is most naturally written as purely recursive, in real-life code you often add Monad m = to the type signature and wrap the function in a return. This is primarily so that you can propagate exceptions. (I personally am not so impressed by the refactoring fears in the referenced paper, but yes, that is another reason.) True, there are a few rare monads that have non-lazy semantics; IO and ST come to mind. So I avoid those unless absolutely necessary. On Tue, Aug 30, 2005 at 12:40:27PM +0100, Thomas Davie wrote: On Aug 30, 2005, at 12:13 PM, Bayley, Alistair wrote: Something else I noticed about my non-monadic code was the way I was threading state through functions. That was the classical way of doing state in functional languages, but in my opinion it is very bad style in modern Haskell. I was tempted to introduce a State monad... Right! I was also wondering what the disadvantages of monadic style are? Both the advantage and the disadvantage is that you break lazy evaluation. Not true. Only if you use a non-lazy monad, like IO or ST. There is no inherent advantage or disadvantage to monads. If the idea is most clearly expressed as a monad, use a monad. If the idea is most clearly expressed recursively, write it recursively (but perhaps wrap it in return). Using that philosophy, I find that quite a bit of my code is monadic - most commonly State and StateT - and still perfectly functional and lazy. 90% of the time lazyness is your friend... but there is an occasional 10% of the time when it's useful to break lazyness. I find the percentage much higher than 90%. ...monadifying your code can break some nice features,... I do not know of any features it breaks. On a side note, whenever I find myself tempted to pass state around, I consider whether using CPS is better... I do not know how it could ever make sense to use CPS, except for a research project that explicitly requires it. (Yes, I know about callCC. I use a much simpler and clearer Exit monad instead.) -Yitz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] List of functions
Hi, Basically, i have several rules: f1 x y ... f2 x y ... . They are all of the same type, but different names because i'll later on launch one thread for each of them, i.e: forkIO (f1 x y) forkIO (f2 x y) . There maybe still more rules, and i dont want to manually writing forkIO ... for every new one. So is there an elegant way to put all those rules together in a list and then call mapIO forkIO just once, (of course, a new rule should be attached to the list as well) ? Thanks a lot TuanAnh _ Winks nudges are here - download MSN Messenger 7.0 today! http://messenger.msn.co.uk ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] List of functions
On 8/30/05, Dinh Tien Tuan Anh [EMAIL PROTECTED] wrote: Hi, Basically, i have several rules: f1 x y ... f2 x y ... . They are all of the same type, but different names because i'll later on launch one thread for each of them, i.e: forkIO (f1 x y) forkIO (f2 x y) . There maybe still more rules, and i dont want to manually writing forkIO ... for every new one. So is there an elegant way to put all those rules together in a list and then call mapIO forkIO just once, (of course, a new rule should be attached to the list as well) ? Thanks a lot TuanAnh _ Winks nudges are here - download MSN Messenger 7.0 today! http://messenger.msn.co.uk ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] List of functions
On 8/30/05, Dinh Tien Tuan Anh [EMAIL PROTECTED] wrote: Hi, Basically, i have several rules: f1 x y ... f2 x y ... . They are all of the same type, but different names because i'll later on launch one thread for each of them, i.e: forkIO (f1 x y) forkIO (f2 x y) . There maybe still more rules, and i dont want to manually writing forkIO ... for every new one. So is there an elegant way to put all those rules together in a list and then call mapIO forkIO just once, (of course, a new rule should be attached to the list as well) ? Thanks a lot TuanAnh Something like (untested)... xs - zipWith ($) forkIO (map (\f - f x y) funs) tids - sequence xs /S /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
Joel Reymont wrote, Can I beg for examples? I've been using parsec for binary parsing (Java class files in my case) as a first exercise with both Haskell and combinator parsing, with a view to applying same to network protocols. The experience has been surprisingly pleasant. In particular, it handles the common count, count*tokens idiom that's found in many binary formats and network protocols very smoothly ... something I've always had to code by hand. Being so new to Haskell I'm hesitant to give possibly bad examples, but how about something like this, constantPoolEntry :: Parser ConstantPoolEntry constantPoolEntry = do { u1Literal 1 ; bytes - u2 = (flip count $ u1) ; return (ConstantUTF8 (decodeUTF8 bytes)) } | -- etc. ... where u1Literal matches the byte '1' from the input, and u2 parses a following 2 byte unsigned integer byte-count which is then used to construct a parser of exactly byte-count bytes, ie. it matches the byte sequence, '1', n, b0 ... bn-1 I'm not aware of any other general purpose parsing framework which can do this anything like as deftly. Cheers, Miles ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] List of functions
On 8/30/05, Sebastian Sylvan [EMAIL PROTECTED] wrote: On 8/30/05, Dinh Tien Tuan Anh [EMAIL PROTECTED] wrote: Hi, Basically, i have several rules: f1 x y ... f2 x y ... . They are all of the same type, but different names because i'll later on launch one thread for each of them, i.e: forkIO (f1 x y) forkIO (f2 x y) . There maybe still more rules, and i dont want to manually writing forkIO ... for every new one. So is there an elegant way to put all those rules together in a list and then call mapIO forkIO just once, (of course, a new rule should be attached to the list as well) ? Thanks a lot TuanAnh Something like (untested)... xs - zipWith ($) forkIO (map (\f - f x y) funs) tids - sequence xs or: 'mapM_ [ f x y | f - rules ]' -- Friendly, Lemmih ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
There is no inherent advantage or disadvantage to monads. If the idea is most clearly expressed as a monad, use a monad. If the idea is most clearly expressed recursively, write it recursively (but perhaps wrap it in return). Perhaps the inherent disadvantage is that functions written in the monadic style must have different types compared with their conceptually similar non-monadic functions.. mapM:: Monad m = (a - m b) - [a] - m [b] map :: (a - b) - [a] - [b] filter :: (a - Bool) - [a] - [a] filterM :: (Monad m) = (a - m Bool) - [a] - m [a] foldl :: (a - b - a) - a - [b] - a foldM :: (Monad m) = (a - b - m a) - a - [b] - m a Some would say but they're different functions!, others would say close enough. I imagine this would be an absolute pain for library writers. Notice that we get Data.Map.map but no Data.Map.mapM - or perhaps there's some magical lifting combinator that I am not aware of? Ben. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell poker server
On 31/08/2005, at 7:37 AM, Miles Sabin wrote: I've been using parsec for binary parsing (Java class files in my case) as a first exercise with both Haskell and combinator parsing, with a view to applying same to network protocols. I've also been experimenting with using Parsec to parse binary files. The biggest problem with is that it's a slow, because you're working with types of [Char] rather than e.g. UArray Word8. This is usually fine if you're doing on-the-fly processing or are working with small files, but in my case, I was working with 1GB+ video files. Having over 1,000,000 list cells of one character each gets a tad slow :). I did a little bit of work (with emphasis on 'little') to start refactoring Parsec so it can work with generic sequences instead of just lists (so you can make it work with arrays), but haven't gotten too far. Having Parsec work speedily with binary files would absolutely rock -- I suspect there are a lot of people who've never thought about using parser combinators to process binary data, and if it's a feasible option ... -- % Andre Pang : trust.in.love.to.save http://www.algorithm.com.au/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
Perhaps you could write _everything_ in monadic style, and then derive the non-monadic version by running it on an empty state monad. But then if everything was already monadic you wouldn't need the non-monadic version.. :) ... Perhaps the inherent disadvantage is that functions written in the monadic style must have different types compared with their conceptually similar non-monadic functions.. mapM:: Monad m = (a - m b) - [a] - m [b] map :: (a - b) - [a] - [b] filter :: (a - Bool) - [a] - [a] filterM :: (Monad m) = (a - m Bool) - [a] - m [a] foldl :: (a - b - a) - a - [b] - a foldM :: (Monad m) = (a - b - m a) - a - [b] - m a Some would say but they're different functions!, others would say close enough. I imagine this would be an absolute pain for library writers. Notice that we get Data.Map.map but no Data.Map.mapM - or perhaps there's some magical lifting combinator that I am not aware of? Ben. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
On Mon, Aug 29, 2005 at 01:08:31AM +0200, Joel Reymont wrote: Alistair, Thanks alot for your examples. I still have one unanswered question... How would you read a tuple of values (24, GID, Seq) like in my Erlang example, where 24 is one byte, GID is a 4-byte integer and Seq is a 2- byte word? Is there an elegant way of specifying packet format and reading/writing Haskell data according to it? If you don't actually need a binary format (or don't care about the format) you can use the 'Show' and 'Read' classes to turn values into strings and back again. so, you would do a show on one side and send the string, and then on the other side 'read' it and you will get the same value out. Instances exist for all built in types where it makes sense, and you can automatically derive instances for your own types. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell poker server
On Tue, Aug 30, 2005 at 12:35:30PM +0100, Philippa Cowderoy wrote: On Tue, 30 Aug 2005, Tomasz Zielonka wrote: On Tue, Aug 30, 2005 at 12:41:20PM +0200, Joel Reymont wrote: Erlang does this nicely, I replied to the LtU thread. I positively got the impression that nobody was parsing binary data in Haskell ;). I am doing this quite often, I apologize for not sharing my experience and promise to improve ;-) BTW, if efficiency is not a primary concern, Parsec can be quite nice for decoding binary messages of many protocols. I'd quite like to see some benchmarks for Parsec parsers compiled with jhc, I can't help thinking that the optimisations involved would make them go much faster. Not really practical right here and right now AFAIK, but hey. I'll work on it :). it does seem to behave particularly well on failable state monads like the Maybe monad so should do well with parsec too. I have not figured out why, I think it is due to my CPR being generalized to work on non-CPR types as long as they are used in a CPR fashion (the vast majority of functions in such monads are of the 'successful' variety). This optimazation can most likely be ported to ghc easily and it appears to be a big win in certain situations. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)
On Tue, Aug 30, 2005 at 12:55:55PM +0200, Henning Thielemann wrote: The disadvantage of pure functional code is certainly the danger of being forced to rewrite it to monadic code in the future. But there is a big advantage of pure functional code: It gives the guarantee about data dependencies to the user. In many cases Haskell provides a pure functional way out of the decision monadic or pure: You can write your functions in a way that they return intermediate data in some data structure. Then it is easy to pull them out for output. Also, the ability to recognize when something might need to be monadic or that it will always be pure is a skill you eventually learn as you use haskell. I know that the same issue bothered me a lot in the past, but it comes up less and less nowadys. A useful skill is to know the monad template library well. collecting up a list? use MonadWriter instead of manually concatting the list and your code is still pure and often a lot clearer. if you need some other monadic functionality in the future, it is just a matter of changing a type signature or two and applying the right monad transformer. the contention isn't between 'monads vs. pure' it is 'uses IO vs. pure', monads, like many powerful abstractions, are very useful in making pure code more concise, clear and flexible. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe