假设我有一个列表fns
的从部分功能a
到b
,我所代表的功能从a
到Maybe b
,并且我有一个对象x
类型的a
.假设现在我要定义另一个函数从a
到Maybe b
这需要第一的价值f x
,是不是Nothing
,如果这样的f
存在fns
,或价值Nothing
,如果没有这样的f
存在.所以基本上它f x
是第一个f
有效的输出,或者Nothing
如果没有f
效果.
提出一些能够完成这项工作的代码并不难.例如,可以创建一个列表从中[f x| f <- fns]
删除所有Nothing
s,然后取结果列表的头部,或者Nothing
如果该列表为空.但这感觉很笨拙,这似乎是一种普遍的情况,在Haskell中使用一些内置函数可以实现更加时尚的实现.如果是这样,那么我有兴趣知道它是什么.
Ale*_*lec 12
这Alternative
是为了什么.它代表选择,在这里您可以选择Maybe
值.你可以做点什么
foldr (<|>) empty [f x | f <- fns]
Run Code Online (Sandbox Code Playgroud)
在Data.Foldable
你也有asum :: (Foldable t, Alternative f) => t (f a) -> f a
更直接地做你想要的东西:
asum [f x | f <- fns]
Run Code Online (Sandbox Code Playgroud)
作为旁注,我应该注意到它MonadPlus
也为你的Maybe
实例做了你想要的.如上所述,你可以拥有
foldr mplus mempty [f x | f <- fns]
Run Code Online (Sandbox Code Playgroud)
和
msum [f x | f <- fns]
Run Code Online (Sandbox Code Playgroud)
但你应该Alternative
在这里使用IMO ,因为它更准确地传达了你的"选择"的含义.
在Data.Monoid
,被称为"一开始"行为的newtype
副本.Maybe
First
Just
如果您正在寻找类型的功能
[a -> First b] -> a -> First b
Run Code Online (Sandbox Code Playgroud)
根据你描述的行为,它就是这样
fold
Run Code Online (Sandbox Code Playgroud)
from Data.Foldable
,因为monoid行为a ->
需要逐点提升:Monoid
for a -> First b
正好选择了第一个应用结果.可悲的是(因为我的眼泪已经很多了),Maybe
而不是First
需要多做一些工作.
请注意,逐点提升,a ->
通过[]
,只是那种工作sequenceA
,所以
(asum .) . sequenceA
Run Code Online (Sandbox Code Playgroud)
会做的.
从类型中获取需要提示的monoid结构是很好的:在这种情况下,访问Alternative
行为asum
必须要做.