Разница между "возвратом" и "чистым"

В чем разница между 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.