2017-05-26 24 views
4
早期

鑑於返回m (Maybe a)我試圖返回m (Maybe [a])其中,如果任何單個的結果是Nothing整個結果是Nothing的行動清單的更地道的方式。 m包含StateT和我想避免運行任何動作則返回第一個Nothing後。退出MAPM

嘗試使用mapM,然後將Maybe移動到列表的外部會導致所有正在運行的操作。

我有這樣的解決方案,但只用了很多包裝的嵌套的case語句和去包裹給我的感覺,有可能是這樣做的更優雅的方式。通常當我有這種感覺,有一個班輪具有更普遍的類型不完全一樣的東西。

有什麼建議嗎?

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)) 

回答

8

你想要的行爲是the monad transformer MaybeT

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

是啊,這確實起作用。還有我懷疑存在的一行代碼。謝謝。 –