如何编写函数来评估自定义数据类型

How can I write a function to evaluate custom datatype

datatype mixed_expression =
   ME_NUM of int
 | ME_PLUS of mixed_expression * mixed_expression
 | ME_TIMES of mixed_expression * mixed_expression
 | ME_LESSTHAN of mixed_expression * mixed_expression;

datatype value =
   INT_VAL of int
 | BOOL_VAL of bool
 | ERROR_VAL;

我得到了这些数据类型,这是我的方法

fun eval e = 
  case e of 
    ME_NUM x       => INT_VAL x 
  | ME_PLUS (l, r) => eval l + eval r

我收到以下错误消息。

**Error: overloaded variable not defined at type
  symbol: +
  type: value**

我不知道如何解决这些问题,因为不允许我使用突变。

错误消息告诉您需要知道的内容。当你写:

eval l + eval r

表达式 eval leval r 产生类型 value。此类型没有 + 运算符。

作为样式说明,您的 case 在这种情况下是无关紧要的。

fun eval(ME_NUM x)       = INT_VAL x
  | eval(ME_PLUS (l, r)) = eval l + eval r

您还应该收到有关 pattern-matching 为 non-exhaustive 的警告,因为您尚未处理 ME_TIMESME_LESSTHAN.

真的,你需要做的是定义一个函数,它可以 add 两个 value 值。

fun me_add(INT_VAL a, INT_VAL b)  = INT_VAL (a + b)
  | me_add(INT_VAL a, BOOL_VAL b) = (* ... *)

您需要 pattern-match 多种组合。您可能只想定义一个将 value 强制转换为 int.

的函数
fun toInt(INT_VAL a)      = a
  | toInt(BOOL_VAL True)  = 1
  | toInt(BOOL_VAL False) = 0
  | (* and so on... *)

那么你可以这样写:

fun me_add(a, b) = INT_VAL(toInt a + toInt b)

问题是没有为 value 类型定义的 + 运算符。
(你不会通过使用突变来解决这个问题。)

您需要“分离”eval 的结果,然后从加法中构建一个新的 value

最天真的方法是案例分析,但这很快就变得不可读了:

  eval (ME_PLUS (e1, e2)) = (case eval e1 of
                                   INT_VAL x1 => (case eval e2 of
                                                      INT_VAL x2 => INT_VAL (x1 + x2)
                                                    | _ => ERROR_VAL)
                                 | _ => ERROR_VAL)

每个案例都需要这些丑陋之处之一。

一种更简洁的方法是将 value 上的操作定义为单独的函数:

fun add (INT_VAL x1) (INT_VAL x2) = INT_VAL (x1 + x2)
  | add _ _ = ERROR_VAL;

等等。
然后根据这些操作定义解释器:

fun eval (ME_NUM x) = INT_VAL x
  | eval (ME_PLUS (e1, e2)) = add (eval e1) (eval e2)
  | eval (ME_TIMES (e1, e2)) = multiply (eval e1) (eval e2)
  | eval (ME_LESSTHAN (e1, e2)) = less_than (eval e1) (eval e2);