ML:警告:匹配不详尽

ML : Warning: match nonexhaustive

这是问题:

我们使用以下类型表示多项式:

datatype exp = Const of int | x | Add of exp * exp | Mult of exp * exp | Power of exp * int

例如,表达式 Add (Add (Mult (Const 3, Power (x, 2)), Mult (Const 6, x)), Const 1) 表示多项式 3x2 + 6x + 1.

(a) 编写函数 "evaluate" 来计算给定表达式 e 的特定值 x.

这是我的答案:

datatype exp = Const of int | x | Add of exp * exp | Mult of exp * exp |Power of exp * int
fun pow(a,0) = 1 | pow(a,1) = a | pow(a,b) = mult(a,pow(a,b-1));
fun evaluate(Const(a),t) = a 
| evaluate(x,t) = t 
| evaluate(Add(a,x),t)= (evaluate(a,t)+t) 
| evaluate(Mult(a,x),t) = (evaluate(a,t)*t) 
| evaluate(Power(x,a),t) = pow(t,a);
val y = Add (Add (Mult (Const 3, Power (x, 2)), Mult (Const 6, x)), Const 1);
evaluate(y,1);

但结果是:

uncaught exception Match [nonexhaustive match failure]
raised at: stdIn:6.37

同样在定义函数 evaluation 之后,我收到了这个警告:

stdIn:1.6-6.37 Warning: match nonexhaustive
      (Const a,t) => ...
      (x,t) => ...
      (Add (a,x),t) => ...
      (Mult (a,x),t) => ...
      (Power (x,a),t) => ...
val evaluate = fn : exp * int -> int

我该如何解决?

您收到警告是因为您的模式并未涵盖所有情况。例如 -- 和 Add 模式应该看起来像 Add(a,b) 因为这涵盖了所有可能的情况。例如,

在表达式 2x^3 + 3x^2 中,a 将绑定到 2x^3b 将绑定到 3x^2(当然,所有这些都适当地转换为您的数据类型)。但是——在你的 evaluate 中,你使用像 Add(a,x) 这样的模式——它只会捕获看起来像 2x^3 + x 的多项式。我认为绝对没有理由假设总和中的第二项是 x。类似的评论适用于您的其他模式( x 本身的第一个模式除外)。在所有情况下,将看起来像 Add(a,x) 的模式替换为看起来像 Add(a,b) 的模式,并仔细考虑在这些情况下要 return 什么。

您只匹配包含 x 的字词;您需要考虑任意 exps 并递归地评估所有这些。

例如替换

evaluate(Add(a,x),t)= (evaluate(a,t)+t) 

evaluate (Add(e1, e2), t) = evaluate(e1, t) + evaluate(e2, t)