Интерпретатор SML. Мой Div Fun c работает, но у меня проблема с моим Minus Fun c. Я хочу, чтобы это выдало ошибку, когда переданная ошибка не является числом - PullRequest
0 голосов
/ 04 апреля 2020
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;

1 Ответ

0 голосов
/ 04 апреля 2020

Int это не значение, это конструктор. Вы не можете сравнить это ни с чем.
Это также конструктор exp значений, а не целых чисел.

Если вы посмотрите на свое определение,

datatype value = CVal of int 
...

ясно, что x и y должны быть целыми числами, как в случае деления.
Если вы хотите проверить типы, вы должны сделать это и для деления, и вам нужно сделать это за до того, как вы совпадете с CVal x и CVal 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;
...