Как выглядит пример кода JavaScript, который использует Monad? Я спрашиваю, потому что понимание Монады намного яснее, если я могу увидеть пример кода (а JavaScript - простой, функциональный язык, который может быть лучшим языком для изучения).
Монады в JavaScript?
Ответ 1
Я бы начал с написания вашей собственной монады в JavaScript. Монада списка - отличное место для начала; Я нахожу его безусловно полезным. Просто определите функции, которые выполняют следующие действия:
- Создайте список одного заданного элемента (назовите это
mreturn
). - Создайте пустой список (назовите это
mzero
). - Добавить один список в другой (назовите это
mplus
). - Применить функцию для преобразования каждого элемента в данный список (назовите это
map
). - "Сгладить список списков в простой список, объединив списки (назовите это
join
).
Это определяет то, что известно как "аддитивная монада" (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() } }
);
Наконец, вы можете захотеть включить эти функции в состав нового прототипа списка (или того, что JavaScript пропускает для классов в наши дни), поэтому вы можете написать 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() } });