0

私は基本的な質問で再び戻ってきました.! ;)

リスト関数のいくつかを学びました。「List.nth」もその一つです。この関数を SML コマンド ウィンドウで使用すると、正常に動作します。ただし、 Let..in.end 内で使用すると; ブロック 、機能していません。

誰かが助けてくれることを願っています。

let
  val actualDays = 0;

in
  actualDays = List.nth([10,20,31,50,45], 2);
  actualDays
end;

期待される出力:

 val it = 31 : int

実際の出力:

 val it = 0 : int

前もって感謝します!

4

2 に答える 2

2

これが意図したとおりに機能しない理由は、List.nth関数や式の中にいるという事実とは関係ありませんlet。これが意図したとおりに機能しない理由は=、SML の代入演算子ではなく等価演算子にあるためです。

SML の唯一の代入演算子はoperator であり、その左オペランドは単純な整数ではなく である:=必要があります。refしたがって、コードを修正する 1 つの方法は、単に ではなくに変更actualDaysし、 の代わりに使用することです。ただし、変数の変更は SML ではあまり慣用的ではありません。より良い解決策は、おそらく再帰関数を使用するか、正確に何をしようとしているかに応じて、より高次の関数を使用して、変更を必要としないようにロジックを調整することです。int refint:==

于 2013-01-20T12:41:17.313 に答える
1

「命令的思考」を手放し、代わりに「機能的思考」に心を向ける必要があります。例えば

前述のように、変数が参照でない限り、変数を再割り当てすることはできません。また、参照を使用する必要がある場合は、とにかく「間違った」ことをしている可能性があります。関数型プログラミングでは、変数の代入ではなく、実際に名前バインディング(単一の代入とも呼ばれます) を行っています。それらを「不変オブジェクト」と考えてください。

最初にコードを見てみましょう

let
  val actualDays = 0;    
in
  actualDays = List.nth([10,20,31,50,45], 2);
  actualDays
end;

パーツ内に一連の式を配置する場合、in ... end実際には を使用するのと同じin ( expr_1; ... ; expr_n) endです。一連の式を表す括弧に注意してください。一連の式は、各式を左から右に評価し、最後の式の結果以外はすべて無視します。したがって、主に副作用のある式を評価するために使用されます

- (print "foo\n"; print "bar\n"; 3);
foo
bar
val it = 3 : int

あなたの場合、等号は代入演算子ではなく比較演算子であるため、最初の式はブール式に評価され、副作用がないため「無視」され、値がactualDaysそのまま返されます最後の表現です。

actualDays例を修正する 1 つの方法は、 が の結果であると宣言することですList.nth。次に、関数は 2 つの引数を取ることができます。1 つの引数は取得する要素であり、もう 1 つの引数は検索したくないインデックスです。

fun foo x i =
    let
      val actualDays = List.nth([10,20,31,50,45], i)
    in
      x = actualDays
    end

- foo 20 1;
val it = true : bool
- foo 50 3;
val it = true : bool

ただし、この特定の関数では、let 式は必要なく、次のように記述してもかまいません。

fun foo x i = x = List.nth([10,20,31,50,45], i)
于 2013-01-20T15:19:11.323 に答える