它不一定是最简单的解决方案,但我觉得强调First
Monoid
基于解决方案很重要。我觉得是最美的
import Data.Monoid
import Data.Foldable (Foldable, foldMap)
tryPick :: (a -> Maybe b) -> [a] -> Maybe b
tryPick f = getFirst . foldMap (First . f) -- this is just `foldMap f`
-- with the "firsty" Maybe Monoid
这也可以立即推广到任何Foldable
具有完全相同代码的人
tryPick :: Foldable t => (a -> Maybe b) -> t a -> Maybe b
Foldable
实例提供了使用 s 将所有元素“粉碎”在一起的方法Monoid
。First
Monoid
定义为
newtype First a = First { getFirst :: Maybe a }
是选择“第一个”或“最左边”Maybe
的操作的特化。mappend
Just
因此,将它们放在一起,getFirst . foldMap (First . f)
计算您(a -> Maybe b)
对 中所有a
s 的函数,然后将结果与“第一个”获胜[a]
的规则一起粉碎。Just