Информация об изменениях

Сообщение Re: Монады от 27.10.2014 15:22

Изменено 27.10.2014 15:54 HrorH

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

ARK>Или монады это такая сложная концепция, что описать ее доступным языком невозможно в принципе?

Попробую своими словами, синтаксис C# + небольшие добавки для удобства.

Допустим, у нас есть какой-то тип X. И есть какие-то фукции, f1: X->X, f2: X->X.
И мы хотим уметь делать композицию этих функций. Мы определяем оператор <*>, чтобы можно было писать
f = f1 <*> f2

И еще мы хотим, что для функции Id, которая определена как x=>x , выполнялось

 f <*> id = f = id <*> f

То есть это по сути моноид.

А теперь мы хотим немножко усложнить, и научиться делать композицию фукнций вот такого вида: f1: A->M<B>, f2 : B->M<C>.
Делаем аналогично, добавляем операцию <*>.

Попробуем реализовать <*>
<*> f1 f2 = 
    a =>  {
            var mb = f1 (a);
            return bind(mb, f2);
          };

Здесь я сделал вспомогательную функцию bind. У каждой монады ее реализация своя.
Ее тип M<B>->(B->M<C>)->M<C>. Да, это и есть тот самый bind.

А теперь попробуем написать аналог f <*> id = f = id <*> f
f <*> return = f = return <*> f .

Тип функции return: T->M<T>. Слева это будет B->M<B>, а справа A->M<A>.

Если что непонятно или неправильно написал, более подробно и на английском
см Brian Beckman: Don't fear the Monad
Здравствуйте, AlexRK, Вы писали:

ARK>Или монады это такая сложная концепция, что описать ее доступным языком невозможно в принципе?

Попробую своими словами, синтаксис C# + небольшие добавки для удобства.

Допустим, у нас есть какой-то тип X. И есть какие-то фукции, f1: X->X, f2: X->X.
И мы хотим уметь делать композицию этих функций. Мы определяем оператор <*>, чтобы можно было писать
f = f1 <*> f2

И еще мы хотим, что для функции Id, которая определена как x=>x , выполнялось

 f <*> id = f = id <*> f

То есть это по сути моноид.

А теперь мы хотим немножко усложнить, и научиться делать композицию фукнций вот такого вида: f1: A->M<B>, f2 : B->M<C>.
Делаем аналогично, добавляем операцию <*>.

Попробуем реализовать <*> (здесь return — это не функция, а ключевое слово C#)
<*> f1 f2 = 
    a =>  {
            var mb = f1 (a);
            return bind(mb, f2);
          };

Здесь я сделал вспомогательную функцию bind. У каждой монады ее реализация своя.
Ее тип M<B>->(B->M<C>)->M<C>. Да, это и есть тот самый bind.

А теперь попробуем написать аналог f <*> id = f = id <*> f
f <*> return = f = return <*> f .

Тип функции return: T->M<T>. Слева это будет B->M<B>, а справа A->M<A>.

Если что непонятно или неправильно написал, более подробно и на английском
см Brian Beckman: Don't fear the Monad