如何评估 Maybe 列表的最佳实践
我正在寻找一个函数,它接受一个函数 (a -> a -> a) 和一个 [Maybe a] 列表并返回 Maybe a。胡格尔没有给我任何有用的东西。这看起来是一个很常见的模式,所以我想问这种情况是否有最佳实践?
>>> f (+) [Just 3, Just 3]
Just 6
>>> f (+) [Just 3, Just 3, Nothing]
Nothing
提前致谢,克里斯
i am looking for a function which takes a function (a -> a -> a) and a list of [Maybe a] and returns Maybe a. Hoogle gave me nothing useful. This looks like a pretty common pattern, so i am asking if there is a best practice for this case?
>>> f (+) [Just 3, Just 3]
Just 6
>>> f (+) [Just 3, Just 3, Nothing]
Nothing
Thanks in advance, Chris
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该首先将
[Maybe a]
转换为包含所有Just
元素的Maybe [a]
(产生Nothing 如果其中任何一个是
Nothing
)。这可以使用 sequence,使用 Maybe 的 Monad 实例:
序列的定义 等价于以下内容:
因此我们可以将后一个示例扩展为:
使用 monad 法则的 do-notation 表达式,我们可以将其重写如下:
如果你知道 Maybe monad 是如何工作的,你现在应该明白
sequence
是如何实现的这期望的行为。 :)然后,您可以使用
(<$>)
(来自 Control.Applicative;相当于fmap或
liftM
)将二进制函数折叠到列表上:当然,您可以使用任何您想要的折叠,例如
foldr
、foldl1
等 另外,如果您希望列表为空时结果为
Nothing
,从而能够省略折叠的零值而不用担心空列表上的错误,那么您可以使用 .这个折叠函数:和类似的
foldr
、foldl
等。您需要导入 Control.Monad 为此。然而,它的使用方式必须略有不同:
or
这是因为,与其他折叠不同,结果类型看起来像
m a
而不是a
;它是一个绑定而不是映射。You should first turn the
[Maybe a]
into aMaybe [a]
with all theJust
elements (yieldingNothing
if any of them areNothing
).This can be done using sequence, using Maybe's Monad instance:
The definition of sequence is equivalent to the following:
So we can expand the latter example as:
Using the do-notation expression of the monad laws, we can rewrite this as follows:
If you know how the Maybe monad works, you should now understand how
sequence
works to achieve the desired behaviour. :)You can then compose this with
foldr
using(<$>)
(from Control.Applicative; equivalently,fmap
orliftM
) to fold your binary function over the list:Of course, you can use any fold you want, such as
foldr
,foldl1
etc.As an extra, if you want the result to be
Nothing
when the list is empty, and thus be able to omit the zero value of the fold without worrying about errors on empty lists, then you can use this fold function:and similarly for
foldr
,foldl
, etc. You'll need to import Control.Monad for this.However, this has to be used slightly differently:
or
This is because, unlike the other folds, the result type looks like
m a
instead ofa
; it's a bind rather than a map.据我了解,您想要获得一堆可能的总和,或者如果其中任何一个是
Nothing
,则Nothing
。这实际上非常简单:您可以将其概括为:
当与
Maybe
monad 一起使用时,f
完全按照您想要的方式工作。如果您关心空列表,可以使用此版本:
As I understand it, you want to get the sum of a bunch of maybes or
Nothing
if any of them areNothing
. This is actually pretty simple:You can generalize this to something like:
When used with the
Maybe
monad,f
works exactly the way you want.If you care about empty lists, you can use this version:
或者
,通过使用
(+)
:那么,
maybeSum = fmap sum 。序列
。What about something as simple as:
Or, by using
(+)
:So,
maybeSum = fmap sum . sequence
.