Разница между "возвратом" и "чистым"
В чем разница между return
и pure
от Control.Applicative
? Кажется, что я могу использовать pure
даже в конце блока do
?
Итак, есть ли ситуация, когда нужно быть предпочтительнее другого (кроме того, что каждый ожидает return
в конце блока do
)?
Ответы
Ответ 1
В GHC 7.8 и ранее Applicative
не был суперклассом Monad
. Возможно даже, что экземпляр Monad
не имеет экземпляра Applicative
. Было, однако, ожидание того, что pure
и return
должны иметь одинаковое поведение для типов, которые являются экземплярами обоих.
В GHC 7.10, из-за Предложения по применению актера-монодара, Applicative
теперь является суперклассом Monad
(class Applicative m => Monad m
), и это теперь правило, что pure
и return
должно быть одинаковым для всех экземпляров Monad
. Фактически, реализация по умолчанию return
теперь pure
, как видно из источника в hackage.
pure
может быть предпочтительнее return
, потому что это не приводит к ограничению Monad
, а только ограничению Applicative
, что делает функцию более общей. return
может быть предпочтительнее pure
в нотации из-за исторического прецедента, но pure
может использоваться точно для того же самого эффекта.
Ответ 2
Прикладная модель была добавлена после Monad
, и исторически класс Monad
не был подклассом Applicative
. Это довольно недавно было изменено в Applicative-Monad-Proposal
, и это означает, что return a
должен быть эквивалентен pure a
для каждого экземпляра Monad
.
Существует предложение , чтобы переместить return
из класса Monad
и сделать его псевдонимом для pure
.
Поэтому при работе с Monad
вы всегда можете использовать pure
вместо return
. Вы не можете пойти другим путем, так как pure
имеет более общий тип, чем return
, так как он возвращает только Applicative
. Например, следующие
wontCheck :: Applicative f => f Int
wontCheck = return 4
не будет вводить проверку, так как return
требует f
как Monad
.