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!!!!
  • 相关阅读:
    RSA使用
    C#获取主机信息
    NSIS打包软件使用
    C#获取局域网主机
    C#实现Web链接启动应用程序
    4.布局介绍
    Server Sql 多表查询、子查询和分页
    C# File类常用方法
    Vue 使用技巧手记
    前端面试题手记
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13031395.html
Copyright © 2011-2022 走看看