2016-06-15 6 views
0

私は、純粋なコードと純粋でないコードとを区別するためにIOが使用されることを理解します。また、私はIOが参照透過性を持つことを認識しています。IOモナドに含まれる合成機能は、望ましくない効果がないことが保証されていますか?

IOについての1つのことは、まだ私にはやや不明です。つまり、IO間には何も悪いことが起こらないという保証があります。なぜなら、呼び出されたときにすべてが一度に実行されるからです。したがって、この怠け者の合成が最後に呼び出されると、他の並行コードはそれを歪めることはありません(この怠惰な合成)。

これは本当ですか? IOはこのようなコードよりも(この文脈で)良いでしょうか?

var x = 1; //shared resource 

//some other code access and changes x to 2 

const y = multiplyBy100(x); 
const z = add1000(y); 

log(z); // 1200 instead of desired 1100 

私はIOがこのような問題の解決策であることを理解しています。

IO(function() {return x;}).map(multiplyBy100).map(add1000).map(log); //1100 no matter what 

私の推論は大丈夫ですか?

答えて

0

IOモナドが不純な動作と純粋な動作の分離を可能にするということは、正しい方向から考え始めることになります。

また、私はIOが参照透過を許していることを認識しています。

IO自体のセマンティクスと、外部のコードに与える利点とを混在させている可能性があります。 IOは、それ自体では参照透過性をあまり許さず、代わりに、参照透過性を失うことなく、参照透過的(純粋)な機能がIO内に含まれる不純な動作とインタフェースすることを可能にする。

IOアクションを作成して実行すると、結果はではなく、であることが保証されていることが保証されています。私たちがIOが不公平な行動のための投機の場であるという理解で武装しているとき、これは驚くべきことではありません。この怠惰な組成物が最終的に呼び出されたときに

ので、他の同時 コードは、(この怠惰な組成物)を歪めることはできません。

残念ながら、それほど単純ではありません。コードが怠惰であっても、それは情報を透明にしません。 IOが遅れている(遅延している)ような一連の機能の評価は、それらが動作している値には関係しません。

javascriptのコンテキストでは、すべての値が参照です。スコープ内にある参照(参照)を持つスタック上の関数は、その参照の値を変更できます。どのような値であっても1100の値を返すIOを示すあなたのサンプルコードのために、これが何を意味するのかを教えてください。 IOラッピングxを宣言する前または後にxの値を変更すると、IOによって返された値にそのような変更が反映されます。したがって、このコードは//1100 no matter whatを返しませんが、実際には1200を返します。

function switcharoo() { 
    x = 2; 
} 

var x = 1; 

var IOdoMaths = IO(() => x).map(x => x * 100).map(x => x + 1000); 

// Some concurrent proccess calls this 
switcharoo(); 

var result = IOdoMaths.runIO(); 

console.log(result); // 1200 

我々はIOアクションが1100をもたらすと期待していたが、istead我々は1200を得ました。 IOを作成したときに、値ではなく参照をラップしたことを覚えておいてください。これは、Javascriptの任意のタイプのクロージャーに当てはまります。あなたがそれを宣言した後に閉鎖をIOに入れたら、同じルールが適用されます。

関連する問題