mokus0 / monad-loops

Some useful control operators for looping

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unexpected change in the behavior of unfoldrM (ignores new seed)

sabauma opened this issue · comments

The new definition of unfoldrM' ignores the new generator (second value of the
tuple). This results in the first argument function being called with the seed
value every time. This seems like undesirable behavior.

-- |See 'Data.List.unfoldr'.  This is a monad-friendly version of that, with a
-- twist.  Rather than returning a list, it returns any MonadPlus type of your
-- choice.
unfoldrM' :: (Monad m, MonadPlus f) => (a -> m (Maybe (b,a))) -> a -> m (f b)
unfoldrM' f z = go
    where go = do
            x <- f z
            case x of
                Nothing         -> return mzero
                Just (x, z)     -> do
                        xs <- go            -- < Call ignores the new z
                        return (return x `mplus` xs)

This seems like the correct version

-- |See 'Data.List.unfoldr'.  This is a monad-friendly version of that, with a
-- twist.  Rather than returning a list, it returns any MonadPlus type of your
-- choice.
unfoldrM :: (Monad m, MonadPlus f) => (a -> m (Maybe (b,a))) -> a -> m (f b)
unfoldrM f z = go z
    where go z = do
            x <- f z
            case x of
                Nothing         -> return mzero
                Just (x, z)     -> do
                        xs <- go z          -- < Call uses the new z
                        return (return x `mplus` xs)

Sorry to take so long to look at this, I haven't looked at my github account in over a month because I've been extremely busy. Good catch, I've just fixed it.

It would be nice to have it in hackage. I've just spent several crazy hours because of this issue