// codeart.ru / Вопрос/Ответ / Про монады в функциональных языках Форум

Про монады в функциональных языках rss подписка

Автор: Evgeniy Sergeev

Начну из далека, но очень быстро перейду к сути вопроса. Итак, есть теория категори, которая является чисто абстрактной и если честно скучной штукой. Не поймите меня неправильно, теория категорий вещь полезная, учить ее, безусловно, надо. Но все равно скучно. Как в любой сфере знаний в данном разделе математики есть свои определения, например морфизмы (или их еще по идиотски называют стрелками), функторы (которые по большому счету есть морфизмы для категории катеорий), естественное преобразование, монада и т.д.

Что интересно, никто не ломает копья в попытках объяснить суть каждого из этих терминов в свете функционального программирования. Но вот к монадам народ просто проникся чистой бескорыстной любовью. И попыток объяснить значения монад в функционаэльном программировании стало столь много, что в зоопарке мнений и объяснений потерялась сама суть.

А суть состоит в том, что в программировании всегда хочется что-нибудь отделить от чего-нибудь. Например, очень хочется отделить обработку ошибок и принятие решения о дальнейших вычислениях от непосредственно самих вычислений. Плюс очень хочется иметь красивый код. Вот и решили для выполнения цепочки вычислений использовать красивую и удобную запись.

Т.е. Было так:

write_file(Path, Data, Modes) ->
Modes1 = [binary, write | (Modes -- [binary, write])],
case make_binary(Data) of
Bin when is_binary(Bin) ->
case file:open(Path, Modes1) of
{ok, Hdl} ->
case file:write(Hdl, Bin) of
ok ->
case file:sync(Hdl) of
ok ->
file:close(Hdl);
{error, _} = E ->
file:close(Hdl),
E
end;
{error, _} = E ->
file:close(Hdl),
E
end;
{error, _} = E -> E
end;
{error, _} = E -> E
end.

make_binary(Bin) when is_binary(Bin) ->
Bin;
make_binary(List) ->
try
iolist_to_binary(List)
catch error:Reason ->
{error, Reason}
end.

А стало вот так:

write_file(Path, Data, Modes) ->
Modes1 = [binary, write | (Modes -- [binary, write])],
do([error_m ||
Bin <- make_binary(Data), {ok, Hdl} <- file:open(Path, Modes1), {ok, Result} <- return(do([error_m || ok <- file:write(Hdl, Bin), file:sync(Hdl)])), file:close(Hdl), Result]).

В чем различие между первым и вторым куском кода понять нетрудно. Преимущества и недостатки так же очевидны. Но чтобы програмиисты могли друг друга понимать нужно как-то правильно обозвать данный подход. Поэтому и появляются термины do-нотация и монада error.

И на самом деле совсем неважно почему монаду назвали монадой. Я считаю, что обучение нужно начинать не с попытки объяснить, что есть монада. А с наработки неких шаблонов, т.е. есть код, есть возможность его улучшить. Делаем то и то, называем все это дело монадой.

Рано или поздно человек сам созреет до того, что разберется с типами монад, с причинами по которым был использован термин монада и с прочими вопросами. Но в самом начале пути, нужно тупо принять, что монада - это особая запись цепочки вычислений.

Leave a Reply

« »