0
type Name = string;
datatype Expr = Const of int
    | Var of Name
    | Neg of Expr
    | Plus of Expr * Expr
    | Mult of Expr * Expr
    | App of Fun * Expr
    and Fun = Def of Name * Expr

(* substitute every x in expression z with expression y *)

fun substitute (Name x, Expr y, Expr z) = if x = z then y else z;

我只想比较 x 和 z 的字符串值,如果它们相同则返回 y,否则返回 z,但我一直收到此错误?

e.sml:13.33-13.39 Error: non-constructor applied to argument in pattern: Expr
e.sml:13.25-13.31 Error: non-constructor applied to argument in pattern: Expr
e.sml:13.17-13.23 Error: non-constructor applied to argument in pattern: Name
e.sml:13.50 Error: unbound variable or constructor: z
e.sml:13.46 Error: unbound variable or constructor: x
e.sml:13.57 Error: unbound variable or constructor: y
e.sml:13.64 Error: unbound variable or constructor: z

uncaught exception Error
  raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
         ../compiler/TopLevel/interact/evalloop.sml:44.55
         ../compiler/TopLevel/interact/evalloop.sml:296.17-296.20
4

2 回答 2

3

你的定义substitute没有多大意义;)。首先,您使用错误的类型和模式匹配,其次您需要递归替换,而不仅仅是根表达式。

这是一个工作版本的草图:

fun substitute(x, e, Const n)      = Const n
  | substitute(x, e, Var y)        = if x = y then e else Var y
  | substiture(x, e, Neg e')       = Neg(substitute(x, e, e'))
  | substitute(x, e, Plus(e1, e2)) = Plus(substitute(x, e, e1), substitute(x, e, e2))
  | ...

您应该能够填写剩余的案例。这种App情况需要注意避免在函数中意外捕获——也就是说,您必须避免在x与参数变量相同的情况下在主体内部进行替换。

如果你热衷于给出类型注释,那么这个函数可能最好用一个案例来编写:

fun substitute(x : Name, e : Expr, z : Expr) =
    case z of
      Const n => z
    | Var y   => if x = y then e else z
    | Neg e'  => Neg(substitute(x, e, e'))
    ...

这相当于前者,后者只是一个案例的语法糖。

于 2013-03-02T09:56:53.063 回答
1

您似乎认为函数参数的语法是typename variablename. 它不是。语法是pattern : typename或者只pattern​​是模式的最简单形式只是一个变量名。

编写类似的东西Name x意味着这Name是某个数据类型的构造函数,并且您正在尝试将您的第一个参数(必须是该数据类型的值)与该构造函数进行模式匹配。那不是你想要的。

要定义一个接受参数和的函数x,您应该只写:yz

fun substitute (x, y, z) = ...

或者,如果您想说明参数的类型:

fun substitute (x: Name, y: Expr, z: Expr) = ...

PS:在您编写的函数主体中x = z,但这不起作用,因为xandz是不同类型的值-它们不可能彼此相等。

于 2013-03-01T21:58:27.473 回答