1

次のコードで値渡しの結果関数を「シミュレート」しようとしていますが、構文エラーがあるようです。私はsmlのチュートリアルを見てきましたが、これがうまくいかない理由を理解するのに苦労しています

1 val x = ref 0;
2 fun p(y': int ref)=
3 let
4   val y = !y'
5     in
6         let
7             y = 1
8             in
9                 let x := 0 
10                 in
11                 y' := y
12                 end
13         end  
14 end     
15 p(x)
4

2 に答える 2

3

では、let <decs> in <exp>1<decs>つ以上の宣言が必要です。

あなたの場合、7行目でそうしますy = 1-これは代入ではなく比較です。つまり、C++ では、 を実行するのと同じy == 1です。非 ref 変数に代入することはできません。(そして、一般に、ref 変数はできるだけ避けたいと思います。)その代わりに、 の名前でval y = 1新しい値を作成することもできます。新しい価値を創造します。)yy

同様に、9 行目で を実行しますx := 0。これは宣言ではなく、値0を参照値 に代入し、x単位を返す式です。

さらに、let ステートメントで複数の宣言を行うことができるため、入れ子にする必要はありません。

最後にp(x)、トップレベルに書き込みます。前の宣言がセミコロンで終わる場合、トップレベルでのみ式を書くことができます。それ以外の場合は、宣言の一部であると見なされます。あれは

val a = 5
6

と解釈される

val a = 5 6

要するに、これを次のように書き換えることができます。

val x = ref 0;

fun p(y': int ref)=
let
  val y = !y' (* this line might as well be deleted. *)
  val y = 1
in
  x := 0;
  y' := y
end;

p(x)

または、SML には優れた型推論があるため、短いバージョン:

val x = ref 0;

fun p y' = (x := 0; y' := 1);

p x

しかし、私はこれを言います。C++ などの言語を使用している場合は、多くの言語を使用したくなるかもしれません'a refが、それらの使用を最小限に抑えると、SML のコードがよりクリーンになることがよくあることに気付くでしょう。(および他の関数型言語。)

于 2011-10-25T07:12:07.263 に答える
2

let y = 1 ...間違っている。そうですlet x := 0。の内部では、または宣言let ... inが必要です。valfun

SML について誤解しているようです。letスコープで新しいローカル変数を宣言するために使用されます。すぐ外側のスコープで宣言した変数yをシャドウする内側のスコープで名前を付けた変数を宣言しようとするのは奇妙です。次の 2 つのいずれかを意味していました。ylet

  1. 外側のスコープで定義されている「y」変数の値を変更します。不可能だよ。ML で変数の値を変更することはできません
  2. 「y」という名前の新しい無関係な変数を宣言し、このスコープ内の以前の「y」を非表示にします。この場合、使用しますlet var y = 1 in ...

また、あなたが持っているのは奇妙ですlet x := 0x := 0それ自体は有効な式です。が指す参照に含まれる値を変更しますx。は必要ありませんletx := 0は副作用についてのみ評価され、型を返す(unitつまり、何も役に立たない);ため、最後の結果に評価される一連の副作用「ステートメント」をつなぎ合わせるために使用できる演算子に慣れているかもしれません。 1:x := 0; y' := y

于 2011-10-25T07:09:24.383 に答える