为什么我会收到“匹配减少”错误?

时间:2016-11-15 19:45:38

标签: sml

我对运行以下代码时遇到的“匹配冗余”错误感到有点困惑:

    datatype expression =  Constant of int |
            Variable of string |
            Operator of string * expression |
            Pair of expression list |
            List of expression list

fun add2 (ul1: expression, ul2: expression) =
    let
        fun gcd (a, b) =
            if a >= b
            then 
                if (a mod b) = 0
                then b
                else gcd (b,(a mod b))
            else
            if (b mod a) = 0
            then a
            else gcd (a, (b mod a))
        fun lcm (a,b) =
            a*b div (gcd(a,b))      
    in

        case ul1 of
            Operator("/",Pair [Constant a, Constant b]) =>
                case ul2 of
                    Operator("/",Pair [Constant c, Constant d]) => 
                    a*d + c*b//(b*d)
                    |Operator("/",Pair [Variable c, Constant d])=>
                    Operator("/",Pair [(Operator("+", Pair [Constant a, Variable c])),Constant (lcm(b,d))])

            |Operator("/",Pair [Variable a, Constant b]) =>
                case ul2 of
                    Operator("/",Pair [Constant c, Constant d]) => 
                    Operator("/",Pair [(Operator("+", Pair [Variable a, Constant c])),Constant (lcm(b,d))])
                    |Operator("/",Pair [Variable c, Constant d])=>
                    Operator("/",Pair [(Operator("+", Pair [Variable a, Variable c])),Constant (lcm(b,d))])


    end

确切的错误按摩是:

C:\Users\erikj\Dropbox\Fakulteta Laptop\Programiranje\domacanaloga 6.sml:91.5-102.93 Error: match redundant and nonexhaustive
          Operator ("/",Pair (Constant c :: Constant d :: nil)) => ...
          Operator ("/",Pair (Variable c :: Constant d :: nil)) => ...
    -->   Operator ("/",Pair (Variable a :: Constant b :: nil)) => ...

我不介意非穷举的比赛,因为它只是一个练习。 感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

请考虑以下代码:

case ul1 of
    Operator("/",Pair [Constant a, Constant b]) =>
        case ul2 of
            Operator("/",Pair [Constant c, Constant d]) => 
            ...
            |Operator("/",Pair [Variable c, Constant d])=> (* Case A *)
            ...
            |Operator("/",Pair [Variable a, Constant b]) => (* Case B *)
            ...

很明显,案例B是多余的,因为它与案例A相同(变量名除外)。

此代码和代码之间的唯一变化是我更改了案例B的缩进。现在缩进不会影响SML程序的语义,因此案例B在代码中与在此处一样冗余。

对于人类读者来说,从缩进中可以清楚地看出,您希望案例B属于外部模式匹配,但正如我所说,编译器并不关心缩进,因此您需要使用括号或开始结束块告诉编译器内部匹配结束的位置。