假设我有一个代表某些可能失败的计算的函数
f :: a -> Maybe b
如果我有一个清单l
,我可以找到列表中的第一个(从左到右扫描时)项目f
成功使用findList f l
, where findList
是下面的函数
findList :: (a -> Maybe b) -> [a] -> Maybe b
findList f [] = Nothing
findList f (x : xs) = case f x of
Nothing -> findList f xs
Just y -> Just y
(或使用,例如firstJust https://hackage.haskell.org/package/extra-1.7.9/docs/Data-List-Extra.html#v:firstJust来自extra
包裹)。
问题。
如果我想对一个人做同样的事情我该怎么办Set https://hackage.haskell.org/package/containers-0.6.4.1/docs/Data-Set.html#t:Set from containers
?
也就是说,我想要一个带有签名的函数
findSet :: (a -> Maybe b) -> Set a -> Maybe b
这相当于
findSet f s = findList f (Set.toList s)
上面的行作为一个实现。但是,我不想创建中间列表Set.toList s
(即使使用惰性求值,仍然存在一些不必要的开销,对吧?)。
一旦找到成功的项目,我也不想迭代整个集合,如以下实现所示:
findSet f s = foldl g Nothing s
where
g Nothing x = f x
g (Just y) _ = Just y
那么是否有一种好方法可以“从左到右”遍历集合,应用可能对每个成员失败的计算,并在第一个成功结果处停止?