我写了一个函数,该函数将一个列表[a]并将所有相等的值分组到另一个列表中[[a]]。现在,我在启用(-W)警告的情况下使用了ghci,看来我的模式之一并不详尽-您能帮我找到我的模式尚未匹配的情况吗? <3
h :: Eq a => [a] -> [[a]]
h [] = []
h (x:xs) = help x xs [x] []
where help :: Eq a => a -> [a] -> [a] -> [a] -> [[a]]
help _ [] s [] = [s] --line 15
help _ [] s n = s : (h n)
help a (y:ys) s n | a == y = help a ys (y:s) n
| a /= y = help a ys s (y:n)
test.hs:15:8: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘help’: Patterns not matched: _ (_:_) _ _
|
15 | help _ [] s [] = [s]
| ^^^^^^^^^^^^^^^^^^^^...
答案 0 :(得分:4)
基本上,因为从技术上来说,您的守卫a == y
或a /= y
都不是真的。
即使通常假设Eq
表示等价关系,Haskell报告实际上也没有为其定义任何法律。特别是,可能会违反“自定义” x /= y = not (x == y)
。 (即使这是法律,编译器也不会强制执行。)请考虑以下问题:
data BadIdea = BadIdea
instance Eq BadIdea where
_ == _ = False
_ /= _ = False
尽管您实际上不应该这样做,但是您可以 ,然后由于两种情况都不成立,您的程序将崩溃。
最简单的解决方法是将a /= y
替换为otherwise
。这类似于您不会写if a == y then ...
和if a /= y then ...
而宁愿写if a == y then ... else ...
的事实。由于在实践中,没有真正的类型具有如此病理的Eq
实例,所以这不会真正改变程序的行为(如果您确实使用了这种类型,则只会认为它们不相等而不是崩溃)。 / p>