首页 > 解决方案 > 用递归判断两个列表的长度是否相同

问题描述

实现hasSameLength :: [a] -> [b] -> Bool决定两个列表是否相同长度的函数。禁止使用该length功能。

例如:hasSameLength "apple" "peach" == True, hasSameLength "apple" "cherry" == False, hasSameLength [] [1..] == False,hasSameLength [1..] [] == False

到目前为止,我已经尝试过

hasSameLength [] [] = True
hasSameLength [] [a] = False
hasSameLength [a] [] = False
hasSameLength (x:xs) (y:ys) = hasSameLength (xs) (ys)

但是如果只有一个参数列表是空的,我会得到一个non-exhaustive patterns错误。由于某种原因,这样做hasSameLength (x:xs) (y:ys) = hasSameLength (xs) (ys) && hasSameLength (x) (y)会导致 GHCi 卡在运行时。

标签: listhaskellboolean

解决方案


hasSameLength [] [] = True
hasSameLength [] _ = False
hasSameLength _ [] = False
hasSameLength (x:xs) (y:ys) = hasSameLength (xs) (ys)

请注意,模式是按从上到下的顺序匹配的。因此,当两个列表都为空(第一个模式)时,如果其中一个为空,则它已经是False. 我们不关心另一个列表是否有一个或多个元素,我们用下划线表示_

在您的代码中,您的模式如下:

hasSameLength [] [a] = False
hasSameLength [a] [] = False

当一个列表为空而另一个列表只有一个元素时,这两行负责处理。但是当一个是空的而另一个有 2 个时呢?还是很多?这是您错过该模式的情况,几乎不可能覆盖它,因为下一个模式:

hasSameLength (x:xs) (y:ys) = hasSameLength (xs) (ys)

也没有涵盖它,因为其中一个列表是空的。

一种对我有帮助的思考方式是看:[] []作为一种and情况,您需要两个参数都为空(或为此匹配提供的模式)以匹配_ []模式和类似模式,其中一个是_下划线作为or您只需要一个匹配即可工作的情况。


推荐阅读