【发布时间】:2015-03-25 20:40:18
【问题描述】:
我对使用 Haskell 非常陌生,我不确定“head”是如何工作的。据我了解,它返回列表中的第一个元素。我一直在尝试使用它,但我不断收到错误。我通过创建一个单独的函数来找到头部添加了一个解决方法,但这似乎应该是不必要的。
我不明白为什么在这里调用 findHead:
single x = length (snd(x)) == 1
toList board
| board == [] = []
| otherwise = filter single board
findHead board = head (toList board)
这里不等同于调用toList:
single x = length (snd(x)) == 1
toList board
| board == [] = []
| otherwise = head (filter single board)
在我看来,这两个应该是相同的,但只有第一个运行。为什么它们不被解释为相同?你能给我解释一下吗?在上面的代码中,'board' 是一个元组列表,每个元组的形式为 (x, [a,b,...])。
我在一些简单的事情中使用了“head”,例如:
union xs ys
| xs == [] = ys
| ys == [] = xs
| otherwise = union (tail xs) (add (head xs) ys)
这似乎按我的预期工作。
【问题讨论】:
-
“但只有第一个运行” - 这是否意味着第二个挂起,或者它产生不同的输出,或者导致错误?
-
在这两种情况下都需要调用
head,即更改| board == [] = head []。然后我希望你能明白为什么head在这里是个坏主意。 -
在绝大多数情况下,比起
head或tail等部分投影,更喜欢(详尽!)模式匹配。 -
顺便说一句,您不应该使用
==[]来检查空列表。这无缘无故地强加了Eq约束,看起来很奇怪。您通常应该在这种上下文中使用模式匹配,而不是守卫。例如union [] ys = ys和union (x:xs) ys = union xs (x:ys)。如果你真的想要一个“它是空的”,你应该使用null。此外,询问列表的长度是否为 1 的效率可能远低于将其与[x]或[_]模式匹配的模式。 -
另外,以后如果你用英文告诉我们代码应该做什么和它实际做什么,并给出一个实际的测试用例是非常有帮助的。否则,弄清楚如何解决它就像阅读茶叶。