gpt4 book ai didi

haskell - 如何评估 Maybe 列表的最佳实践

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

我正在寻找一个函数,它接受一个函数 (a -> a -> a) 和一个 [Maybe a] 列表并返回 Maybe a。胡格尔没有给我任何有用的东西。这看起来是一个很常见的模式,所以我想问这种情况是否有最佳实践?

>>> f (+) [Just 3, Just 3]
Just 6
>>> f (+) [Just 3, Just 3, Nothing]
Nothing

提前致谢,克里斯

最佳答案

您应该首先打开 [Maybe a]进入Maybe [a]与所有Just元素(如果其中任何一个是 Nothing ,则产生 Nothing )。这可以使用 sequence 来完成,使用 Maybe 的 Monad 实例:

GHCi> sequence [Just 1, Just 2]
Just [1,2]
GHCi> sequence [Just 1, Just 2, Nothing]
Nothing

definition of sequence相当于以下内容:

sequence [] = return []
sequence (m:ms) = do
x <- m
xs <- sequence ms
return (x:xs)

因此我们可以将后一个示例扩展为:

do x <- Just 1
xs <- do
y <- Just 2
ys <- do
z <- Nothing
zs <- return []
return (z:zs)
return (y:ys)
return (x:xs)

使用do-notation expression of the monad laws ,我们可以将其重写如下:

do x <- Just 1
y <- Just 2
z <- Nothing
return [x, y, z]

如果您知道 Maybe monad 是如何工作的,那么您现在应该了解 sequence 是如何工作的。努力实现所需的行为。 :)

然后您可以使用 foldr 来编写此内容使用(<$>) (来自 Control.Applicative ;等效于 fmapliftM )将二进制函数折叠到列表上:

GHCi> foldl' (+) 0 <$> sequence [Just 1, Just 2]
Just 3

当然,您可以使用任何您想要的折叠,例如 foldr , foldl1等等

作为额外的,如果您希望结果为 Nothing当列表为空时,从而能够省略折叠的零值而不用担心空列表上的错误,那么你可以使用这个折叠函数:

mfoldl1' :: (MonadPlus m) => (a -> a -> a) -> [a] -> m a
mfoldl1' _ [] = mzero
mfoldl1' f (x:xs) = return $ foldl' f x xs

foldr 也类似, foldl等。您需要导入 Control.Monad为此。

但是,使用方式必须略有不同:

GHCi> mfoldl1' (+) =<< sequence [Just 1, Just 2]
Just 3

GHCi> sequence [Just 1, Just 2] >>= mfoldl1' (+)
Just 3

这是因为,与其他折叠不同,结果类型看起来像 m a而不是a ;它是一个绑定(bind)而不是映射

关于haskell - 如何评估 Maybe 列表的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8544278/

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