2016-06-15 7 views
0

Я понимаю, что IO используется для отделения чистого кода от нечистого. Кроме того, я знаю, что 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, отложенная (ленивая), не влияет на значения, на которых они работают.

В контексте javascript все значения являются ссылками. Любая функция в стеке, которая имеет свою область действия, ссылку, может изменить значение указанной ссылки. Позвольте мне показать вам, что это означает для вашего собственного примера кода, показывающего IO, возвращающее значение 1100 независимо от того, что. Когда я изменяю значение x до или после объявления обмотки IO 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 

Мы ожидали, что действие ввода-вывода, чтобы привести к 1100, но istead мы получили 1200. Помните, что когда мы создали наш IO, мы использовали ссылку, а не значение. Это справедливо для любого типа закрытия в Javascript.неважно, если вы закроете закрытие в IO после того, как вы его объявите, те же правила будут применяться.

 Смежные вопросы

  • Нет связанных вопросов^_^