javascript - JavaScript 中的单子(monad)?

标签 javascript functional-programming theory monads

使用 Monad 的示例 JavaScript 代码看起来如何?我问是因为如果我能看到一个代码示例(并且 JavaScript 是一种简单的函数式语言,它可能是学习它的最佳语言),对 Monad 的理解会更清楚。

最佳答案

我将从用 JavaScript 编写您自己的 monad 开始。 list monad 是一个很好的起点;我发现它是迄今为止最有用的。只需定义执行以下操作的函数:

  1. 创建一个给定项目的列表(称之为 mreturn)。
  2. 创建一个空列表(称之为mzero)。
  3. 将一个列表附加到另一个列表(称为 mplus)。
  4. 应用一个函数来转换给定列表中的每个元素(调用此 map)。
  5. 通过连接列表(称之为join)将列表列表“扁平化”为一个简单列表。

这定义了所谓的“加法 monad”(mzeromplus 形成了“加法”部分)。试一试,看看仅使用这些函数 对列表进行操作可以做些什么有趣的事情。例如,您可以像这样计算小学生乘法表中所有偶数的列表:

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() } }
));

或者,将 mapjoin 合并为一个函数,定义为 function bind(l, f) { return join(map(l, f) )bind 可以用来代替 mapjoin 并且更常用于例如 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/

相关文章:

javascript - 使用正则表达式匹配 javascript 中的引号包裹字符串

javascript - Azure 存储上传后会损坏文件吗?

functional-programming - 将节点插入树中 - Racket

c# - 使用 block 分解 C# 以启用函数式编程的模式

python - 如何在 Python 3 中使用过滤器、映射和归约

c# - 部分覆盖子类中的虚拟自动属性

programming-languages - 我想回到 CS 的基础。对教程或注重应用的引用资料有什么建议吗?

javascript - 如何在页面加载时防止 css 关键帧动画?

javascript - 动态重新加载src

windows - Linux Windows 之间的多任务、多线程有什么区别?