A more idiomatic way to exit mapM at the beginning

Given the list of actions returning m (Maybe a), I am trying to return m (Maybe [a])where, if any of the individual results Nothing, the whole result Nothing. mcontains StateT, and I want to avoid starting any action after returning the first Nothing.

Trying to use mapM, and then moving Maybeout of the list, leads to all actions performed.

I have this solution, but the nested case statements with a lot of wrapping and expanding give me the feeling that there might be a more elegant way to do this. Usually, when I have this feeling, there is a one-line with a more general type that does the same.

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))
+4
1

, , - MaybeT.

myMapM :: Monad m => (t1 -> m (Maybe t)) -> [t1] -> m (Maybe [t])
myMapM f = runMaybeT . mapM (MaybeT . f) 
+8

Source: https://habr.com/ru/post/1677994/


All Articles