嗨大家好,真希望一天能有 48 小时,不然这主题都要分到四部曲了,没错,应该会有四部曲! 抱歉了!
上次提到了 map
与 chain
的用法,当然也可以用将多个 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 的特性
首先来记得 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!
感谢大家阅读!!!
今天介绍「条件/布林类型」的 operators,这类型的 operators 都是用来判断整个 O...
挑战目标: MockNative Camp 今天继续来制作我们的Footer, 目标 前两天我们已经...
前言 本文说明使用Python建立Telegram Bot-echo测试 。 程序实作 from t...
以下是 NIST SP 800-204B 的摘录: 可以通过配置身份验证和存取控制策略来实施对微服务...
今天我们继续介绍基因演算法作曲。 昨天我们介绍了如何让电脑看得懂音乐/音符的样子以及如何对基因演算法...