javascript - 这是单子(monad)吗?

标签 javascript functional-programming monads

我试图理解 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/

相关文章:

javascript - 滚动浏览彼此堆叠的 div

javascript - 浏览器之间的按钮 css 不一致

javascript - 删除下拉列表中的垂直滚动条

haskell - 定义自制 monad 变压器的绑定(bind)

haskell - (>>=) 和 (>=>) 之间的区别

haskell - IO Monad 记录更新失败?

javascript - 水平排列动态内容

functional-programming - 什么是 'Closure' ?

rust - 为什么我得到 FromIterator<&T>` is not Implemented for Vec<T>?

haskell - `++` 的 `foldr` 实现是如何工作的?