【问题标题】:How to pattern match an ADT in ML如何在 ML 中模式匹配 ADT
【发布时间】:2021-04-06 04:17:30
【问题描述】:

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

【问题讨论】:

    标签: pattern-matching sml ml


    【解决方案1】:

    直接的问题不是模式匹配问题,而是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);
    

    【讨论】:

    • 嗯。可悲的是,这似乎没有帮助。更改后我得到了同样的错误。
    • 我会更新原始帖子以反映您的建议。
    • 啊,prog 包含NumExp e。我现在明白了,我完全在看模式匹配中的e。谢谢。
    • 下一个我无法定义maxargs 以接受stmexp 并不明显。我想这只是语言的一个特点。但是,我可以以某种方式将类型 entity 定义为 stm | exp 吗?因此 maxargs 会映射 entityint 吗? IE。 | 仅适用于构造函数还是也适用于类型名称?
    • 如果你想要一个这样的联合类型,你可以为每个选项定义一个新的数据类型和一个构造函数,尽管我认为两个相互递归的函数(如 molbdnilo 所示)是更好的解决方案.
    猜你喜欢
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2015-08-31
    • 1970-01-01
    • 2010-12-22
    相关资源
    最近更新 更多