Given a list of actions that returns m (Maybe a)
I'm trying to return m (Maybe [a])
where if any of the individual results are Nothing
the whole result is Nothing
. m
contains StateT
and I want to avoid running any actions after the first Nothing
is returned.
Trying to use mapM
and then moving the Maybe
outside the list results in all the actions being run.
I have this solution but nested case statements with just a lot of wrapping and unwrapping gives me the feeling that there's probably a more elegant way of doing this. Usually when I have this feeling there a one-liner with a more general type that does exactly the same thing.
Any suggestions?
myMapM' :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM' f [] = return (Just [])
myMapM' f (a:as) = do
r <- f a
case r of
Nothing -> return Nothing
Just g -> do
rs <- myMapM' f as
case rs of
Nothing -> return Nothing
Just gs -> return (Just (g:gs))
The behavior you want is that of the monad transformer MaybeT
.
myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With