Аппликативная функция
В функциональном программировании или аппликативный функтор сокращенно аппликатив — это промежуточная структура между функторами и монадами . В теории категорий они называются закрытыми моноидальными функторами . Аппликативные функторы позволяют упорядочивать функториальные вычисления (в отличие от простых функторов), но не позволяют использовать результаты предыдущих вычислений при определении последующих (в отличие от монад). Аппликативные функторы являются программным эквивалентом нестрогих моноидальных функторов с тензорной силой в теории категорий .
Аппликативные функторы были представлены в 2008 году Конором МакБрайдом и Россом Патерсоном в их статье «Аппликативное программирование с эффектами» . [1]
Аппликативные функторы впервые появились как библиотечная функция в Haskell , но с тех пор распространились и на другие языки, включая Idris , Agda , OCaml , Scala и F# . Glasgow Haskell, Idris и F# предлагают языковые функции, предназначенные для упрощения программирования с помощью аппликативных функторов.
В Haskell аппликативные функторы реализованы в Applicative
тип класса.
Хотя в таких языках, как Haskell, монады являются аппликативными функторами, в общих настройках теории категорий это не всегда так — примеры несильных монад можно найти в Math Overflow .
Определение
[ редактировать ]В Haskell аппликатив — это параметризованный тип , который мы рассматриваем как контейнер для данных типа параметра плюс два метода. pure
и <*>
. pure
метод для аппликатива параметризованного типа f
имеет тип
pure :: a -> f a
и его можно рассматривать как привнесение ценностей в аппликативность. <*>
метод для аппликатива типа f
имеет тип
(<*>) :: f (a -> b) -> f a -> f b
и его можно рассматривать как эквивалент применения функции внутри аппликатива. [2]
Альтернативно, вместо предоставления <*>
, можно предоставить функцию под названием liftA2
. Эти две функции могут быть определены друг через друга; поэтому для минимально полного определения необходим только один. [3]
Аппликативы также должны удовлетворять четырем эквационным законам: [3]
- Личность:
pure id <*> v = v
- Состав:
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
- Гомоморфизм:
pure f <*> pure x = pure (f x)
- Развязка:
u <*> pure y = pure ($ y) <*> u
Любой аппликатив является функтором. Чтобы быть явным, учитывая методы pure
и <*>
, fmap
может быть реализован как [3]
fmap g x = pure g <*> x
Обычно используемые обозначения g <$> x
эквивалентно pure g <*> x
.
Примеры
[ редактировать ]В Haskell тип Maybe можно сделать экземпляром класса типов. Applicative
используя следующее определение: [2]
instance Applicative Maybe where
-- pure :: a -> Maybe a
pure a = Just a
-- (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
Nothing <*> _ = Nothing
_ <*> Nothing = Nothing
(Just g) <*> (Just x) = Just (g x)
Как указано в разделе «Определения», pure
поворачивает a
в Maybe a
, и <*>
применяет функцию Maybe к значению Maybe. Использование аппликатива Maybe для типа a
позволяет работать со значениями типа a
при этом ошибка автоматически обрабатывается аппликативным механизмом. Например, чтобы добавить m :: Maybe Int
и n :: Maybe Int
, нужно только написать
(+) <$> m <*> n
В случае отсутствия ошибок добавление m=Just i
и n=Just j
дает Just(i+j)
.
Если любой из m
или n
является Nothing
, то результат будет Nothing
также. Этот пример также демонстрирует, как аппликативы позволяют использовать своего рода обобщенные функции.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Макбрайд, Конор; Патерсон, Росс (1 января 2008 г.). «Апппликативное программирование с эффектами». Журнал функционального программирования . 18 (1): 1–13. CiteSeerX 10.1.1.114.1555 . дои : 10.1017/S0956796807006326 . ISSN 1469-7653 .
- ^ Jump up to: а б Хаттон, Грэм (2016). Программирование на Haskell (2-е изд.). стр. 157–163.
- ^ Jump up to: а б с «Контроль.Аппликативный» .