我做了一个函数来比较字符串(当然这是我正在做的一个练习,以便学习,我很清楚<,>运算符在大多数现代语言中都使用字符串).为了做一些递归我正在使用模式匹配函数,但我不确定发生了什么.这是我的代码:
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 = '='
Run Code Online (Sandbox Code Playgroud)
因此,我的代码中有很多案例,例如一个空列表和一个单例列表,一个空列表和一个普通列表(多个元素).当然还有对称的对应物.我怎样才能确保检查它们?是否有什么东西在幕后?或者只是比较字符串(不是字符,这是我的意图)在某些时候,我不知道它?
对于这样的问题,你只关心每个列表的第一个元素,如果列表是空的.通常,您只需确定您的函数正在操作的列表的哪些元素,然后处理案例,直到您涵盖了可以传入的任何类型的列表.
对于这种情况下,要处理时,两个列表具有数据(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>
Run Code Online (Sandbox Code Playgroud)
请注意,在中间的两种情况下,我们不必指定具有数据的列表实际上具有数据,因为如果它传递了第一个模式,则两者都不为空.如果你有not (xs == [] && ys == []) && (xs == [] && ys == _)(这不是代码,不要尝试运行),那么ys不是[].我们也没有检查xs == [x] && ys == [y]因为[x] == x:[]哪个(z:zs)与x == z和匹配的情况[] == zs.
为了确保您确实覆盖了所有模式,您应该-fwarn-non-exhaustive-patterns按照@StephenDiehl的建议启用.
我是否涵盖了我的代码可能出现的所有情况,如果不是这样,我怎么能确定?
实际上,这种模式匹配并非详尽无遗,因为某些输入没有定义.您可以告诉GHC用旗子警告您-fwarn-non-exhaustive-patterns,它会打印出您未覆盖的案例.
cover.hs:2:1: Warning:
Pattern match(es) are non-exhaustive
In an equation for `compareStrings':
Patterns not matched:
[] _
(_ : (_ : _)) []
(_ : (_ : _)) (_ : _)
[_] []
...
Run Code Online (Sandbox Code Playgroud)