[Haskell-cafe] Monadic vs pure style (was: pros and cons of sta tic typing and side effects)

2005-08-30 Thread Bayley, Alistair
 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

2005-08-30 Thread Bayley, Alistair
 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

2005-08-30 Thread Joel Reymont
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

2005-08-30 Thread Tomasz Zielonka
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

2005-08-30 Thread Joel Reymont

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

2005-08-30 Thread Philippa Cowderoy

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)

2005-08-30 Thread Thomas Davie
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)

2005-08-30 Thread Yitzchak Gale
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

2005-08-30 Thread Dinh Tien Tuan Anh


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

2005-08-30 Thread Sebastian Sylvan
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

2005-08-30 Thread Sebastian Sylvan
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

2005-08-30 Thread Miles Sabin
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

2005-08-30 Thread Lemmih
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)

2005-08-30 Thread Ben Lippmeier



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

2005-08-30 Thread Andre Pang

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)

2005-08-30 Thread Ben Lippmeier


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

2005-08-30 Thread John Meacham
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

2005-08-30 Thread John Meacham
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)

2005-08-30 Thread John Meacham
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