Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
549 views
in Technique[技术] by (71.8m points)

sml - How to pattern match an ADT in ML

I'm brand new to ML and I'm trying to figure out the syntax for pattern matching. Can someone help me understand the compiler error, and the correct syntax for pattern matching an AssignStm while binding its second argument to the variable e ?

Maybe what I'm trying to do is simply not supported? I have an ADT defined as follows.

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

And I'm trying to implement a function which counts the number of calls to print in a given statement.

The compiler complains

/Users/jimka/Repos/mciml/fig4.1.sml:15.60 Error: unbound variable or constructor: e

Here is my code:

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)

The actual code which triggers the error is the following:

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 suggested the following. But I get the same error.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The immediate problem is not a pattern-matching problem, but that prog contains NumExp e while you haven't defined e anywhere.

You also have the problem that you're trying to make maxargs take either a stm or an exp, and you can't do that.

Also,

fun maxargs PrintStm nil = 0 

would define a function that takes two arguments; PrintStm and nil.

You need parentheses around the patterns, and you need two mutually recursive functions:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...