Сообщение Re: Монады от 27.10.2014 15:22
Изменено 27.10.2014 15:54 HrorH
Здравствуйте, AlexRK, Вы писали:
ARK>Или монады это такая сложная концепция, что описать ее доступным языком невозможно в принципе?
Попробую своими словами, синтаксис C# + небольшие добавки для удобства.
Допустим, у нас есть какой-то тип X. И есть какие-то фукции, f1: X->X, f2: X->X.
И мы хотим уметь делать композицию этих функций. Мы определяем оператор <*>, чтобы можно было писать
И еще мы хотим, что для функции Id, которая определена как x=>x , выполнялось
То есть это по сути моноид.
А теперь мы хотим немножко усложнить, и научиться делать композицию фукнций вот такого вида: f1: A->M<B>, f2 : B->M<C>.
Делаем аналогично, добавляем операцию <*>.
Попробуем реализовать <*>
Здесь я сделал вспомогательную функцию bind. У каждой монады ее реализация своя.
Ее тип M<B>->(B->M<C>)->M<C>. Да, это и есть тот самый bind.
А теперь попробуем написать аналог f <*> id = f = id <*> f
Тип функции return: T->M<T>. Слева это будет B->M<B>, а справа A->M<A>.
Если что непонятно или неправильно написал, более подробно и на английском
см Brian Beckman: Don't fear the Monad
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.
И мы хотим уметь делать композицию этих функций. Мы определяем оператор <*>, чтобы можно было писать
И еще мы хотим, что для функции Id, которая определена как x=>x , выполнялось
То есть это по сути моноид.
А теперь мы хотим немножко усложнить, и научиться делать композицию фукнций вот такого вида: f1: A->M<B>, f2 : B->M<C>.
Делаем аналогично, добавляем операцию <*>.
Попробуем реализовать <*> (здесь return — это не функция, а ключевое слово C#)
Здесь я сделал вспомогательную функцию bind. У каждой монады ее реализация своя.
Ее тип M<B>->(B->M<C>)->M<C>. Да, это и есть тот самый bind.
А теперь попробуем написать аналог f <*> id = f = id <*> f
Тип функции return: T->M<T>. Слева это будет B->M<B>, а справа A->M<A>.
Если что непонятно или неправильно написал, более подробно и на английском
см Brian Beckman: Don't fear the Monad
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