fmap
не всегда сокращает это. В частности, pure
- это то, что позволяет вам ввести f
(где f
- Applicative
), когда у вас его еще нет. Хорошим примером является
sequence :: Applicative f => [f a] -> f [a]
. Он берет список «действий», производящих значения, и превращает его в действие, создающее список значений. Что происходит, когда в списке нет действий? Единственный вменяемый результат - это действие, которое не дает никаких значений:
sequence [] = pure [] -- no way to express this with an fmap
-- for completeness
sequence ((:) x xs) = (:) <$> x <*> sequence xs
Если у вас не было pure
, вам пришлось бы требовать непустого списка действий. Вы можете определенно заставить его работать, но это все равно, что говорить о сложении без упоминания 0 или умножения без 1 (как говорили другие, потому что Applicative
s моноидальны). Вы будете неоднократно сталкиваться с крайними случаями, которые могут быть легко решены с помощью pure
, но вместо этого должны быть решены странными ограничениями на ваши входы и другие вспомогательные средства.