Аппликативные функторы хорошо известны и любимы среди хаскеллеров за их способность применять функции в эффективном контексте.
В терминах теории категорий можно показать, что методы Applicative
:
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
эквивалентны наличию Functor f
с операциями:
unit :: f ()
(**) :: (f a, f b) -> f (a,b)
идея состоит в том, что для записи pure
вы просто заменяете ()
в unit
заданным значением, а для записи (<*>)
вы сжимаете функцию и аргумент в кортеж, а затем сопоставляете с ним подходящую функцию приложения.
Более того, это соответствие превращает Applicative
законы в естественные моноидальные законы относительно unit
и (**)
, так что на самом деле аппликативный функтор - это именно то, что теоретик категорий назвал бы слабым моноидальным функтором (слабым, потому что (**)
- просто естественное преобразование, а не изоморфизм ).
Ладно, отлично. Это хорошо известно. Но это только одно семейство слабых моноидальных функторов - тех, которые соблюдают моноидальную структуру продукта. Слабый моноидальный функтор включает в себя два варианта моноидальной структуры в источнике и назначении: вот что вы получите, если превратите произведение в сумму:
class PtS f where
unit :: f Void
(**) :: f a -> f b -> f (Either a b)
-- some example instances
instance PtS Maybe where
unit = Nothing
Nothing ** Nothing = Nothing
Just a ** Nothing = Just (Left a)
Nothing ** Just b = Just (Right b)
Just a ** Just b = Just (Left a) -- ick, but it does satisfy the laws
instance PtS [] where
unit = []
xs ** ys = map Left xs ++ map Right ys
Похоже, что преобразование суммы в другие моноидальные структуры становится менее интересным из-за того, что unit :: Void -> f Void
определяется однозначно, так что вы действительно имеете дело с большей полугруппой. Но все равно:
- Являются ли другие нестрогие моноидальные функторы изученными или полезными?
- Есть ли для них отличная альтернативная презентация, такая как
Applicative
?
Void
в типеPtS.unit
, разве вы не имеете в виду Пустой, поскольку это должна быть единица дляEither
? - person Dominique Devriese   schedule 27.04.2014Void
представлять пустой тип. Я был сбит с толку, потому что имя void в C-подобных языках соответствует типу модуля, который вы пишете как()
. - person Dominique Devriese   schedule 27.04.2014