使用带有monadic动作的Maybe monad

时间:2015-05-08 12:35:41

标签: haskell

当我有一个Maybe值时,如果它是Just我希望在其上应用某些内容,或者如果它是Nothing则只保留Nothing 1}},我有很多方法可以在haskell中实现这一点。但是,当我想要采用monadic动作时,我没有找到简洁的方法。

在此代码中,要获得d,我可以使用fmap。但是我无法使用它来获取c,因为那个需要monadic(在这种情况下为IO)操作才能应用Maybe中的值。

import Control.Applicative

main = do
    let x = Just "test.txt"
    let d = reverse <$> x -- good
    print d
    c <- case x of -- verbose
     Nothing -> return Nothing
     Just y -> Just <$> readFile y
    print c

这是一种可行的方式,但它也过于冗长。

    c' <- maybe (return Nothing) (\a -> Just <$> readFile a) x
    print c'

我确定有更短的路,我现在无法看到它......

2 个答案:

答案 0 :(得分:6)

您正在寻找来自traverse的{​​{1}} - 它是一种Data.Traversable / sequence构造应用于不是列表monad的monad(除了它已应用) “traversables”,适用于比“monads”弱的东西。因此,对于您的特定情况,该功能只是:

mapM

但是traverseMaybe f Nothing = return Nothing traverseMaybe f (Just x) = fmap Just (f x) 定义了一个更通用的类:

Data.Traversable

这也适用于不是monad的applicative functor,比如ZipLists。

答案 1 :(得分:3)

traverse在这里做你想做的事:

c' <- traverse readFile x
print c'