Day 28 - State Monad III

嗨大家好,真希望一天能有 48 小时,不然这主题都要分到四部曲了,没错,应该会有四部曲! 抱歉了!

Applicative Functor

上次提到了 mapchain 的用法,当然也可以用将多个 State monad 套用在函式参数长度为多个以上

const State = (run) => ({
  run,
  map: (f) =>
    State((a) => {
      const [y, s] = run(a);
      return [f(y), s];
    }),
  chain: (f) =>
    State((x) => {
      const [y, s] = run(x);
      return f(y).run(s);
    }),
  ap: (m) =>
    State((x) => {
      const [y, s] = run(x);
      return m.map(y).run(s);
    }),
});

而这概念也提过很多次,就不多做赘述了~

State.of(1).map(R.add).ap(State.of(1)).run() // [3, undefined]

如果今天是要将一个 Array 内多个 State Monad (Array<State>)进行运算并转换成 State Array s 呢? 当然也可以还记得在 Traversable 那章提过的吗? 其要件就是同时要有 Foldable 以及 Functor 的特性

Travserable

首先来记得 Array 也有 traverse 的特性吗?

Array.prototype.traverse = function (T, f) {
  return this.reduce(
    (acc, val) =>
      f(val)
        .map((x) => (y) => y.concat(x))
        .ap(acc),
    T.of([])
  );
};

在来就是准备多个 State Monad 塞到阵列

const generator = (seed) => {
  const nextSeed = (seed * 1103515245 + 12345) & 0x7fffffff;
  return [nextSeed, nextSeed];
};

const value = (seed) => (seed >>> 16) / 0x7fff;

const normalize = (min, max) => (x) => Math.floor(x * (max - min)) + min;

const randomInRange = (min, max) =>
  State(generator).map(value).map(normalize(min, max));
  
const randomFrom = (from) =>
  randomInRange(0, from.length).map((index) => from[index]);

const FisrtRandom = randomFrom(['FP', 'OOP', 'BOTH']);
const MiddleRandom = randomFrom(['IS', 'ARE']);
const LastRandom = randomFrom(['GOOD', 'SUCK']);

const combineIt = [FisrtRandom, MiddleRandom, LastRandom]

这样就完成多组同时进行随机抽取了!!! 猜猜这次的结果会是什麽吧!

const seed = 1;

combineIt.traverse(State, R.identity)
  .map(([x, y, z]) => `${x} ${y} ${z}`)
  .run(seed);
  
// ["FP IS SUCK", 333417792]

Oops! 怎麽会这样... 突然觉得变搞笑文章系列,Anyway, That's it for today!

小结

感谢大家阅读!!!

Reference

  1. State Monad

<<:  [Day_29]函式与递回_(8)

>>:  流程与制度 - 打造一个「人」的系统

RxJS 条件/布林类型 Operators (1) - isEmpty / defaultIfEmpty / find / finxIndex / every

今天介绍「条件/布林类型」的 operators,这类型的 operators 都是用来判断整个 O...

[Day 15]呐呐,还有一半别想跑(前端篇)

挑战目标: MockNative Camp 今天继续来制作我们的Footer, 目标 前两天我们已经...

[第20天]理财达人Mx. Ada-Telegram Bot-echo测试

前言 本文说明使用Python建立Telegram Bot-echo测试 。 程序实作 from t...

电路级(Circuit-level)授权策略不是常见的服务网格授权策略类型

以下是 NIST SP 800-204B 的摘录: 可以通过配置身份验证和存取控制策略来实施对微服务...

Day 19: 人工智慧在音乐领域的应用 (AI作曲-基因演算法三 音乐间的交配)

今天我们继续介绍基因演算法作曲。 昨天我们介绍了如何让电脑看得懂音乐/音符的样子以及如何对基因演算法...