如何编写函数来评估自定义数据类型
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 l
和 eval 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_TIMES
或 ME_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);
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
您还应该收到有关 pattern-matching 为 non-exhaustive 的警告,因为您尚未处理 ME_TIMES
或 ME_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);