您的数据类型似乎对数学表达式的某些子集进行了建模,并且您已将加法、乘法和变量拆分为两个单独的数据类型 expression 和 term。因为terms只指terms而不回表达式s,所以表达式a + (b × c) em> 可以编码为:
AddE (Term (ID (IdentE #"a")),
Term (MultE (ID (IdentE #"b")),
ID (IdentE #"c")),
IdentE #"?")
但你不能编码表达式a × (b + c)。
我不确定为什么加法有三个参数,大概是二元运算符。
这是您的 sum 函数,具有适当的间距和换行符:
fun sum(Empty) = 0
| sum(Term) = sum(ID) +
| sum(IdentE) = 1
|| sum(AddE(AddE, Term) = sum(AddE) + sum(Term)
| sum(MultE(MultE, IdentE) = sum(MultE) + sum(IdentE)
一些事情变得明显:
- 您在发布代码之前没有仔细阅读自己的代码。
- 您的数据类型中没有
Empty 构造函数。什么是“空表达式”?
- 您似乎忘记完成第二行中
+之后的表达式。
- 您在第四行的
| 太多,而在第四行和第五行的) 太少。
- 您的函数
sum 不能同时处理多种类型的值。如果它在一行中接受与 AddE (...) 匹配的值,则它也不能在另一行中接受与 MultE (...) 匹配的值,因为它们属于不同的类型。
-
您要进行模式匹配的每个值构造函数都没有其参数。每个递归调用都是针对值构造函数的名称而不是传入的值的参数进行的。如果您想要一个接受 表达式s 的函数,可以如下所示:
fun sum (AddE (e1, e2, t)) = sum e1 + sum e2 + ...
| sum (Term t) = ...
-
由于您有多种递归数据类型,最好的办法是拥有多个函数来处理每种数据类型的递归。 (这不是绝对必要的,但是您也有一些非常复杂的模式。)
fun sum (AddE (e1, e2, t)) = sum e1 + sum e2 + sumTerm t
| sum (Term t) = sumTerm t
and sumTerm (ID id) = 1
| sumTerm (MultE (t1, t2, id)) = sumTerm t1 + sumTerm t2 + 1
同样,我不知道为什么加法有第三项,为什么乘法有第三个标识符,以及为什么你有多个数据类型开始。
如果我要为一个简单的算术语法树建模并计算它的变量数量,我会从 one 数据类型开始,二元运算符只有 two 每个参数:
datatype expr = AddE of expr * expr
| MultE of expr * expr
| ConstE of int
| VarE of string
有了这个数据类型定义,
-
a + (b × c) 变为
AddE (VarE "a", MultE (VarE "b", VarE "c")),并且
-
a × (b + c) 变为
MultE (VarE "a", AddE (VarE "b", VarE "c"))。
我可以创建一个函数来计算表达式中变量的数量,如下所示:
fun countVars (AddE (e1, e2)) = countVars e1 + countVars e2
| countVars (MultE (e1, e2)) = countVars e1 + countVars e2
| countVars (ConstE const) = 0
| countVars (VarE varname) = 1
我可能有兴趣获取这些变量的列表:
fun getVars (AddE (e1, e2)) = getVars e1 @ getVars e2
| getVars (MultE (e1, e2)) = getVars e1 @ getVars e2
| getVars (ConstE const) = []
| getVars (VarE varname) = [varname]