非穷尽模式

时间:2019-12-01 05:39:20

标签: haskell pattern-matching

我写了一个函数,该函数将一个列表[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]
   |        ^^^^^^^^^^^^^^^^^^^^...

1 个答案:

答案 0 :(得分:4)

基本上,因为从技术上来说,您的守卫a == ya /= 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>