首页 > 其他 > 详细

[Functional Programming] Alternative operator for Either

时间:2020-06-02 16:46:42      阅读:42      评论:0      收藏:0      [点我收藏+]

Thinking about Promise.all, once there is a Promise in the list fails, the whole promise fails.

There would be good to have an ‘Alernative‘ operator, which just skip the failling one, and continue the work. ‘Alternative‘ works for Either data type;

const Right = (x) => ({
  x,
  chain: (f) => f(x),
  map: (f) => Right(f(x)),
  concat: (o) => Right(x.concat(o.x)),
  fold: (f, g) => g(x),
  isRight: true,
  isLeft: false,
  toString: `Right(${x})`,
});

const Left = (x) => ({
  x,
  chain: (f) => Left(x),
  map: (f) => Left(x),
  concat: (o) => Left(x),
  fold: (f, g) => f(x),
  isRight: false,
  isLeft: true,
  toString: `Left(${x})`,
});

const Alternative = (ex) => ({
  ex,
  concat: (o) => Alternative(o.ex.isLeft ? ex : ex.concat(o.ex)),
});

 

Run:

const res = Alternative(Right("hello"))
  .concat(Alternative(Right("world")))
  .concat(Alternative(Left("errrr")))
  .concat(Alternative(Right("!!")));
console.log(res.ex.fold(identity, identity)); // helloworld!!

 

Simpify the code:

const List = (x) => ({
  x,
  foldMap(type, _empty) {
    const empty = _empty ? _empty : type.empty();
    if (!empty) throw new Error(`foldMap expect an empty as second value`);
    return x.map(type).reduce((acc, curr) => {
      return acc.concat(curr);
    }, empty);
  },
});
const res1 = List([
  Right("hello"),
  Right("world"),
  Left("errrr"),
  Right("!!!!"),
]).foldMap(Alternative, Alternative(Right("")));
console.log(res1.ex.fold(identity, identity)); // helloworld!!!!

 

[Functional Programming] Alternative operator for Either

原文:https://www.cnblogs.com/Answer1215/p/13031395.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!