JavaScript 中的 Monad?

发布于 2024-12-23 04:44:13 字数 110 浏览 6 评论 0原文

使用 Monad 的 JavaScript 代码示例会是什么样子?我这样问是因为如果我能看到代码示例,理解 Monad 就会更清楚(JavaScript 是一种简单的函数式语言,它可能是学习它的最佳语言)。

How would an example JavaScript code look like that uses Monad? I'm asking because understanding Monad is much clearer if I can see a code example (and JavaScript being a simple, functional language it could be the best language to use to learn it).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴意少年 2024-12-30 04:44:13

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

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

这定义了所谓的“加法单子”(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 组合在一起作为定义为 的单个函数函数绑定(l,f){返回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() } }
);

最后,您可能希望将这些函数合并为新列表原型的一部分(或者当今任何 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() } });

I would start by writing your own monad in JavaScript. The list monad is a great place to start; I find it by far the most useful. Simply define functions which do the following:

  1. Create a list of one given item (call this mreturn).
  2. Create an empty list (call this mzero).
  3. Append one list to another (call this mplus).
  4. Apply a function to transform every element in a given list (call this map).
  5. "Flatten" a list of lists into a simple list by concatenating the lists (call this join).

This defines what's known as an "additive monad" (mzero and mplus form the "additive" part). Play around to see what interesting things you can do using only these functions to operate on lists. For example, you can compute the list of all even numbers on a schoolkid's multiplication table like so:

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

Alternatively, combine map and join together as a single function defined as function bind(l, f) { return join(map(l, f)) }. bind can be used instead of map and join and is used more often in e.g. Haskell. The same exercise above can then be written:

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

Finally, you may want to incorporate these functions as part of a new list prototype (or whatever JavaScript has that passes for classes these days), so you can instead write the jQuery-esque:

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() } });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文