
Mark Carroll 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
participants (1)
-
Jon Cast