Javascript 读者Monad&x27的目的是什么;什么是局部函数?

Javascript 读者Monad&x27的目的是什么;什么是局部函数?,javascript,Javascript,简单地说,读取器Monad只是一个函数的包装器。这有利于通过计算隐式传递配置信息: const ap=f=>x=>f(x); 常数id=x=>x; 常数co=x=>y=>x; 常数comp=f=>g=>x=>f(g(x)); const Reader=ap(cons=>f=>{ const t=新cons(); t、 run=x=>f(x); 返回t; })(函数读取器(){}); Reader.map=f=>tf=>Reader(comp(f)(tf.run)); Reader.ap=af=

简单地说,读取器Monad只是一个函数的包装器。这有利于通过计算隐式传递配置信息:

const ap=f=>x=>f(x);
常数id=x=>x;
常数co=x=>y=>x;
常数comp=f=>g=>x=>f(g(x));
const Reader=ap(cons=>f=>{
const t=新cons();
t、 run=x=>f(x);
返回t;
})(函数读取器(){});
Reader.map=f=>tf=>Reader(comp(f)(tf.run));
Reader.ap=af=>ag=>Reader(x=>af.run(x)(ag.run(x));
Reader.chain=mf=>fm=>Reader(x=>fm(mf.run(x)).run(x));
Reader.of=f=>Reader(co(f));
Reader.ask=()=>Reader(id);
Reader.ask=f=>Reader.chain(Reader.ask)(x=>Reader.of(f(x));
Reader.local=f=>tf=>Reader(comp(tf.run)(f));
常数compM=tDict=>fm=>gm=>x=>
tDict.链(tDict.链(tDict.of(x))(gm))(fm);
const foo=n=>Reader(env=>(console.log(env),n+1)),
c=compM(读卡器)(foo)(foo)(2);
console.log(
c、 运行(“共享环境”)
);
我知道
local
只是
contracmap
,但这没有多大帮助。那么它的目的是什么呢

嗯,
contracmap
map
一样重要–在(这里翻译成JS)中,
local
允许在下一位读者获得值之前影响该值

const calculateLength =
  Reader.map (s => s.length) (Reader.ask ())

const calculateModifiedLength = 
  Reader.local (s => 'Prefix ' + s) (calculateLength)

console.log (calculateLength.run ('12345'))
// '12345'.length == 5
// => 5    

console.log (calculateModifiedLength.run ('12345'))
// 'Prefix 12345'.length == 12
// => 12
这是你的读者蒙纳德,他被重新格式化了。我包括了每个函数的演示,以便我们可以验证每个结果是否正确。谢谢你让我终于了解了这个有趣的单子

const Reader=f=>
({run:x=>f(x)})
Reader.of=x=>
读卡器(()=>x)
Reader.chain=f=>m=>
读卡器(x=>f(m.run(x)).run(x))
Reader.map=f=>m=>
读卡器(x=>f(m.run(x)))
Reader.ap=f=>m=>
读卡器(x=>f.run(x)(m.run(x)))
Reader.join=m=>
读卡器(x=>m.run(x.run(x))
Reader.ask=()=>
读者(身份)
Reader.local=f=>m=>
读卡器(x=>m.run(f(x)))
常量标识=x=>x
常数sq=x=>x*x
常量add=x=>y=>x+y
常数计算长度=
Reader.map(s=>s.length)(Reader.ask())
常量calculateModifiedLength=
Reader.local(s=>Prefix'+s)(calculateLength)
console.log
(Reader.chain(x=>Reader.of(x+1))(Reader(sq)).run(4)//17 sq(4)+1
,Reader.chain(x=>Reader(add(x)))(Reader(sq)).run(4)//20sq(4)+4
,Reader.map(sq)(Reader(sq)).run(4)//256 sq(sq(4))
,Reader.ap(Reader.of(sq))(Reader.of(4)).run()//16 sq(4)
,Reader.ap(Reader(add))(Reader(sq))。运行(4)//20 sq(4)+4
,Reader.join(Reader.of(Reader.of(4))).run()//4
,Reader.ask().run(4)//4
,calculateLength.run('12345')//5'12345'。长度
,calculateModifiedLength.run('12345')//12'前缀12345'.length

)
您在哪里找到此代码的?请链接它的来源。(如果你在理解上有困难的话,听起来并不是你自己写的)我现在强迫自己去了解读者monad,这样也许我可以为这次对话做出贡献^_^@Bergi实际上是我自己写的,主要是基于Haskell类型的签名。单子模式是重复出现的,为特定的单子复制它通常不是那么困难。然而,我经常发现很难应用这种模式或识别合适的用例。你看到了吗?@Bergi不,我没有。我试着翻译它,然后把它作为一个答案发布。哦,你做了我应该做的工作…谢谢!我怀疑
local
会包含更多的“魔力”。但是它只是
contracmap
local
的签名不是
Reader.local:(f->e)->Reader ea->Reader fa
,因为它只是
contracmap
?当然,你在
f~e
时给出的签名是有效的,但为什么只限于这种情况?@M.Aroosi我最后的评论是不准确的。当您将常规单子类型
ma
映射到它的
Reader
实例
Reader ea
时,
m
对应于
Reader e
,而
a
对应于
a
。现在很明显,您不能更改
e
s类型,因为
e
是要保留的上下文的一部分。不管怎么说,我不是想在这方面教训你。它更适合未来的读者…@ftor
Monad
不包含
local
的定义
local
Reader
所特有的(或者如果我们查看Haskell的mtl库,可以查看
monawarder
类型类,在这种情况下,您的参数成立)。但这是一个Javascript问题,Javascript没有类型类,甚至没有接口(本机)。根据给定的代码,类型将与我编写的相同。如果你想限制使用(按惯例或其他工具)仅限于WARE
f~e
,但这就像说Haskell的前奏曲
id
的类型是
Monad a=>a->a
,因为你只会这样使用它。只要我的2美分。@M.Aroosi我完全同意你的类型,但是使用一个独特的名称,这样人们就不会期望有特定的行为。