Комментарии 23
Ваше описание bind больше похоже на fmap: (a -> b) -> m a -> m b
+1
А вы не путаете мунады с монадами случайно? Теория котегорий появилась около двух часов назад. Аппарат ещё не разработан, школа отсутствует. Даже статьи на википедии ещё нет.
+9
Справедливо.
0
НЛО прилетело и опубликовало эту надпись здесь
На самом деле в динамическом языке существует только один тип, соответственно в категории, где типы языка — объекты, а функции — стрелки, есть только один объект, со стрелками из себя в себя (группоид?), поэтому bbind :: (any -> any) -> any -> any. И bbind может быть как fmap, так и bind. Для нормальной работы list-монады fmap уже будет недостаточно для описания.
0
а теперь читаем статью и понимаем что написано не правильно habrahabr.ru/post/183150/
0
Зато гораздо понятнее
+1
Значит цель достигнута. Дело в том, что абстрактный программист с ООП бэкграундом не может с первого раза понять что такое монады и зачем они нужны. Ему придётся прочитать википедию, десятки введений, и, скорее всего, поломать глаза о примеры кода на Haskell. Эта статья претендует на место одного из десятка введений, которые программист в любом случае будет читать.
+2
Ну так поясните что именно:) Я перечитал десятки статей про монады, и после этой статьи наконец-то понял. А тут вы — неправильно…
+2
В статье нет монад. Если автор напишет что-то вроде
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. А так сплошные функторы с жестко заданной трубой преобразований, а монады позволяют комбинировать результаты разных функций (имитировать присваивание), чем получаются мощнее.
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. А так сплошные функторы с жестко заданной трубой преобразований, а монады позволяют комбинировать результаты разных функций (имитировать присваивание), чем получаются мощнее.
0
Да не хранит в себе монада ничего такого, о чем вы. Почитайте, во что разворачивается do notation, но я сразу скажу — это всего лишь цепочка лямбд, связываемых bind-ами.
Да, это не то, что написал автор, но ваш код еще дальше от истины, я бы сказал.
Да, это не то, что написал автор, но ваш код еще дальше от истины, я бы сказал.
0
Автор в этом плане гениально решил обойтись мунадами, чтобы буквоеды проходили мимо. Расшифрую, что у меня написано. Bind умеет связать результат вычисления с некоторой мнемоникой, которая является именем параметра вложенной функции.
r :: [Integer]
r = do x {- [1,2,3]
y {- [4,5,6]
return (x+y)
{ вместо знака больше, парсер тут крутой.
Как у автора привязать одно значение к «x», другое — к «y», чтобы использовать в третьей функции? Именно используя точки, а не do-нотацию со вложенными лямбдами?
r :: [Integer]
r = do x {- [1,2,3]
y {- [4,5,6]
return (x+y)
{ вместо знака больше, парсер тут крутой.
Как у автора привязать одно значение к «x», другое — к «y», чтобы использовать в третьей функции? Именно используя точки, а не do-нотацию со вложенными лямбдами?
0
Уже непонятно… Я понимаю что вы понимаете, но к сожалению слишком сжатое изложение:(
0
На самом деле эти мунады есть монады. Но… не честным путём они ими являются. А вот почему:
Для того, чтобы понять, чем мунады не совсем монады надо посмотреть на подпись:
или в нотации Хаскеля
Как видим, bbind на самом деле — функтор.
Монадами мунады стали бы, если можно было написать:
Кстати, легко видно как исправить положение — нам надо добавить по строчке в функцию bbind:
И вот тут превратятся наши гадкие утята — мунады в настоящие монады!
Однако, мунады неотличимы от монад из-за одной хитрости, которые мы соблюдали: все конструкторы должны быть this.value = value;
Пы.Сы. ну и всегда используется в конце runMonad то бишь, M.value
Для того, чтобы понять, чем мунады не совсем монады надо посмотреть на подпись:
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
+1
Официально это набор лучших практик, которыми следует руководствоваться при решении «типичных задач». Неофициально — просто набор костылей для языков, в которых нет встроенных средств для решения типичных проблем.
Золотые слова!
Но как они к м*надам относятся?
0
А чем в данной статье отличается Context от IdentityMoonad?
Несколько раз пролистал, думал, может какой-то подвох от автора. :)
Несколько раз пролистал, думал, может какой-то подвох от автора. :)
+1
Ничем. В данном случае переименование позволяет показать, что монада в вырожденном случае — это способ сделать method chaining (builder, fluent interface) с передачей контекста (промежуточного значения).
+3
Как я понял, контекст это общая «база» для всех монад — обертка, в которой хранятся собственно данные. Этот шаг необходим для понимания.
То что в данном примере он ничем не отличается, не столь важно…
То что в данном примере он ничем не отличается, не столь важно…
+1
Имхо на википедии доступнее написано.
0
Я так понимаю, с Мэйби монадой небольшая ошибочка вышла:
А то с Мэйби монадой прибавить ничего не сможете ))
MaybeMoonad.prototype.bbind = function(f) {
if(this.value == null) { // было (!this.value)
return this;
}
...
А то с Мэйби монадой прибавить ничего не сможете ))
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Что-то издали похожее на монады