今天来介绍 Reader Monad,其主要处理的就是 dependency injection,
说到 dependency injection 如果最坏的情况就是要将值不断的传下去,但中间的函式都不会用到该值
const toUpper = str => str.toUpperCase();
const exlaim = str => str.concat('!');
const deps = {
"i18n": {
"HELLO FP!!": "嗨 函数式编程!"
}
}
const f = (str, deps) => deps.i18n[str]
const g = (upper, deps) => f(exlaim(upper), deps)
const h = (str, deps) => g(toUpper(str), deps)
h('hello fp!', deps) // "嗨 函数式编程!"
可以看到 g
以及 h
就只是将 deps
传下去而已,本身根本没用到,这样不是很冗余吗? 而 Reader Monad 就是来解决这个痛点的! 首先先来看看最初的起点 Function Modeling
什麽是 Functions Modeling 呢? 回想一下前面几章无论是 Either, Maybe 又或是 IO 都是放入单一型别(Object
, String
, ...) ,但如果现在想要放入的是函式呢?
举例来说
const Function = (run) => ({
run,
})
如果想要让 Function
变成是一个 Functor 呢?
const Function = run => ({
run,
map: f => Function(x => f(run(x)))
})
可以看到 map
就是将函式进行 compose,
Function(toUpper)
.map(exlaim)
.run('hello fp!') // HELLO FP!!
那想要将两个 Function Monad
进行 compose 呢?
const Function = run => ({
run,
map: f => Function(x => f(run(x))),
chain: f => Function(x => f(run(x)).run(x))
})
接下来就可以将两个 Monad 进行 compose 了!
Function(toUpper)
.chain(upper => Function(x => exlaim(upper)))
.run('hello fp!') // HELLO FP!!
也可将 Function 变成 pointed functor
Function.of = x => Fn(() => x)
大家这时应该就会好奇,那 x
是什麽呢? 可以先印出来看看
Function(toUpper)
.chain(upper => Function(x => console.log(x, exlaim(upper))))
.run('hello fp!') // hello fp! HELLO FP!!
没错 x
就是原本放入 run
的参数,而这有什麽用呢? 如果现在要做 dependency injection,例如 DB 的 config 注入等等,就可以派上很大的用场!
所以来改写上述痛点!
Function.of('hello fp!')
.map(toUpper)
.chain((upper) => Function((deps) => deps.i18n[exlaim(upper)]))
.run(deps); // 嗨 函数式编程!!
另外,Function ADT 通常会有一个优化的 API,ask
,其主要就是取 run
传入的值(deps)
Function.ask = Function(x => x)
再将上面程序码套用 ask
Function.of('hello fp!')
.map(toUpper)
.map(exlaim)
.chain((str) => Function.ask.map((deps) => deps.i18n[str]))
.run(deps); // 嗨 函数式编程!!
而这也被称为 Reader Monad!
感谢大家阅读!!
<<: 第 25 集:Bootstrap 客制化 RFS 响应式文字
>>: Day 25 : 插件篇 04 — 如何让 Obsidian 自动推荐关联笔记 (下)?介绍我的笔记架构与 Breadcrumbs 实战应用
在将主内存分配给操作系统中的进程时,有两个主要部分。 在连续内存分配中,进程被分配主内存的顺序块给整...
该文章同步发布於:我的部落格 After Hooks 之前有介绍过 before hooks 的使...
第 13 天要介绍 defer 是什麽,那麽我们就进入正题吧 ─=≡Σ(((っ゚∀゚)っ defer...
缘由: 在职训时老师讲解语法,讲到Dictionary(字典)时,有一种老师说的我都懂,看起来没什麽...
话不多说,赶紧把我们的作品Demo 给我们 铁人学院的业主吧!! Demo 进入主画面 我们可以透过...