如何在 ML 中模式匹配 ADT

How to pattern match an ADT in ML

我是 ML 的新手,我正在尝试找出模式匹配的语法。 有人可以帮助我理解编译器错误,以及在将其第二个参数绑定到变量 e 时模式匹配 AssignStm 的正确语法吗?

也许我正在尝试做的事情根本不受支持?我有一个 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 接受 stmexp,但你做不到。

此外,

fun maxargs PrintStm nil = 0 

会定义一个有两个参数的函数; PrintStmnil.

您需要将模式括起来,并且您需要两个相互递归的函数:

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);