我实现的JS链式调用代码是否符合Functor的定义?
结论
你实现的这段代码不符合Functor的标准定义,核心问题出在map方法的行为和Functor要求的规则不匹配。
Functor的两个必须满足的核心定律
- 恒等定律:任意Functor实例调用
map(x => x)(传入恒等函数),返回的新实例必须和原实例完全等价 - 组合定律:对任意两个函数
a、b,f.map(x => a(b(x)))的执行结果,必须和f.map(b).map(a)的执行结果完全等价
你的代码不符合规则的原因
你设计的map没有把传入函数的返回值直接作为新实例包裹的内容,而是额外做了对象合并操作:{...store, ...result}。举个简单的反例:
// 按照你的代码逻辑执行 const res = Init({a: 1}).map(store => ({b: 2})).unwrap() // 你得到的res是 {a:1, b:2},而不是传入map的函数返回的 {b:2}
Functor的map定义就是对包裹的内部值做纯映射,新实例包裹的值就是函数的返回值,不能插入合并这类额外逻辑,所以你的实现不满足Functor的要求。
怎么改能变成标准Functor
把map的逻辑调整成直接把函数返回值作为新实例的store即可,这就是最基础的Identity Functor:
function Init(store = {}) { const map = (fn) => { // 直接把fn返回值作为新的store,不做合并 return Init(fn(store)) } const unwrap = () => store return { map, unwrap } }
额外说明
你原本的实现是一个很实用的链式状态更新工具,逻辑类似简化版的State Monad变种,但也不满足Monad的标准定义,Monad要求的flatMap逻辑同样需要遵循对应的定律,不能做自定义的合并操作。
内容的提问来源于stack exchange,提问作者user8190223
相关产品推荐
相关产品推荐

