In functional programming, an applicative functor, or an applicative for short, is an intermediate structure between functors and monads. Applicative functors allow for functorial computations to be sequenced (unlike plain functors), but don't allow using results from prior computations in the definition of subsequent ones (unlike monads). Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory.
Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.
Applicative functors first appeared as a library feature in Haskell, but have since spread to other languages as well, including Idris, Agda, OCaml, Scala and F#. Glasgow Haskell, Idris, and F# offer language features designed to ease programming with applicative functors.
In Haskell, applicative functors are implemented in the
Applicative type class.
In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods
<*>. Consider a parametrized type
f a. The
pure method for an applicative of type
f has type
pure :: a -> f a
and can be thought of as bringing values into the applicative. The
<*> method for an applicative of type
f has type
(<*>) :: f (a -> b) -> f a -> f b
and can be thought of as the equivalent of function application inside the applicative.
Alternatively, instead of providing
<*>, one may provide a function called
liftA2. These two functions may be defined in terms of each other; therefore only one is needed for a minimally complete definition.
Applicatives are also required to satisfy four equational laws:
pure id <*> v = v
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
pure f <*> pure x = pure (f x)
u <*> pure y = pure ($ y) <*> u
Every applicative is a functor. To be explicit, given the methods
fmap can be implemented as
fmap g x = pure g <*> x
The commonly-used notation
g <$> x is equivalent to
pure g <*> x.
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)
As stated in the Definition section,
pure turns an
a into a
Maybe a, and
<*> applies a Maybe function to a Maybe value. Using the Maybe applicative for type
a allows one to operate on values of type
a with the error being handled automatically by the applicative machinery. For example, to add
m :: Maybe Int and
n :: Maybe Int, one needs only write
(+) <$> m <*> n
For the non-error case, adding
m=Just i and
n=Just j gives
If either of
Nothing, then the result will be
Nothing also. This example also demonstrates how applicatives allow a sort of generalized function application.
- Description of the Applicative typeclass in the Haskell docs
- Definition of the Applicative typeclass in the Glasgow Haskell Prelude