问题描述
我是 ML 的新手,我正在尝试找出模式匹配的语法。
有人可以帮助我理解编译器错误,以及在将 AssignStm
的第二个参数绑定到变量 e
时匹配模式的正确语法吗?
也许我正在尝试做的事情根本不受支持?我有一个 ADT 定义如下。
type id = string
datatype binop = Plus | Minus | Times | Div
datatype stm = CompoundStm of stm * stm
| AssignStm of id * exp
| PrintStm of exp list
and exp = IdExp of id
| NumExp of int
| OpExp of exp * binop * exp
| EseqExp of stm * exp
我正在尝试实现一个函数,该函数计算给定语句中对 print
的调用次数。
编译器抱怨
/Users/jimka/Repos/mciml/fig4.1.sml:15.60 Error: unbound variable or constructor: e
这是我的代码:
fun maxints(a,b) =
if a > b then a else b
fun maxargs PrintStm nil = 0
| maxargs PrintStm h::t = 1 + (maxargs printStm t )
| maxargs CompoundStm(a,b) = maxints(maxargs a,maxargs b)
| maxargs AssignStm(_,e: exp) = maxargs e (* the error is on this line *)
| maxargs IdExp = 0
| maxargs NumExp = 0
| maxargs OpExp(e1,_,e2) = maxints(maxargs e1,maxargs e2)
| maxargs EseqExp(s,e) = maxints(maxargs s,maxargs e)
val prog =
CompoundStm(AssignStm("a",OpExp(NumExp 5,Plus,NumExp e)),CompoundStm(AssignStm("b",EseqExp(PrintStm[IdExp"a",OpExp(IdExp"a",Minus,NumExp 1)],OpExp(NumExp 10,Times IdExp"a"))),PrintStm[IdExp "b"]))
maxargs prog
molbdnilo 提出以下建议。但我得到了同样的错误。
fun maxargs( PrintStm nil) = 0
| maxargs( PrintStm (h::t)) = 1 + maxints(maxargs(h),maxargs( PrintStm( t )))
| maxargs( CompoundStm (a,b)) = maxints(maxargs( a),maxargs( b))
| maxargs( AssignStm (_,e)) = maxargs( e)
| maxargs( IdExp (_)) = 0
| maxargs( NumExp (_)) = 0
| maxargs( OpExp (e1,e2)) = maxints(maxargs e1,maxargs e2)
| maxargs( EseqExp (s,e)) = maxints( maxargs(s),maxargs(e))
解决方法
当前的问题不是模式匹配问题,而是 prog
包含 NumExp e
而您还没有在任何地方定义 e
。
您还遇到了问题,即您试图让 maxargs
取 stm
或 exp
,但您做不到。
还有,
fun maxargs PrintStm nil = 0
将定义一个接受两个参数的函数; PrintStm
和 nil
。
你需要在模式周围加上括号,并且需要两个相互递归的函数:
fun maxargs_stm (PrintStm nil) = 0
| maxargs_stm (PrintStm (h::t)) = 1 + (maxargs_stm (PrintStm t))
| maxargs_stm (CompoundStm(a,b)) = maxints(maxargs_stm a,maxargs_stm b)
| maxargs_stm (AssignStm(_,e: exp)) = maxargs_exp e
and maxargs_exp (IdExp _) = 0
| maxargs_exp (NumExp _) = 0
| maxargs_exp (OpExp(e1,_,e2)) = maxints(maxargs_exp e1,maxargs_exp e2)
| maxargs_exp (EseqExp(s,e)) = maxints(maxargs_stm s,maxargs_exp e);