Здравствуйте, 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).
Пока писал обратил внимание, что для написания первого варианта даже напрягся, проверяя логическое условие. Второй вариант потребовал усилия мозга, чтобы правильно расставить лямбды и скобки, а третий на автомате написал не задумываясь.