非详尽模式匹配?

Non-exhaustive pattern matching?

我有以下代码:

data Tree = Leaf | Node Int Tree Tree
  deriving (Eq, Show, Read, Ord)

insert :: Int -> Tree -> Tree
insert n Leaf = Node n Leaf Leaf
insert n tree@(Node num lt rt)
                    | n < num  = Node num (insert n lt) rt
                    | n > num  = Node num lt (insert n rt)
                    | n == num = tree

对我来说,insert 函数似乎详尽无遗地列出了可能的参数模式,但是当我尝试使用 ghc 进行编译时,它说

Pattern match(es) are non-exhaustive
In an equation for ‘insert’:
    Patterns not matched:
        _ (Node _ Leaf Leaf)
        _ (Node _ Leaf (Node _ _ _))
        _ (Node _ (Node _ _ _) Leaf)
        _ (Node _ (Node _ _ _) (Node _ _ _)) 

你能帮我看看为什么吗?

Haskell 不知道如果 n < num 不成立且 n > num 不成立,那么 n == num 成立。 指出对于像 FloatDouble 这样的浮点数,情况并非如此(尽管严格来说 Ord 对浮点数的定义没有定义顺序关系)。

你可以使用otherwiseTrue的别名)这意味着无论nnum如何关联都会“解雇”最后一个守卫;或者我们可以使用 compare 并详尽地定义所有情况:

insert :: Int -> Tree -> Tree
insert n Leaf = Node n Leaf Leaf
insert n tree@(Node num lt rt) = go (<strong>compare n num</strong>)
  where go LT  = Node num (insert n lt) rt
        go GT = Node num lt (insert n rt)
        go EQ = tree