如何在 ML 中模式匹配 ADT

问题描述

我是 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

您还遇到了问题,即您试图让 maxargsstmexp,但您做不到。

还有,

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