【问题标题】:Decide whether two lists are the same in length with recursion用递归判断两个列表的长度是否相同
【发布时间】:2021-12-08 23:13:24
【问题描述】:

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

例如:hasSameLength "apple" "peach" == TruehasSameLength "apple" "cherry" == FalsehasSameLength [] [1..] == FalsehasSameLength [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 由于某种原因卡在运行时。

【问题讨论】:

  • 记得使用-Wall 保持警告开启。这样做会告诉您在模式匹配中错过的情况,例如hasSameLength [] (_:_:_) 指出当第一个列表为空而第二个列表至少有两个元素时,匹配将失败。
  • @chi 如何开启-Wall
  • 当您运行 GHC(或 GHCi)时,您可以将其作为参数传递,例如ghci -Wall MyModule.hs。或者,您可以在文件本身的最顶部添加一行:{-# OPTIONS_GHC -Wall #-}

标签: list haskell boolean


【解决方案1】:
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 的情况,你只需要一个匹配就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2019-03-23
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多