# Applicative

A trait for functors that support application, i.e. allow to:

- Make an applicative value out of a normal value (embed it into a default context), e.g. embed
`5`

into`Some(5)`

. - Apply a function-type applicative to a matching argument-type applicative, resulting in an applicative of the function's result type.

The meaning of the application realized by the `ap`

function is defined by the respective instance.
Conceptually this can be understood as applying functions "contained" in the first applicative to arguments
in the second applicative, where the possible quantity of functions/arguments depends on the type `m`

.
For example, an `Option[a -> b]`

can be `None`

, or contain a function of type `a -> b`

, and only in the
latter case a function is applied. A `List[a -> b]`

is an applicative that contains a list of functions,
which are all to be applied to all arguments contained in the arguments list.

A minimal implementation must define `point`

and at least one of `ap`

and `map2`

(if `map2`

is implemented,
`ap`

can be defined based on `map2`

as shown below). If both `ap`

and `map2`

are defined,
they must be equivalent to their default definitions:
`ap(f: m[a -> b \ e], x: m[a]): m[b] \ ef = map2(identity, f, x)`

`map2(f: a -> b -> c \ e, x: m[a], y: m[b]): m[c] \ ef = ap(Functor.map(f, x), y)`

## Signatures

`def ap(f: m[a -> b \ ef], x: m[a]): m[b] \ ef with Applicative[m]`

SourceApply the function-type applicative `f`

to the argument-type applicative `x`

.

`def point(x: a): m[a] with Applicative[m]`

SourcePuts `x`

into a default context.

## Trait Definitions

`def map2(f: t1 -> (t2 -> r \ ef), x1: m[t1], x2: m[t2]): m[r] \ ef with Applicative[m]`

SourceLift a binary function to work on `Applicative`

s.
Instances can define more efficient implementations than the default implementation
(which is `Applicative.ap(Functor.map(f, x1), x2)`

).

`def map3(f: t1 -> (t2 -> (t3 -> r \ ef)), x1: m[t1], x2: m[t2], x3: m[t3]): m[r] \ ef with Applicative[m]`

SourceLift a ternary function to work on `Applicative`

s.
Instances can define more efficient implementations than the default implementation
(which is `Applicative.ap(Applicative.map2(f, x1, x2), x3)`

).

`def map4(f: t1 -> (t2 -> (t3 -> (t4 -> r \ ef))), x1: m[t1], x2: m[t2], x3: m[t3], x4: m[t4]): m[r] \ ef with Applicative[m]`

SourceLift a 4-ary function to work on `Applicative`

s.
Instances can define more efficient implementations than the default implementation
(which is `Applicative.ap(Applicative.map3(f, x1, x2, x3), x4)`

).

`def map5(f: t1 -> (t2 -> (t3 -> (t4 -> (t5 -> r \ ef)))), x1: m[t1], x2: m[t2], x3: m[t3], x4: m[t4], x5: m[t5]): m[r] \ ef with Applicative[m]`

SourceLift a 5-ary function to work on `Applicative`

s.
Instances can define more efficient implementations than the default implementation
(which is `Applicative.ap(Applicative.map3(f, x1, x2, x3), x4)`

).

## Module Definitions

`def *>(ma: m[a], mb: m[b]): m[b] with Applicative[m]`

Source`*>`

is an operator alias for `productRight`

.

`def <*(ma: m[a], mb: m[b]): m[a] with Applicative[m]`

Source`<*`

is an operator alias for `productLeft`

.

`def <**>(ma: m[a], mf: m[a -> b \ ef]): m[b] \ ef with Applicative[m]`

Source`<**>`

is a variant of the operator `<*>`

with its arguments flipped.

The order of evaluation is `ma`

then `mf`

.

`def <*>(mf: m[a -> b \ ef], ma: m[a]): m[b] \ ef with Applicative[m]`

Source`<*>`

is an operator alias for `ap`

.

`def product(fa: m[a], fb: m[b]): m[(a, b)] with Applicative[m]`

SourceChain two applicative actions, returns the product of their results.

`def product3(x1: m[t1], x2: m[t2], x3: m[t3]): m[(t1, t2, t3)] with Applicative[m]`

SourceChain three applicative actions, return the 3-tuple of their results.

`def product4(x1: m[t1], x2: m[t2], x3: m[t3], x4: m[t4]): m[(t1, t2, t3, t4)] with Applicative[m]`

SourceChain four applicative actions, return the 4-tuple of their results.

`def product5(x1: m[t1], x2: m[t2], x3: m[t3], x4: m[t4], x5: m[t5]): m[(t1, t2, t3, t4, t5)] with Applicative[m]`

SourceChain five applicative actions, return the 5-tuple of their results.

`def productLeft(fa: m[a], fb: m[b]): m[a] with Applicative[m]`

SourceChain two applicative actions, return only the result of the first.

`def productRight(fa: m[a], fb: m[b]): m[b] with Applicative[m]`

SourceChain two applicative actions, return only the result of the second.