2016-12-23 5 views
0

関数の各呼び出しでリストを更新する必要があるとします。リストの前の要素が保持されるようにします。リスト内の要素をSMLでプログラム内に保持する方法は?

local 
    val all_list = []; 
in 
    fun insert (x:int) : string = int2string (list_len((([email protected][x])))) 
end; 

は私が呼ぶたびに挿入することで問題は、私はリストを再び[]に開始されたことを示す出力「1」を、取得:

は、ここに私の試みです。

しかし、最初の呼び出しでは"1"の出力が、2番目の呼び出しでは"2"の出力が期待されていました。

回避策はありません。どのようにそれを行う必要がありますか?

+0

、繰り返し与える同じ入力で繰り返し関数を呼び出します同じ結果。なぜあなたは他に何を期待しますか? – Bergi

+0

あなたは変数を更新することは決してありません。長さを決めて新しいリストを作成するだけです。 – Bergi

+0

R. Harperの[Programming in Standard ML](http://www.cs.cmu.edu/~rwh/isml/book.pdf)を読むことをお勧めします。本当に素晴らしい本です! –

答えて

2

side-effectsを使用する必要があります。 機能プログラマはほとんどの場合、副作用のないpure functionsを使用します。あなたの実装は純粋な関数なので、同じ入力に対して常に同じ値を返します(そして、あなたの場合は、すべての入力に対して同じ値を返します)。

の参照を使用すると、それを処理できます。

標準MLでの参照でクラッシュコース:

  • refが、それはあなたが後から変更することができます参照セルの中に任意の値をパックして、'a -> 'a ref型を持つ、新しい参照を作成するrefを使用します。
  • !は参照をアンパックするためのものです:(!) : 'a ref -> 'aほとんどの命令的言語でこの操作は暗黙的ですが、SMLまたはOCamlではそうではありません。
  • (:=) : 'a ref * 'a -> unitは、参照を変更するために使用される中置演算子です。ここでは、整数参照の内容を増やす方法を示します。r := !r + 1。上記の私たちに次のコードを与える

(私が代わりにそれらを追加するのは、リスト上にx Sを付加):関数型プログラミングで

local 
    val rxs = ref [] 
in 
    fun insert (x:int) : string = 
     (rxs := x :: !rxs; 
     Int.toString (length (!rxs))) 
end 
1

値はSMLでは不変です。 insertは、all_listの値が[]であり、コードの価値がその値を変更しないというコンテキストで定義されています。

[email protected][x] 

は値all_listを変化させません - それはブランドの新しいリスト、あなたのコードは、速やかに(その長さを取った後)捨てるものを返します。

リファレンスタイプ(SMLの不純な機能の1つ)を使用すると、実行しようとしていることを行うことはできますが、結果のコードは慣用的なSMLではありません。参照透過性(同一の入力で呼び出された関数が同じ出力をもたらす関数型プログラミング言語の望ましい特徴)を壊すでしょう。

関連する問題