Как стать автором
Обновить

Комментарии 20

Это же перевод, кмк, потому как я уже читал почти слово в слово такую же статью где-то.
Вы могли еще читать здесь же, месяц назад. В прошлой версии в ней содержалась ссылка на сайт который нельзя называть, поэтому меня забанили. Эта версия уже без ссылки.
Точно:) Спасибо, классная статья
НЛО прилетело и опубликовало эту надпись здесь
1. МонадА по сути состоит из трех частей.

2.… ну а мы можно вспомнить что выражение…
Если честно, я бы вообще не вспоминал про монады в данном случае.

Проще было бы показать CPS на примерах, потом заметить, что одна операция (композиция функций в cps) повторяется очень часто и выделить ее в функцию (которая в Cont называется bind).

Радует, что широкие массы потихоньку просвещаются. :)

PS: кстати, может быть. кого-нибудь заинтересует Arrowlets, там тоже скрывается plumbing (в неместном жаргоне можно сказать «абстрагируется поток управления»), только немного по-другому
перевод просто T________________T
«Тогда монаду можно представить в виде такой делегаты.» :D
Что не так?
Как монаду можно представить в виде «делегаты»? Делегат — это просто функция по сути :)
newtype Cont r a = Cont { runCont :: (a -> r) -> r }
В чем вам видеться разница runCont и просто функции?
То, что вы привели — хаскельное определения record'а, с полем типа ((a -> r) -> r), для получения которого создаётся функция-акцессор ``runCont`` с сигнатурой (Cont r a -> ((a -> r) -> r)).

Исходная фраза такова: «Тогда монаду можно представить в виде такой делегаты». Вы меня извините, но это звучит как полный бред. Не «монаду» можно представить в виде «делегаты», а тип вычисления в монаде Cont можно представить в виде типа делегата .NET.
То есть, выражение
монаду Cont можно представить в виде newtype Cont r a = Cont { runCont :: (a -> r) -> r }
некорректное?
Некорректное. Монада — это _тип_вычисления_ (Cont<T>, IEnumerable<T> и т.п.) и две функции: возврата тривиального вычисления (return) и композиции вычислений (bind). То есть монада — это тройка из одного типа и двух функции.

А вот newtype Cont r a = Cont { runCont :: (a -> r) -> r } — это _тип_монадического_вычисления_, часть этой тройки. Это нельзя называть самой «монадой».

IEnumerable<T> — это не монада, это опять же тип вычисления внутри монады Linq to Objects, тип монадического вычисления.
Теперь я понял о чем вы, да это было бы более корректно, но я в начале сказал что она состоит их трех частей, поэтому думаю из контекста должно быть понятно о чем речь.
Почему-то мне выражение
GetPage("http://habrahabr.ru", 
    x => Translate(x, 
        y => Display(y)));


как-то понятней чем
var result =
	from x in GetPage("www.example.com").ToCont()
	from y in Translate(x).ToCont()
	from z in Analyse(y).ToCont()
	select z;
result(Display);


но может это просто слегка другой способ записи…

Хотя, как мне кажется, где-то был тоже красивый вариант с помощью хелпер-класса «AndThen». Там выходило что-то вроде:
Async.Do(GetPage('...')).AndThen(Tranlsate).AndThen(Analyze).AndThen(Display);

… или это просто подумалось что это реально можно реализовать…
*запускаю студию и засучиваю рукава* :)
а скажите пожалуйста, в коде вида a => a(...) используется анонимная рекурсия?
К примеру:
public static Cont<T> ToCont<T>(this Task<T> task) {
	return k => task.ContinueWith(task => k(task.Result));
}


Статья понравилась, но вот такие моменты не понял.
Нет. k — это просто некая функция колбек, протаскиваемая через выражения.
Например
var task = Task<int>.Factory.StartNew(() => 10);
var cont = task.ToCont();
Action<int> k = x => Display(x);
cont(k);
//Тут нет никакой рекурсии.
k => task.ContinueWith(task => k(task.Result));// k == Display
//->
task.ContinueWith(task => Display(task.Result))

разобрался. в том случае это просто аргумент возвращаемой лямбды.
не знаю я .NET'а =)
Как-то у меня с монадой Maybe сложилось по-другому, а именно так. Основное с чем я не согласен — это с созданием своего типа а-ля option<'t>, т.к. вместо него можно использовать null.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории