SML interpreter.My Div func 正在运行,但我的 Minus func 有问题。当传递的错误不是数字时,我希望它给出错误

SML interpreter.My Div func is working but i am having issue with my Minus func. I want it to give an error when the passed error is not a number

datatype exp = Int of int | Minus of exp * exp | Div of exp * exp;


datatype value = CVal of int 
               | FnVal of string * exp * (string * value) list 
               | Error of string;

fun eval (Int x) _ = CVal x 
  | eval (Div (e1, e2)) ctx = let val (CVal x) = eval e1 ctx
                                  val (CVal y) = eval e2 ctx
                              in if y = 0
                                 then Error "Division by zero error"
                                 else CVal (x div y)
                              end
  | eval (Minus (e1, e2)) ctx = let val (CVal x) = eval e1 ctx
                                    val (CVal y) = eval e2 ctx
                                in if x <> Int orelse y <> Int
                                   then Error "Minus error : not an integer"
                                   else CVal (x - y)
                                end;

Int 不是一个值,它是一个构造函数。你无法将它与任何东西进行比较。
它也是 exp 值而非整数的构造函数。

如果你看看你的定义,

datatype value = CVal of int 
...

很明显 xy 必须 是整数,就像除法一样。
如果你想检查类型,你也需要为除法做那个,你需要在 before 你匹配 CVal xCVal y.

如果你尝试在一个函数中完成这一切,这会变得非常混乱,所以我会写一些评估辅助函数;像这样:

fun divide (CVal _) (CVal 0) = Error "Division by zero"
  | divide (CVal x) (CVal y) = CVal (x div y)
  | divide _ _ = Error "Division error: not an integer";

fun subtract (CVal x) (CVal y) = CVal (x - y)
  | subtract _ _ = Error "Subtraction error: not an integer";

fun eval (Int x) _ = CVal x 
  | eval (Div (e1, e2)) ctx = let val x = eval e1 ctx
                                  val y = eval e2 ctx
                              in
                                  divide x y
                              end
  | eval (Minus (e1, e2)) ctx = let val x = eval e1 ctx
                                    val y = eval e2 ctx
                                in
                                    subtract x y
                                end;