Re[3]: Монады
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.14 15:17
Оценка: 6 (1)
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, gandjustas, Вы писали:


G>>Этот паттерн состоит из трех частей — монадного типа M<T> , функции bind и фукнции return.


ARK>Как раз о чем я в первом посте и написал.

А никакого тайного смысла нет, как и во всех других паттернах.

G>>bind и return должны подчинаться трем монадным законам.

ARK>Каким? Они не могут причинить вред программисту, должны ему подчиняться и заботиться о своей корректности?
1) bind(x, y => return y) = x
2) bind(return x, y => f(y)) = f(x)
3) bind(m, y => bind(g(y), x => f(x))) = bind(bind(m, x => f(x)), y => g(y))


G>>Но сам по себе паттерн "монада" был бы не нужен никому, если бы не поддержка в языках.

G>>Формальное определение паттерна позволяет в языки встроить "монадный синтаксис" (aka do-нотация, aka linq). Этот синтаксис позволяет вложенные вызовы bind записывать в линейной форме.

ARK>А можно простой пример на псевдокоде? "Вот так — без монад, а вот так — с монадами, писанины в 3 раза меньше".


Проще всего на примере Maybe монады увидеть
//Ручками
Maybe<int> Add1(Maybe<int> a, Maybe<int> b)
{
   if(!a.HasValue || !b.HasValue) return Maybe.None<int>();
   return Maybe.Return(a.Value+b.Value);
}

//Через bind
Maybe<int> Add2(Maybe<int> a, Maybe<int> b)
{
   return Bind(a, v1 => Bind(b, v2 => Maybe.Return(v1+v2)));
}

//Через монадный синтаксис
Maybe<int> Add3(Maybe<int> a, Maybe<int> b)
{
   return from v1 in a
          from v2 in b
          select v1+v2;
}


Последняя нотация вдвойне крута, ибо позволяет еще where использовать и локальные связывания (let).

Пока писал обратил внимание, что для написания первого варианта даже напрягся, проверяя логическое условие. Второй вариант потребовал усилия мозга, чтобы правильно расставить лямбды и скобки, а третий на автомате написал не задумываясь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.