gpt4 book ai didi

haskell - 将 Maybe monad 与 monadic 操作一起使用

转载 作者:行者123 更新时间:2023-12-02 06:32:35 25 4
gpt4 key购买 nike

例如当我有一个 Maybe值,我想在它是 Just 时应用一些东西或者只保留 Nothing如果它是 Nothing ,我有很多方法可以在 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'

我确定有一条更短的路,只是我现在看不到...

最佳答案

您正在从 Data.Traversable 中寻找 traverse —— 它有点像 sequence/mapM构造应用于不是列表 monad 的 monad(除了它应用于“traversables”并且适用于比“monads”弱的事物)。因此,对于您的特定情况,该功能只是:

traverseMaybe f Nothing = return Nothing
traverseMaybe f (Just x) = fmap Just (f x)

但是Data.Traversable定义了一个更通用的类:

class (Functor t, Foldable t) => Traversable t where
{-# MINIMAL traverse | sequenceA #-}

-- | Map each element of a structure to an action, evaluate these
-- these actions from left to right, and collect the results.
-- actions from left to right, and collect the results. For a
-- version that ignores the results see 'Data.Foldable.traverse_'.
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f

-- | Evaluate each action in the structure from left to right, and
-- and collect the results. For a version that ignores the results
-- see 'Data.Foldable.sequenceA_'.
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id

-- | Map each element of a structure to a monadic action, evaluate
-- these actions from left to right, and collect the results. For
-- a version that ignores the results see 'Data.Foldable.mapM_'.
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
mapM = traverse

-- | Evaluate each monadic action in the structure from left to
-- right, and collect the results. For a version that ignores the
-- results see 'Data.Foldable.sequence_'.
sequence :: Monad m => t (m a) -> m (t a)
sequence = sequenceA

这也适用于不是 monad 的应用仿函数,例如 ZipLists。

关于haskell - 将 Maybe monad 与 monadic 操作一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30124035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com