[Haskell-cafe] Lazy Evaluation in Monads

Scott Lawrence bytbox at gmail.com
Tue May 31 21:49:02 CEST 2011

I was under the impression that operations performed in monads (in this
case, the IO monad) were lazy. (Certainly, every time I make the
opposite assumption, my code fails :P .) Which doesn't explain why the
following code fails to terminate:

  iRecurse :: (Num a) => IO a
  iRecurse = do
    recurse <- iRecurse
    return 1

  main = (putStrLn . show) =<< iRecurse

Any pointers to a good explanation of when the IO monad is lazy?

=== The long story ===

I wrote a function unfold with type signature (([a] -> a) -> [a]), for
generating a list in which each element can be calculated from all of
the previous elements.

  unfold :: ([a] -> a) -> [a]
  unfold f = unfold1 f []

  unfold1 :: ([a] -> a) -> [a] -> [a]
  unfold1 f l = f l : unfold1 f (f l : l)

Now I'm attempting to do the same thing, except where f returns a monad.
(My use case is when f randomly selects the next element, i.e. text
generation from markov chains.) So I want

  unfoldM1 :: (Monad m) => ([a] -> m a) -> [a] -> m [a]

My instinct, then, would be to do something like:

  unfoldM1 f l = do
    next <- f l
    rest <- unfoldM1 f (next : l)
    return (next : rest)

But that, like iRecurse above, doesn't work.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 900 bytes
Desc: OpenPGP digital signature
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110531/9f4672af/attachment.pgp>

More information about the Haskell-Cafe mailing list