模式匹配涵盖多个案例

时间:2014-06-12 14:20:48

标签: haskell

我做了一个比较字符串的功能(当然这是我为了学习而做的练习,我很清楚&lt ;,>操作符都适用于大多数现代字符串语言)。为了做一些递归,我使用模式匹配功能,但我不确定发生了什么。这是我的代码:

compareStrings :: String -> String -> Char
compareStrings (x:xs) (y:ys)
    | x > y = '>'
    | x < y = '<'
    | x == y = compareStrings xs ys
compareStrings [a] [b]
    | a < b = '<'
    | a > b = '>'
    | a == b  = '='

因此,我的代码中有很多情况,例如一个空列表和一个单例列表,一个空列表和一个普通列表(多个元素)。当然还有对称的对应物。我怎样才能确保检查它们?是否有什么东西在引擎盖下或者只是比较字符串(不是字符,这是我的意图)在某些时候,我不知道它?

  • 总结一下,我的问题是:我是否涵盖了我的代码可能出现的所有情况,如果情况不是这样,我怎么能确定?我怎么处理对称的情况(比如第一个列表为空,但第二个列表没有,反过来又没有声明两种不同的模式)。

2 个答案:

答案 0 :(得分:6)

对于这样的问题,你只关心每个列表的第一个元素,如果列表是空的。通常,您只需确定您的函数正在运行的列表的哪些元素,然后处理案例,直到您涵盖了可以传入的任何类型的列表。

对于此实例,您希望在两个列表都包含数据(x:xs)(y:ys)时以及当其中一个或两个都为空时进行处理。你可以用

来解决这个问题
-- Both are empty
compareStrings [] [] = '='
-- The first is empty, the second is not
compareStrings [] ys = '<'
-- The first is not empty, the second is
compareStrings xs [] = '>'
-- Both have data
compareStrings (x:xs) (y:ys) = <your current implementation>

请注意,在中间的两种情况下,我们不必指定包含数据的列表实际上具有数据,因为如果它传递了第一个模式,则两者都不为空。如果您有not (xs == [] && ys == []) && (xs == [] && ys == _)(这不是代码,请勿尝试运行),则ys不是[]。我们也不必检查xs == [x] && ys == [y]的情况,因为[x] == x:[](z:zs)x == z[] == zs匹配。

为了确保您确实覆盖了所有模式,您应该按照@StephenDiehl的建议启用-fwarn-non-exhaustive-patterns

答案 1 :(得分:5)

  

我是否涵盖了我的代码可能出现的所有情况,如果情况并非如此,我怎么能确定?

事实上,这种模式匹配并非详尽无遗,对于某些输入,它并未定义。您可以告诉GHC使用标记-fwarn-non-exhaustive-patterns向您发出警告,并打印出您未覆盖的案例。

cover.hs:2:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for `compareStrings':
        Patterns not matched:
            [] _
            (_ : (_ : _)) []
            (_ : (_ : _)) (_ : _)
            [_] []
            ...
相关问题