在上一章,我们提到了如何用一般方法实作 PRNG 乱数生成器,本章将介绍 State Monad 以及改写上一章的范例,废话不多说让我们看下去吧!
concept
State a s
State Monad 的 constructor 也跟 Reader Monad一样,都是放入函式,比较值得注意的是,State 里面包含了 s
与 a
, s
表示为状态, a
则是结果
const State = run => ({
run,
})
State.of = a => State(s => [a, s])
而 State Functor 则可以将 a
进行 trasnform,
const State = run => ({
run,
map: f => State(a => {
const [y, s] = run(a);
return [f(y), s]
})
})
这样就可将前一篇的 randomInRange
先改为
const seed = 1;
const randomInRange = (min, max) => s =>
State(generator).map(value).map(normalize(min, max)).run(s);
randomInRange(0, 1)(seed)
// [5, 1103527590]
再来将前一章最後的范例改为
const nameList = ["jing", "jing*5", "jing-tech"];
const randomName = (from) => (seed) =>
randomInRange(0, from.length)
.map((index) => from[index])
.run(seed);
const [name, r1] = randomName(nameList)(1); // ["jing*5", 1103527590]
是不是清楚很多了!!
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)
}),
});
当然也可以将两个 State Monad 作结合,例如是要继续精进自己,还是当懒虫。
const randomInRange = (min, max) =>
State(generator).map(value).map(normalize(min, max));
const randomFrom = (from) =>
randomInRange(0, from.length).map((index) => from[index]);
const keepImprove = randomFrom(['Study', 'Coding', "Writing"]);
const lazy = randomFrom(['Couch Potato', 'Netflix']);
const seed = 1;
const result = randomInRange(0, 1)
.map((n) => n === 1)
.chain((bool) => (bool ? keepImprove : lazy))
.run(seed); // ["Couch Potato", 377401600]
OKAY,result 竟然是怂恿笔者当 Couch Potato,那就不客气了!决定把剩下的留到下一章写,感谢大家阅读!!!
<<: D28 / Compose 可以用来做 Desktop App? - Compose JB
什麽是机器学习? 机器学习是一种能够赋予机器学习的能力,以让机器完成直接编程所无法完成的任务的方法。...
前言 主要籍由这个主题,熟悉永丰金融API的相关操作。 将系列文章 做一下规划 环境建置 API串接...
Chap.IV Data Services 资料库服务 SQL Databases SQL 资料库 ...
感觉和知觉可说是心理学最早被定义出来的两个名词,甚至可能比心理学这门学问本身诞生的还要早。最一开始他...
以下内容同步更新於 https://kevinyay945.com/smart-home-tutor...