2017-04-23 12 views
2

をカリー化すること:F#の純粋な機能と私が機能している場合

let f (myClass : MyClass) x = 
    // do something using the instance of myClass and x 

を、私はこのようにfをカレー:

let myClass = new MyClass() 
let g = f myClass 

ので、私はちょうど

let something = f 42 

を呼び出すことができますGA純粋です関数?それとも、MyClassのインスタンスへの参照が取得されていますか?

答えて

2

関数が呼び出す関数(またはメソッド)と、それらの関数(またはメソッド)が純粋かどうかによって異なります。キャプチャされたオブジェクトは完全に無関係です。

関数は、(1)常に同じ引数で同じ結果を返し、(2)入力/出力や突然変異などの副作用が発生しないという条件データ)。関数がクロージャーでキャプチャされたデータを持っているかどうかは、純度の概念とはほとんど関係がありません。

let f (c: MyClass) x = if c = null then x else x+1 
let g = f (MyClass()) 

しかし、次のような機能は、それがどのようなデータをキャプチャしていなくても、不純です:

たとえば、次の関数は、それがクロージャ内のオブジェクトをキャプチャしていても、純粋になります

let g1 x = printfn "%d" x 
let g2 x = System.DateTime.Now.Minute + x 

この例では、g1は、コンソールへの出力の形で副作用が発生するため、無効です。 g2は、呼び出されるたびに別の結果を返すため、不都合です。

純粋さのこの定義の背後にある元の考え方(「参照透過性」とも呼ばれる)は、プログラム内の純関数の呼び出しを、プログラムの意味を警告することなくその結果と置き換えることができるということでした。これは、すべての種類の最適化とプルーフに役立ちます。そのプログラムのコンソール出力を変更するので、

は、例えば、(上記で定義した通り)gの任意の呼び出しを安全に(例えば6g 5を置き換える)、その結果に置き換えることができるが、g1の呼び出しができません。

関連する問題