RE [Haskell-cafe] Monad Description For Imperative Programmer

alpheccar misc at alpheccar.org
Wed Aug 1 13:13:15 EDT 2007


> Kaveh> "A monad is like a loop that can run a new function against  
> its variable in each iteration."
>
> I’m an imperative programmer learning Haskell, so I’m a newbie,  
> but I’ll give it a try ☺ Making mistakes is the best way to  
> learn it ;)
>

I was a newbie not so long ago so I can understand the trouble of  
imperative programmers when they meet monads for the first time. I  
think the problem is due to a few bad tutorial still available on the  
web and which are making two mistakes:

1 - Focusing on the IO monad which is very special ;
2 - Detailing the implementation. As a newie we don't care and we  
would prefer to see how to use monads rather than how to develop monads.

When you look at monads you see they can be used for controlling the  
evaluation order (list monad, error monad, IO monad). They can be  
used for side effects (IO, state monad). They can be seen as  
containers (list, Maybe). They can be used to provide a protected  
environment (tainting). So, it is difficult to see what they have in  
common. Of course, what they have in common is a set of algebraic  
laws : the monadic laws but it does not help to know it.

I think that a way to see monads (and a consequence of the monadic  
laws) is that monads are interpreters for domain specific languages.  
Each monad will generally come with a runMonad function (runReader,  
runWriter etc...) to execute the monadic program. IO is different  
because runIO is controlled by the runtime and cannot be manipulated  
by the user.

The monadic combinators >>= are used to build programs. It is a way  
to concatenate two small programs to create a bigger one.
In fact a combinator like >>= is doing two things : building new  
sentences of your domain specific language and evaluating them.

if you take the list monad as example : [1,2,3] >>= \x -> [x*2,x*3].

First a new sentence will be created : [[2,3],[4,6],[6,9]]. Then, it  
is evaluated to give [2,3,4,6,6,9].

Here the interesting part is the sentence construction one. In other  
monads it may be the evaluation one.

So, instead of building a big sentence and then evaluating it, a  
monad is a dynamical interpreter. The sentences are built and  
evaluated progressively.

But of course, as I said, I was a newbie not long ago so the experts  
will correct me if needed.

Now, a bit of self promotion but just because it may help. I have  
summarized the problems I faced when I was a newbie learning  
Haskell : http://www.alpheccar.org/en/posts/show/67
Some people told me it was useful. It is a summary of how imperative  
programmers should change their state of mind to understand the  
Haskell way.

alpheccar.

> There are lots of different kinds of monads, but let’s stick to  
> the IO monad first, which you seem to refer to.
>
> No *an IO monad is not a loop at all*. Instead, from an imperative  
> programmer’s point of view, the following might be better:
>
> “an IO monad is a delayed action that will be executed as soon as  
> that action is needed for further evaluation of the program.”
>
> The simple program
>
> main = getLine >>= putStrLn
>
> can be visually represented as (see attachment)
>
> The “world” (=a representation of your computer’s hardware) is  
> passed to the main function, which passes it to all actions that it  
> encounters during its lazy evaluation, causing the executing of the  
> actions as an effect.
>
> The red wire through which the “world flows” is a “single  
> thread”, it cannot be split (because the physical world cannot be  
> copied!!!), so no unwanted side effects can ever occur, making IO  
> safe in Haskell.
>
> When you write your IO program, this world object is never  
> available (the IO type is a special internal type), so the red wire  
> is erased from the diagram, and the getLine and putStrLn boxes  
> become “delayed actions”.
>
> Imperative programmers like myself might initially be confused when  
> they see Haskell’s do notation, because it looks like the actions  
> are strict statements as in C/C++/Pascal/Java/C#/etc, but they are  
> not.
>
> For example, try the following program:
>
> main = do last [
>            putStrLn "NOT executed although it is first in the list,  
> as it is not used by the main function!",
>            putStrLn "This action IS executed because it is  
> evaluated by the main function." ]
>
> This is of course all due to Haskell’s laziness which only  
> evaluates just those expressions that it needs to evaluate the main  
> function.
>
> One thing to note in the diagram above is that the getLine box has  
> TWO outputs, the String and the World. But functions can only have  
> a single output, but this can be tuple. Hence the passing of the  
> world from one box to the other is a bit more complicated. It is  
> this pattern of extracting both values from the output and passing  
> them to the next function and other related combinations that form  
> the generic monad class, which can be used for many more things  
> than IO.
>
> See http://haskell.org/haskellwiki/IO_inside for a much deeper and  
> more correct explanation ☺
>
> And for the pros here, did this newbie make any sense? Probably  
> not ;-)
>
> Oh no, yet another monad explanation!!! Now the universe will most  
> certainly collapse…
>
>
> No virus found in this outgoing message.
> Checked by AVG Free Edition.
> Version: 7.5.476 / Virus Database: 269.11.0/929 - Release Date:  
> 31/07/2007 17:26
>
>
> <IO monad.GIF>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list