我正在进行自我练习,并想知道是否有办法只使用foldr
找到符合特定条件的列表中左起第一个项目?我希望在找到第一个项目时停止递归(我知道我可以使用take
进行组合),但我很想知道是否可以使用foldr
?
firstFind (\x -> x > 1000) [] xs
答案 0 :(得分:8)
问题:找到f
和b
。
firstFind :: (a -> Bool) -> [a] -> Maybe a
firstFind p list = foldr f b list
where f = ???
b = ???
我们希望:
firstFind p [] = Nothing
但我们也有
firstFind p []
= def. firstFind
foldr f b []
= def. foldr
b
我们从中了解b
必须是什么。
此外,请list = x:xs
firstFind p list
= def. firstFind
foldr f b (x:xs)
= def. foldr
f x (foldr f b xs)
= def. firstFind
f x (firstFind p xs)
现在,我们只需找到f
,以便选择第一场比赛。
回想一下,f
可能依赖于p
。当f
为真时,p x
应该返回什么?相反的情况呢?
where -- f :: a -> Maybe a -> Maybe a
f x y = ???
(注意:上面我为f
编写了类型签名,但是你不必将它包含在你的代码中。如果添加它,取消注释,你将会遇到类型变量混淆: a
与a
中的findFirst
不同,因为它是在本地推广的 - 因为您刚刚开始,请忽略它,暂时将其删除。)