以递归方式正确编写存在函数

时间:2017-05-24 10:16:52

标签: haskell recursion

如何修复此exists'函数以使其按要求运行?

测试列表中的任何元素是否满足给定条件。

exists' :: (a -> Bool) -> [a] -> Bool

exists' p [] = False
exists' p (x:xs)
   | p == x = True
   | otherwise = exists' p xs

2 个答案:

答案 0 :(得分:3)

只需检查病房值上的功能:

exists' :: (a -> Bool) -> [a] -> Bool
exists' _ [] = False
exists' f (x:xs)
   | f x       = True
   | otherwise = exists' f xs

f类型为(a -> bool)x类型为a,ergo f a将返回bool,如果评估为True,则只返回“也是如此,否则你就像正在做的那样进行递归调用。

答案 1 :(得分:1)

正如@DanielSanchez在他的回答中所说,问题是你编写p == x而不是p x所以不是在列表的头部调用谓词,而是检查谓词是否等于到列表的头部。因此,x也应该是a -> Bool类型(p类型的a),px的类型应该是通过Eq类的实例。

您可以使代码更加优雅,如:

exists' :: (a -> Bool) -> [a] -> Bool
exists' _ [] = False
exists' p (x:xs) = p x || exists' p xs

从现在起它读取语法在列表中存在满足给定谓词的元素,因为列表不为空且谓词对于列表的头部为真,< strong>或此类元素存在于列表的其余部分“。

最后,我们还可以通过使用where子句避免在递归调用中传递谓词,如:

exists' :: (a -> Bool) -> [a] -> Bool
exists' p = helper
    where helper [] = False
          helper (x:xs) = p x || helper xs

请注意,您不必自己编写exists'any :: Foldable t => (a -> Bool) -> t a -> Bool函数在语义上是等效的。