我试图理解 monad 的概念,我想知道这段代码是否是这个概念的实现(在 JavaScript 中)。
我有函数 M,它返回具有创建包装器方法的 set 方法的新对象
var foo = M().set('getX', function() {
return this.x;
}).set('setX', function(x) {
this.x = x;
}).set('addX', function(x) {
this.x += x;
});
然后我可以链接 foo 的方法
foo.setX(10).addX(20).addX(30).getX()
将返回 60
如果我有带方法的对象并用这个对象调用 M,也是一样。
var foo = {
x: 10,
add: function(x) {
this.x += x;
}
};
M(foo).add(10).add(20).add(30).x
将返回 70
函数被包装在 M 对象中,因此方法中的 this 上下文始终是 M 对象。
f = M({x: 20}).set('getX', function() {
return this.x;
}).set('addX', function(x) {
this.x += x;
}).addX(10).getX
所以 f 是一个函数,对象上下文被 M 包裹——如果我调用 f()
它将返回 30。
我的理解正确吗? M 是单子(monad)吗?
EDIT 修改后的代码在github上https://github.com/jcubic/monadic
最佳答案
这是一个幺半群模式。每个状态更新操作,例如 .setX(10)
、.addX(20)
等等,都是一种转换一个对象的计算。 (为了在语法上有效,您必须将其编写为单参数函数 function(x) {x.addX(20);}
,但我认为如果使用缩写形式会更清楚.)
有两件事使它成为一个幺半群。首先,有一个标识元素:.addX(0)
不对其对象执行任何操作。其次,可以组合任何两个操作。例如,.setX(10).addX(20)
也是一种转换一个对象的计算。
它不是单子(monad)。您的方法支持的计算仅限于编写和更新 this.x
。 (.getX()
不是幺半群的成员,因为你不能在它后面链接任何东西)。例如,使用 monad,您可以让操作链中的一个成员执行 if-then-else 来决定链中的下一步。您的方法无法做到这一点。
关于javascript - 这是单子(monad)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5058124/