【发布时间】:2017-12-09 01:03:03
【问题描述】:
我是 Haskell 的新手,正在玩一些游戏。我用警卫创建了一个递归函数。请参阅下面的功能:
filterAge :: [Person] -> [String]
filterAge (x:xs)
| (x:xs) == [] = []
| (getAge x) < 30 || (getAge x) > 40 = [] ++ filterAge xs
| otherwise = [getName x] ++ filterAge xs
我有一个由 10 个人创建的数据集,我在此方法中使用。当我尝试这个功能时,它给了所有合适的人,但之后它得到了一个非详尽模式错误:
["Lise","Jaap","Elle","Ebba"*** Exception: D:\...:(44,1)-(47,77): Non-exhaustive patterns in function filterAge
我发现它永远不会到达第一个守卫。所以我玩了一下,发现了一些非常奇怪的东西(在我看来):
*Main> let (x:xs) = []
*Main> (x:xs) == []
False
现在我的主要问题是:为什么(x:xs) == [] 返回 False?
如果有人对我有更好的方法来完成该功能,那就太好了,但这不是很重要。
提前致谢!
编辑
感谢 Willem Van Onsem 和 Lambda.xy.x,我的问题得到了快速解答。这导致以下功能完美运行:
filterAge :: [Person] -> [String]
filterAge [] = []
filterAge (x:xs)
| (getAge x) < 30 || (getAge x) > 40 = [] ++ filterAge xs
| otherwise = [getName x] ++ filterAge xs
但要获得最佳版本,您必须查看 Willem Van Onsem 的答案。
【问题讨论】:
-
(x:xs) == []永远不会成功。因为(x:xs)是一个包含至少一个元素的列表。 -
谢谢,这有帮助。所以我想我应该解决它?不过不知道该怎么做,因为我的函数有点需要 (x:xs) ..
-
为了扩展答案,一个列表有两个构造函数:
[]和_ : _,最外层构造函数[]的列表永远不能有:作为最外层构造函数。 -
您已经在
filterAge (x:xs)的定义中进行了模式匹配,并在那里排除了空列表。最简单的解决方法是在上面添加定义filterAge []。或者,您可以定义 filterAge xs 并匹配任意列表。 -
@ lambda.xy.x 这行得通!我完全忽略了这种可能性,我之前已经使用过一点,但没有想到这个功能。非常感谢!
标签: list haskell filter pattern-matching lazy-evaluation