The recursive do-notation
--------------------------
The recursive do-notation (also known as mdo-notation) is implemented
as described in:
"A recursive do for Haskell", Levent Erkok, John Launchbury",
Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania.
The do-notation of Haskell does not allow recursive bindings, that is,
the variables bound in a do-expression are visible only in the textually
following code block. Compare this to a let-expression, where bound
variables are visible in the entire binding group. It turns out that
several applications can benefit from recursive bindings in the do-notation,
and this extension provides the necessary syntactic support.
Here is a simple (yet contrived) example:
import Control.Monad.Fix
justOnes = mdo xs <- Just (1:xs)
return xs
As you can guess justOnes will evaluate to Just [1,1,1,...
The Control.Monad.Fix library introduces the MonadFix class. It's
definition is:
class Monad m => MonadFix m where
mfix :: (a -> m a) -> m a
The function mfix dictates how the required recursion operation should
be performed. If recursive bindings are required for a monad, then that
monad must be declared an instance of the MonadFix class. For details,
see the above mentioned reference.
The following instances of MonadFix are automatically provided: List,
Maybe, IO. Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy
modules provide the instances of the MonadFix class for Haskell's internal
state monad (strict and lazy, respectively).
There are three important points in using the recursive-do notation:
1. The recursive version of the do-notation uses the keyword mdo (rather
than do).
2. You should "import Control.Monad.Fix"
3. Hugs should be started with the flag -98.
The web page: "http://www.cse.ogi.edu/PacSoft/projects/rmb"
contains up to date information on recursive monadic bindings.
Historical note: The old implementation of the mdo-notation (and most
of the existing documents) used the name "MonadRec" for the class and
the corresponding library. Hugs continues to support this name
in the "old-libraries" style (i.e., with the option -N). However, this
name is now deprecated, programmers should use the name "MonadFix", and
the hierarchical library structure.