Начинаю тему и приглашаю в нее тех, кто лучше меня в этом разбирается
Для каких именно практических нужд пригодны монады? и что называется монадой в языках, отличных от Хаскеля?
Как-то более или менее понятно, что конкретно в lazy eval Хаскеле нет возможности гарантировать порядок исполнения, иначе чем через f(g(x))
И как-то более или менее понятно, что конкретно монада IO и сделана для того, чтобы после разворачивания bindов получить именно f(g(x)) с гарантией порядка, что очевидно нужна вводу-выводу.
Более или менее понятно, что такое Maybe и зачем оно.
Более или менее понятно, что на монадах можно сделать промис из JS, для этого bind в некоторых случаях должен не звать свою лямбду, а запихивать ее в новый объект, откуда она позовется когда-то потом. Как-то так.
Не очень понятно, для чего еще годится этот механизм.
Попробую выразить свое понимание, что такое монада в Хаскеле вообще:
— Monad T есть обертка вокруг значения T
— при этом обертка динамическая, т.е. "внутренность" может и не лежать всегда в памяти, а может строиться при обращении
— >>=, он же bind, извлекает из монады внутренность и отдает ее туда (в ту лямбду), куда просили. Т.е. "разворачивает".
— при этом монадная лямбда обязана вернуть "завернутую" монаду. Для этого есть return, который по внутренности строит монаду (в простейшем случае кладет ее внутрь новой монады). Т.е. "оборачивает".
— при написании байндов и возвратов для своих монад нужно соблюдать тождества вида "Завернуть(Развернуть(M)) = M".
Получается старый добрый декоратор
который можно реализовать в обычных ОО языках наследованием с перекрытием пабликов. Единственное: при этом объекты будут "по ссылке", а монада позволяет "по значению".
Я прав? а в других языках как?
При этом есть еще такой хитрый трюк: список есть монада, и bind у него — итерация по списку. Это как-то выглядит немного ни к селу, ни к городу.