mokus0 / monad-loops

Some useful control operators for looping

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why does unfoldrM' use MonadPlus?

nh2 opened this issue · comments

unfoldrM' :: (Monad m, MonadPlus f) => (a -> m (Maybe (b,a))) -> a -> m (f b)
unfoldrM' f = go
    where go z = do
            x <- f z
            case x of
                Nothing         -> return mzero
                Just (x, z')    -> do
                        xs <- go z'
                        return (return x `mplus` xs)

MonadPlus here is used as "a container". I think that this might be an accident, and that actually Monoid was the original intention - it is the "appendable container".

To support my idea that the author might have wanted to use a Monoid, see how we're never actually using the fact that f is a Monad? We're only using mzero and mplus, but no monadic bind, which is analogue to Monoid's mempty and mappend.

What do you think?

Another example: Set, a container that one might want to use to collect the results, is a Monoid, but not a MonadPlus.

Set is kinded * -> * and consequently cannot be a Monoid. However, Set a does form a Monoid. The author probably wanted to avoid FlexibleContexts.

That was definitely part of it, another part is for consistency within the families of names - if it were using Monoid, the provided function f would have to return an element of the monoid rather than an instance of the thing contained.

There are probably better fits than MonadPlus these days, especially somewhere within Ed Kmett's vast empire of abstractions, but this is a pretty old library and given the simplicity of what it does I like the fact that it's compatible with such a wide range of GHC versions. Preserving that isn't a primary goal, but it also isn't something I'd like to throw away without a pretty compelling benefit. Pulling in another dependency for a better abstraction would also dramatically increase the footprint of what is currently a very lightweight library, and likely reduce the range of GHC versions it runs on.