私は最近、面白いが厄介なF Sharpの動きに直面した。 [1]によれば、 "F#は自動的にパラメータを取らない関数の値をキャッシュする"。これは良いアイデアのようだが、乱数を生成するためのラッパー関数を試してみると私にとっては問題を引き起こしている。特定の機能のFSharpファンクションキャッシングをオフにしますか?
例として、この質問の最後に2つの異なる機能があります。最初の関数 "getRand"はパラメータを取りませんが、残念ながら常に同じ番号を返します。 2番目の関数 "getRand2"は、呼び出されるたびに新しい乱数を生成すると期待していますが、無意味で無視される余分なパラメータが必要です。
可能であれば、私はgetRand2の機能を持っていますが、getRandの利便性を望みます。 getRand2に適用できるコンパイラ・ディレクティブまたは特別なキーワードがあります。これにより、関数キャッシュ機能がオフになり、getRand2のように動作します。おかげで
、
ショーン
注:答えはすでに[1]、私はちょうど今それを見ていないよに表示されている場合は、私を許してください。
[1] - http://en.wikibooks.org/wiki/F_Sharp_Programming/Caching
(* Always returns the same number *)
let getRand =
let seed = int32(System.DateTime.Now.Ticks)
let randGen = new System.Random(seed)
randGen.Next()
(* Works as expected except I need an annoying extra parameter *)
let getRand2 dummyParam =
let seed = int32(System.DateTime.Now.Ticks)
let randGen = new System.Random(seed)
randGen.Next()
(* Outputs three "identical" numbers to console *)
System.Console.WriteLine(
"Parameterless getRand always outputs same number.")
System.Console.WriteLine(getRand)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand)
System.Console.WriteLine()
(* Outputs three "different" numbers to console *)
System.Console.WriteLine(
"GetRand2 works as expected even though second dummy param is always the same.")
System.Console.WriteLine(getRand2 0)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand2 0)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand2 0)
System.Console.WriteLine()
私はあなたが正しいと思います。私のgetRandのシグネチャを "let getRand ="から "let getRand()="に変更することができますが、それでもgetRandを関数として呼び出す必要があることを認識するのに役立ちました(getRand()、getRandだけではない)...これを回避する方法はありません。 - kvbからの引用。それにもかかわらず、他の誰かがより良い返答を投稿しない限り、あなたは私の回答投票を得るでしょう! –
@Shawn - あなたのコメントからいくつかの詳細を追加しました。 – kvb
* my * getRandが関数にバインドされておらず、単純にint型の値であるというあなたの推論を適用した場合、なぜ同じ値が返され続けるのかが分かります。私はこの説明に感謝します。さらに、* my * getRand2関数が壊れているというあなたの声明に同意します。あなたは正しいです、私は必ずシードを定義し、randGenはgetRandスタイルの構造体を介して返すことを選択した関数の範囲外です。この時点で、私はあなたがこの質問を地面に釘付けにしたと信じています。ありがとう! –