2016-06-15 12 views
0

나는 순수한 코드와 불순한 코드를 분리하는 데 IO가 사용된다는 것을 알고 있습니다. 또한 IO는 참조 투명성을 허용한다는 것을 알고 있습니다.원하지 않는 효과가없는 IO 모나드에 포함 된 합성 함수가 있습니까?

입출력에 관한 한 가지 사실은 여전히 ​​나에게 조금 어둡습니다. 즉, 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 지연 (게으른)과 같은 기능 체인의 평가는 작동중인 값에 영향을주지 않습니다.

자바 스크립트의 맥락에서 모든 값은 참조입니다. 범위 내에서 참조를 갖는 스택상의 모든 함수는 상기 참조의 값을 변경할 수 있습니다. IO가 1100의 값을 반환하는 것을 보여주는 예제 코드에 대해 이것이 무엇을 의미하는지 보여 드리겠습니다. 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에서 모든 타입의 클로저에 적용됩니다.선언 한 후에 입출력에 클로저를 채우는 것은 중요하지 않습니다. 동일한 규칙이 적용될 것입니다.