Либо Монада: Как собрать все правильные ценности и поработать со всеми из них в конце?
Поэтому я пытаюсь собрать все правильные значения из серии результатов Either и получить их все в конце цепочки для работы над ними. Я также хочу, чтобы цепочка быстро выходила из строя, если одно из значений Either равно Left.
Поэтому после прочтения я верю, что ключом к тому, чтобы все это заработало, является сочетание функции с карри и аппликативного функтора.
Ниже приведен пример кода, который у меня пока не работает. Обратите внимание, что я использую monet.js и lodash:
const test1 = Right('test1');
const test2 = Left('test2');
const test3 = Right('test3');
function success(val, val2, val3){
return {
val, val2, val3
};
}
const curriedFn = _.curry(success);
Right(curriedFn)
.ap(Right(function(fn){
return fn(test1);
}))
.ap(Right(function(fn){
return fn(test1);
}))
.ap(Right(function(fn){
return fn(test1);
}))
.map(function(res){
console.log(res);
});
В самом конце я получаю объект, который содержит 3 любых значения, которые выглядят так:
{ val: { isRightValue: true, value: 'test1' },
val2: { isRightValue: true, value: 'test1' },
val3: { isRightValue: true, value: 'test1' } }
То, что я хочу, это 3 фактических значения. И если вы видите, одно из значений Either - это Left, и цепь должна была быть разорвана.
Я пытаюсь сделать это чисто функциональным способом. Вот почему я не отображаю и не вставляю значения в объект вне рамок функций.
Есть идеи? Альтернативы?
2 ответа
Поэтому я неправильно прочитал документы: https://monet.github.io/monet.js/
Вы должны вложить последовательный .ap
звонки. Ниже приведен переработанный пример того, что я пытался сделать выше:
const test1 = Right('test1');
const test2 = Right('test2');
const test3 = Right('test3');
const success = _.curry(function (val, val2, val3){
return {
val,
val2,
val3
};
});
test3.ap(test2.ap(test1.map(success)))
.map(success => {
console.log(success)
});
Я уверен, что есть элегантный способ compose
или какая-то другая монада, чтобы расплющить цепь, но пока я доволен.
Похоже, вы используете .ap
неверно
const Either =
require ('data.either')
const { Left, Right } =
Either
const success = x => y => z =>
[ x, y, z ]
const a =
Right (1)
const b =
Right (2)
const c =
Right (3)
const badegg =
Left ('badegg')
Если success
применяется к badegg
для любого параметра, немедленным результатом будет Left
, Последующие звонки .ap
не повлияет на Left
Right (success)
.ap (a)
.ap (b)
.ap (c)
.fold (console.error, console.log) // [ 1, 2, 3 ]
Right (success)
.ap (badegg)
.ap (b)
.ap (c)
.fold (console.error, console.log) // "badegg"
Right (success)
.ap (a)
.ap (badegg)
.ap (c)
.fold (console.error, console.log) // "badegg"
Right (success)
.ap (a)
.ap (b)
.ap (badegg)
.fold (console.error, console.log) // "badegg"