По моему опыту, аппликативные функторы хороши по следующим причинам:
Определенные виды структур данных допускают мощные типы композиций, но в действительности не могут быть сделаны монадами.Фактически, большинство абстракций в функционально-реактивном программировании попадают в эту категорию.Хотя технически мы можем сделать, например, Behavior
(он же Signal
) монадой, обычно это невозможно сделать эффективно.Аппликативные функторы позволяют нам создавать мощные композиции, не жертвуя эффективностью (правда, иногда сложнее использовать аппликатив, чем монаду, просто потому, что у вас не так много структуры для работы).
Отсутствие зависимости от данных в аппликативном функторе позволяет вам, например, проследить действие, ища все эффекты, которые оно может произвести, не имея доступных данных.Таким образом, вы можете представить аппликатив «веб-формы», используемый следующим образом:
userData = User <$> field "Name" <*> field "Address"
, и вы можете написать движок, который будет проходить, чтобы найти все используемые поля и отобразить их в форме, а затем, когда вы получитеданные возвращаются снова, чтобы получить построенный User
.Это нельзя сделать ни с помощью простого функтора (потому что он объединяет две формы в одну), ни с монадой, потому что с помощью монады вы можете выразить:
userData = do
name <- field "Name"
address <- field $ name ++ "'s address"
return (User name address)
, который не может быть визуализирован, потому что имя второгополе не может быть известно без ответа от первого.Я почти уверен, что есть библиотека, которая реализует эту идею форм - я несколько раз катал свою собственную для этого и этого проекта.
Еще одна приятная вещь в аппликативных функторах - это то, что они составляют.Точнее говоря, функтор композиции:
newtype Compose f g x = Compose (f (g x))
является аппликативным, когда f
и g
.То же самое нельзя сказать о монадах, которые создают целую историю трансформации монад, которая усложняется некоторыми неприятными способами.Аппликаты очень чистые, и это означает, что вы можете создать структуру нужного вам типа, сосредоточившись на небольших компонуемых компонентах.
Недавно в GHC появилось расширение ApplicativeDo
, которое позволяет вам использоватьdo
нотация с аппликативами, облегчающая некоторые нотационные сложности, если вы не делаете никаких монадических вещей.