使用 Monad 的示例 JavaScript 代码看起来如何?我问是因为如果我能看到一个代码示例(并且 JavaScript 是一种简单的函数式语言,它可能是学习它的最佳语言),对 Monad 的理解会更清楚。
最佳答案
我将从用 JavaScript 编写您自己的 monad 开始。 list monad 是一个很好的起点;我发现它是迄今为止最有用的。只需定义执行以下操作的函数:
- 创建一个给定项目的列表(称之为
mreturn
)。 - 创建一个空列表(称之为
mzero
)。 - 将一个列表附加到另一个列表(称为
mplus
)。 - 应用一个函数来转换给定列表中的每个元素(调用此
map
)。 - 通过连接列表(称之为
join
)将列表列表“扁平化”为一个简单列表。
这定义了所谓的“加法 monad”(mzero
和 mplus
形成了“加法”部分)。试一试,看看仅使用这些函数 对列表进行操作可以做些什么有趣的事情。例如,您可以像这样计算小学生乘法表中所有偶数的列表:
var nums = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var even_products = join(map(join(map(nums, function (x) {
return map(nums, function(y) { return x * y })
})),
function (x) { if (x % 2 == 0) { return mreturn(x) } else { return mzero() } }
));
或者,将 map
和 join
合并为一个函数,定义为 function bind(l, f) { return join(map(l, f) )
。 bind
可以用来代替 map
和 join
并且更常用于例如 haskell 。然后可以编写上面的相同练习:
var nums = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var even_products = bind(
bind(nums, function (x) {
return bind(nums, function (y) { return mreturn(x * y) })
}),
function (x) { if (x % 2 == 0) { return mreturn(x) } else { return mzero() } }
);
最后,您可能希望将这些函数合并为新列表原型(prototype)的一部分(或如今用于类的任何 JavaScript),因此您可以改为编写 jQuery 式的:
var nums = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var even_products = nums
.bind(function (x) { return nums.bind(function (y) { return mreturn(x * y) }) })
.bind(function (x) { if (x % 2 == 0) { return mreturn(x) } else { return mzero() } });
关于javascript - JavaScript 中的单子(monad)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8656172/