Здравствуйте, Klapaucius, Вы писали:
K>Сравните:
liftM2 :: Monad m => (a -> a1 -> b) -> m a -> m a1 -> m b
K>и
template<template<class>class M, typename R, typename T1, typename T2>
function<M<R>(M<T1>,M<T2>)> liftM2(R (*f)(T1, T2))
K>Во втором случае (на псевдоплюсах) нигде не написано, что это за M. Использование >>= никак не отражено в сигнатуре. Вот про это я и говорил "нетипизировано" и "несодержательная сигнатура"
Почему это на "псевдоплюсах"? )))
А насчёт нетипизированности... Обычно под этим подразумевают, что компилятор может пропустить ошибку и она всплывёт только где-нибудь во время исполнения. В данном случае, если в качестве M передать тип не имеющий определённого оператора >>=, то компилятор выдаст соответствующую ошибку — какую ещё типизацию то можно требовать?
И кстати говоря это полностью укладывается в классическую идеология шаблонов C++, работающую на базе SFINAE.
K>Т.е. возвращать из функций вида a -> m b и передавать в другие — это все-таки редко нужно, я правильно понял?
Да, цепочки вида m a->m b->m c возникают весьма редко. И в этих редких случаях монады как раз оправданы (в любых языках).
K>Ну так назовите хоть одну. Что это за "неудобности" такие, которые вынуждают в хаскеле монады использовать, и которых в другом языке нет и использовать монады ничто не вынуждает.
K>Вы раз за разом повторяете, что они есть, но назвать ни одной не можете.
Мы же вроде как это уже обсудили один раз. Это особенности реализации IO/ST в Хаскеле. Правда вы указали, что эти особенности привносят некие плюсы по сравнению с другими языками. Подразумевая, что эти плюсы (которых в других языках в принципе нет) перевешивают все ужасы подобного кода. Однако, моя просьба привести хотя бы один пример, демонстрирующий суть этих плюсов на практике, была полностью проигнорирована...