Pull to refresh

Comments 23

А вы не путаете мунады с монадами случайно? Теория котегорий появилась около двух часов назад. Аппарат ещё не разработан, школа отсутствует. Даже статьи на википедии ещё нет.
UFO landed and left these words here
На самом деле в динамическом языке существует только один тип, соответственно в категории, где типы языка — объекты, а функции — стрелки, есть только один объект, со стрелками из себя в себя (группоид?), поэтому bbind :: (any -> any) -> any -> any. И bbind может быть как fmap, так и bind. Для нормальной работы list-монады fmap уже будет недостаточно для описания.
Значит цель достигнута. Дело в том, что абстрактный программист с ООП бэкграундом не может с первого раза понять что такое монады и зачем они нужны. Ему придётся прочитать википедию, десятки введений, и, скорее всего, поломать глаза о примеры кода на Haskell. Эта статья претендует на место одного из десятка введений, которые программист в любом случае будет читать.
Ну так поясните что именно:) Я перечитал десятки статей про монады, и после этой статьи наконец-то понял. А тут вы — неправильно…
В статье нет монад. Если автор напишет что-то вроде
console.log(new ListMoonad(«x», [1, 2, 3])
.bbind(ListMoonad(«y», [4,5,6])
.bbind(add(«x», «y»))
.value); // [1+4, 1+5, 1+6, 2+4, 2+5, 2+6, 3+4, 3+5, 3+6]
Тогда будет монада. Точнее, это то — как я вижу решение, хранением словаря внутри Context. А так сплошные функторы с жестко заданной трубой преобразований, а монады позволяют комбинировать результаты разных функций (имитировать присваивание), чем получаются мощнее.
Да не хранит в себе монада ничего такого, о чем вы. Почитайте, во что разворачивается do notation, но я сразу скажу — это всего лишь цепочка лямбд, связываемых bind-ами.
Да, это не то, что написал автор, но ваш код еще дальше от истины, я бы сказал.
Автор в этом плане гениально решил обойтись мунадами, чтобы буквоеды проходили мимо. Расшифрую, что у меня написано. Bind умеет связать результат вычисления с некоторой мнемоникой, которая является именем параметра вложенной функции.
r :: [Integer]
r = do x {- [1,2,3]
y {- [4,5,6]
return (x+y)

{ вместо знака больше, парсер тут крутой.

Как у автора привязать одно значение к «x», другое — к «y», чтобы использовать в третьей функции? Именно используя точки, а не do-нотацию со вложенными лямбдами?
Не, это уже скучно. Честные монады на JS уже где-то писали, выглядели они очень погано и никакого толка в них все равно не было.

По-моему, автор хорошо передал саму идею, зачем эти монады нужны и где они дают преимущества, а точного соответствия в данном случае и не нужно.
Уже непонятно… Я понимаю что вы понимаете, но к сожалению слишком сжатое изложение:(
На самом деле эти мунады есть монады. Но… не честным путём они ими являются. А вот почему:

Для того, чтобы понять, чем мунады не совсем монады надо посмотреть на подпись:
moo_b (moo_a M).bbind (a_to_b function)  {...}

или в нотации Хаскеля
bbind :: (a -> b) -> moo a -> moo b

bbind = fmap

Как видим, bbind на самом деле — функтор.

Монадами мунады стали бы, если можно было написать:
.bbind(function(cityName) { return new MaybeMoonad(cityName); })


Кстати, легко видно как исправить положение — нам надо добавить по строчке в функцию bbind:
XMoonad.prototype.bbind = function(mf) {
 f = mf.value;
...
}

И вот тут превратятся наши гадкие утята — мунады в настоящие монады!

Однако, мунады неотличимы от монад из-за одной хитрости, которые мы соблюдали: все конструкторы должны быть this.value = value;
Пы.Сы. ну и всегда используется в конце runMonad то бишь, M.value
прошу прощения, не так исправил в bbind, вот наша функция:
XMoonad.prototype.bbind = function(mf) {
  ...
  return f(this.value);
}
Официально это набор лучших практик, которыми следует руководствоваться при решении «типичных задач». Неофициально — просто набор костылей для языков, в которых нет встроенных средств для решения типичных проблем.


Золотые слова!

Но как они к м*надам относятся?
А чем в данной статье отличается Context от IdentityMoonad?
Несколько раз пролистал, думал, может какой-то подвох от автора. :)
Ничем. В данном случае переименование позволяет показать, что монада в вырожденном случае — это способ сделать method chaining (builder, fluent interface) с передачей контекста (промежуточного значения).
Как я понял, контекст это общая «база» для всех монад — обертка, в которой хранятся собственно данные. Этот шаг необходим для понимания.
То что в данном примере он ничем не отличается, не столь важно…
Я так понимаю, с Мэйби монадой небольшая ошибочка вышла:

MaybeMoonad.prototype.bbind = function(f) {
  if(this.value == null) {   // было (!this.value)
    return this;
  }
...

А то с Мэйби монадой прибавить ничего не сможете ))
Sign up to leave a comment.

Articles