Threading monads

Jon Cast jcast@ou.edu
Thu, 10 Apr 2003 15:27:01 -0500


Mark Carroll <mark@chaos.x-philes.com> wrote:
> I could give an example, actually, which might make things
> clearer. Take one of my unfoldM's:

> unfoldM f base =
>     do fb <- f base
>        case fb of
> 	   Nothing     -> return []
> 	   Just (a, b) -> do rest <- unfoldM f b
> 			     return (a : rest)

> Now, using the Identity monad I can write a wrapper for non-monadic
> f's:

> myUnfoldr f b =
>     runIdentity (unfoldM (return . f) b)

> which works the same as a regular unfoldr.  With a monadic function
> and a wrapper that uses the Identity monad, I can offer both monadic
> and non-monadic interfaces to the unfolding functionality that is only
> implemented once.

> Is this a good design idea? Are there better ones? Is myUnfoldr
> necessarily less efficient than a "normal" unfoldr that doesn't have
> monads underneath constraining evaluation order?

Monads don't necessarily constrain the order of evaluation.  The ID
monad, in particular, is perfectly lazy.  So, it doesn't place any more
constraints on the order of evaluation than ordinary Haskell does.
Furthermore, (although I can't check this atm) I suspect if you ask a
Haskell compiler to specialize unfoldM for ID, you'll get a version that
acts internally almost exactly like unfoldr---and that produces a
myUnfoldr implementation precisely equal to unfoldr.

Jon Cast