zoukankan      html  css  js  c++  java
  • [Functional Programming] Alternative operator for Either

    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!!!!
  • 相关阅读:
    支付宝沙箱环境应用
    七牛云视频托管
    腾讯云短息验证码接口
    git远程连接(码云)
    git
    字间距
    html文本保留空格
    mysql重启导致AUTO_INCREMENT从1开始
    js保留两位小数
    vue中watch的基本用法
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13031395.html
Copyright © 2011-2022 走看看