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 l
和eval r
生成类型value
。此类型没有+
运算符。
作为样式说明,在这种情况下,您的case
是无关紧要的。
fun eval(ME_NUM x) = INT_VAL x
| eval(ME_PLUS (l, r)) = eval l + eval r
您还应该收到有关模式匹配不详尽的警告,因为您尚未处理ME_TIMES
或ME_LESSTHAN
。
实际上,您需要做的是定义一个可以添加两个value
值的函数。
fun me_add(INT_VAL a, INT_VAL b) = INT_VAL (a + b)
| me_add(INT_VAL a, BOOL_VAL b) = (* ... *)
您需要对很多组合进行模式匹配。您可能只想定义一个将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);