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しますが、とは異なるタイプの値であるため、これはx機能しませzん。これらは互いに等しくなる可能性はありません。

于 2013-03-01T21:58:27.473 に答える