Re: monad thinking process

2002-01-25 Thread Ronald Legere

Cagdas,
Is it possible for you to give an
example where you think there is too much thinking
involved? I dont see it.
Writing haskell IO with monads
(with the Do notation) is just a straightforward as
writing C code for the same steps, isnt it? Just try
not to think about it too much :)

Cheers!

--- Cagdas Ozgenc [EMAIL PROTECTED] wrote:
 Greetings.
 
 I have very little experience with monads. However
 my first impression is
 that there is too much thinking process involved in


__
Do You Yahoo!?
Great stuff seeking new owners in Yahoo! Auctions! 
http://auctions.yahoo.com

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



Re: monad thinking process

2002-01-25 Thread Andre W B Furtado

Just check this monad tutorial (attached). It's really great for beginners.

-- Andre

---BeginMessage---




-- Forwarded message --
Date: Tue, 05 Jun 2001 11:26:12 -0300
From: Andre Santos [EMAIL PROTECTED]
Newsgroups: depto.cursos.grad.if098
Subject: Monads for the Working Haskell Programmer

http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm

Title: Monads for the Working Haskell Programmer






Monads for the Working Haskell Programmer 
-- a short tutorial.

Theodore Norvell
Memorial University of Newfoundland

New: Updated to Haskell '98.

This short tutorial introduces monads to Haskell programmers. It applies to Haskell
'98. Gofer programmers (are there any left?) can read it too; there is a section at the
end detailing the differences between Haskell and Gofer around monads and another about
the differences between Haskell 1.3, Haskell 1.4, and Haskell 98.

The reader is assumed to have a familiarity with the basics of Haskell programming such
as data declarations, function definitions, and lambda expressions. Familiarity with
classes and instance declarations will help.

Simulating states without Monads

Consider the following function

f1 w a = let (b, x) = g1 w a
 (c, y) = h1 w x b
 (d, z) = i1 w x y c
in (d, z)

where a, b, c, and d all have the same type, State.
 In a sense this definition is very similar to an imperative program in which a
represents the initial state, d represents the final state, and b and c
represent intermediate states. The functions f1 w, g1 w, h1 w x,
and i1 w x y can be thought of as imperative routines that transform the state
and produce results. The results are like the return values in C programs and are bound to
variables x, y, and z in the example. A C routine that
corresponds to this would look something like this:

int f1(float w) {
const char   x = g1(w) ;
const double y = h1(w, x) ;
const intz = i1(w, x, y) ;
return z ; }

All this explicit passing of states around can get a bit tedious, especially when
programs are modified. It also makes the program hard to read vs. the equivalent C
program. 

Note that if we ignore the w, x, y, and z, then g1,
h1, and i1 are being composed. Can we define a kind of composition
operator that allows us to deal with the returned values as well as the state?

Simulating states with Monads

The functions that transform the state in the example above all have the type State
- (State, a) for some result type a. Let's generalize over the type of
the state and create a type to represent these transforms

type StateTrans s a = s - (s, a)

Let us define two functions. The first is a kind of composition function.

(=) :: StateTrans s a -
 (a - StateTrans s b) -
 StateTrans s b

p = k  =  \s0 - let (s1, a) = p s0
   q = k a
   in q s1

The second is a function that turns a value into an imperative program that
does not change the state, but returns the result.

return :: a - StateTrans s a

return a = \s - (s, a)

Our original function may now be written with all the shunting of state around hidden
by these operators:

f w = (g w) = (\x - (h w x) = (\y - (i w x y) = (\z - return z)))

You could also format this as follows

f w = g w = \x -
  h w x = \y -
  i w x y = \z -
  return z

You should verify that f is equal to f1, if g = g1, h =
h1, and i = i1.

(Warning, if you really try to make the above definitions of = and return,
your Haskell compiler will complain, for reasons that will be explained later. However,
you could try changing the names a little, e.g. change = to ==
and change return to rtn.)

A nicer syntax

Now Haskell provides a nice syntax to sugar-coat the calls to =. It
turns out that the definition of f can also be written as

f w = do x - g w
 y - h w x
 z - i w x y
 return z

The do is a keyword of Haskell. Any program involving a do can
be translated to one that doesn't use do by the following 4 rules:

1 An expression


  
do
pattern - expression
  
  

morelines
  


becomes expression = (\ pattern - do morelines)

2 An expression


  
do
expression
  
  

morelines
  


becomes expression  do morelines

3 An expression 


  
do
let declarationList
  
  

morelines
  


becomes 


  
let
declarationList
  
  
in
do morelines
  


4. Finally when there is only one line in the do, an expression


  
do
expression
  


becomes expression

In the second rule, we saw the  operator; this is used when the result of the
first operand is not subsequently used. It can always be defined as

p  q  =  p = (\ _ - q)

So

do p
   q

is the same as

do _ - p
   q

The do notation follows the same conventions as other multi-line constructs
in Haskell. All lines must be vertically alligned. Alternatively, you may use braces and
semicolons if you prefer free format:

do {x - g w ;