这是一个单子吗?

jcu*_*bic 13 javascript monads functional-programming

我试图理解monads的概念,我想知道这个代码是否是这个概念的实现(在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;
});
Run Code Online (Sandbox Code Playgroud)

然后我可以链接foo的方法

foo.setX(10).addX(20).addX(30).getX()
Run Code Online (Sandbox Code Playgroud)

将返回60

如果我有方法对象并使用此对象调用M,则相同.

var foo = {
  x: 10,
  add: function(x) {
    this.x += x;
  }
};

M(foo).add(10).add(20).add(30).x
Run Code Online (Sandbox Code Playgroud)

将返回70

函数包含在M对象中,因此方法内的this context始终是M对象.

f = M({x: 20}).set('getX', function() {
   return this.x; 
}).set('addX', function(x) {
   this.x += x;
}).addX(10).getX
Run Code Online (Sandbox Code Playgroud)

所以f是由M包裹的对象的上下文的函数 - 如果我调用f()它将返回30.

我理解正确吗?M是monad吗?

编辑修改后的代码在github上https://github.com/jcubic/monadic

Hea*_*ink 14

这是一种幺半群模式.每个状态更新操作,例如.setX(10),.addX(20)等等,是变换一个对象的计算.(要在语法上有效,你必须把它写成一个参数函数function(x) {x.addX(20);},但我认为如果我使用短格式它会更清楚.)

有两件事使它成为一个幺半群.首先,有一个标识元素:.addX(0)对它的对象没有任何作用.其次,可以组合任何两个操作.例如,.setX(10).addX(20)也是转换一个对象的计算.

它不是一个单子.您的方法支持的计算仅限于编写和更新this.x.(.getX()不是幺半群的成员,因为你不能在它之后链接任何东西).例如,使用monad,您可以让一个操作链中的一个成员执行if-then-else来决定链中接下来会发生什么.你的方法不能那样做.