3.2.1 Applicative Functor applicative 3.2.1.1 Members pure <*> lift  A2 *> <* 3.2.1.2 Helpers <**> <*>~ <**>~ 3.2.2 Functor functor 3.2.2.1 Members fmap <\$ 3.2.2.2 Helpers <\$> <\$>~ 3.2.3 Monad monad 3.2.3.1 Members >>= >>M return fail 3.2.3.2 Helpers join =<< 3.2.3.3 Do-Notations do do~ 3.2.4 Monoid monoid 3.2.4.1 Members mempty mappend mconcat 3.2.5 Semigroup semigroup 3.2.5.1 Members <> sconcat stimes 3.2.5.2 Helpers stimes-default
7.9

#### 3.2The Base Classes

##### 3.2.1Applicative Functor

 (require algebraic/control/applicative) package: algebraic

A functor with application, providing operations to

• embed pure expressions (pure), and

• sequence computations and combine their results (<*> and liftA2).

 class
A minimal complete definition must include implementations of pure and of either <*> or liftA2. If it defines both, then they must behave the same as their default definitions:

Further, any definition must satisfy the following:

identity

(<*> (pure id) v) = v

composition

(<*> (<*> (<*> (pure ..) u) v) w) = (<*> u (<*> v w))

homomorphism

(<*> (pure f) (pure x)) = (pure (f x))

interchange

(<*> u (pure y)) = (<*> (pure (>> \$ y)) u)

The other members have the following default definitions, which may be overridden with equivalent specialized implementations:

As a consequence of these laws, the functor instance for f will satisfy

It may be useful to note that supposing, for all x and y,

(>> p (q x y)) = (.. (>> f x) (>> g y))

it follows from the above that

(>> liftA2 p (liftA2 q u v)) = (.. (>> liftA2 f u) (>> liftA2 g v))

If f is also a Monad, it should satisfy

(which implies that pure and <*> satisfy the applicative functor laws).

##### 3.2.1.1Members

Minimal instance: pure, (<*> or liftA2)

 class member
Lift a value.

 class member
Sequential application.

 procedure(liftA2 f a b) → applicative f : procedure? a : applicative b : applicative
Lift a binary function to actions.

Some functors support an implementation of liftA2 that is more efficient than the default one. In particular, if fmap is an expensive operation, it is likely better to use liftA2 than to fmap over the structure and then use <*>.

 procedure(*> a b) → applicative a : applicative b : applicative
Sequence actions, discarding the value of the first argument.

This is essentially the same as (>> liftA2 (flip const)), but if the functor instance has an optimized <\$, it may be better to use that instead.

 procedure(<* a b) → applicative a : applicative b : applicative
Sequence ations, discarding the value of the second argument.

##### 3.2.1.2Helpers

 procedure(<**> a f b) → applicative a : applicative f : applicative b : applicative
A variant of <*> with the first two arguments reversed.

 procedure(<*>~ f a) → applicative f : applicative a : applicative
A lazay variant of <*>.

Eager applicative chains get noisy as they grow because Racket functions must be curried explicitly.

Example:
 > (with-instance box-applicative (<*> (pure +) (pure 1)) (<*> (<*> (pure (>>* +)) (pure 1)) (pure 2)) (<*> (<*> (<*> (pure (>>* (>>* +))) (pure 1)) (pure 2)) (pure 3)))

'#&6

The function (in this case, +) must be wrapped in one >>* for each applicative argument or <*> will fail.

This variant wraps the function with >>*. Unless lazy semantics are desired, make the final operator in the chain eager (e.g., <*>) to evaluate the whole chain by force.

Example:
 > (with-instance box-applicative (<*> (pure +) (pure 1)) (<*> (<*>~ (pure +) (pure 1)) (pure 2)) (<*> (<*>~ (<*>~ (pure +) (pure 1)) (pure 2)) (pure 3)))

'#&6

 procedure(<**>~ a f b) → applicative a : applicative f : applicative b : applicative
A lazay variant of <**>.

##### 3.2.2Functor

 (require algebraic/data/functor) package: algebraic

The functor class is used for types that can be mapped over.

 class
Instances of functor should satisfy the following laws:

##### 3.2.2.1Members

Minimal instance: fmap

 procedure(fmap f a) → functor f : procedure? a : functor
Maps a function over a functor.

 procedure(<\$ a b) → any a : any/c b : functor
Replace all locations in the input with the same value. The default definition is (λ (a f-b) (fmap (const a) f-b)), but this may be overridden with a more efficient version.

##### 3.2.2.2Helpers

 procedure(<\$> f a) → functor f : procedure? a : functor
A synonym for fmap.

The name of this operator is an allusion to \$. Whereas \$ is function application, <\$> is function application lifted over a functor.

Examples:

Convert from a Maybe Int to a Maybe String using ~a:

 > (with-instance maybe-functor (<\$> ~a Nothing)) Nothing > (with-instance maybe-functor (<\$> ~a (Just 3))) (Just "3")

Double each element of a list:

 > (with-instance list-functor (<\$> (>> * 2) '(1 2 3))) '(2 4 6)

 procedure(<\$>~ f a) → functor f : procedure? a : functor
A lazy variant of <\$>.

Basic operations on monads, and a generic do-notation.

 class
Instances of monad should satisfy the following laws:

Monads and Applicatives should relate as follows:

The above laws imply:

and that pure and <*> satisfy the applicative functor laws.

##### 3.2.3.1Members

Minimal instance: >>=

Sequentially compose two actions, passing any value produced by the first as an argument to the second.

Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages.

 procedure(return a ...) → monad a : any/c
Inject values into the monadic type.

 procedure(fail msg) → monad msg : string?
Fail with a message. This operation is not part of the mathematical definition of a monad.

##### 3.2.3.2Helpers

The conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.

Same as >>=, but with the arguments interchanged.

##### 3.2.3.3Do-Notations

 syntax(do do-expr ... expr)

syntax

(do~ do-expr ... expr)

 do-expr = formals <- monad-expr | let id expr | let-values formals expr | monad-expr
Eager (do) and lazy (do~) notations for monadic composition.

do composes a seies of do-exprs with a final expr to determine its result.

do~ is similar, except it expects each do-expr to be warpped in a thunk, and it produces a thunk.

A do-expr has one of the following forms:

Examples:
 > (with-instance list-monad (do (x) <- '(1 2 3 4) (return (add1 x))))

'(2 3 4 5)

 let id expr

Evaluates the expr and binds the result to id.

Example:

 > (with-instance truthy-monad ((do~ let `(a . ,b) '(a 1 2 3) (return b))))

'(1 2 3)

 let-values formals expr

Evaluates the expr and binds the result according to formals.

Example:

Examples:
 > (with-instance box-monad (do #&1 (return 2))) '#&2

Examples:

##### 3.2.4Monoid

 (require algebraic/control/monoid) package: algebraic

The class of monoids (types with an associative binary operation that has an identity).

 classmonoid
Instances should satisfy the following laws:

• (<> x mempty) = x

• (<> mempty x) = x

• (<> x (<> y z)) = (<> (<> x y) z) (Semigroup law)

• mconcat = (foldr <> mempty)

The method names refer to the monoid of lists under concatenation, but there are many other instances.

Some types can be viewed as a monoid in more than one way, e.g. both addition and multiplication on numbers.

##### 3.2.4.1Members

 valuemempty : any/c
Identity of mappend.

 procedure(mappend a b) → any a : any/c b : any/c
An associative operation.

NOTE: This method is redundant and has the default implementation mappend = <>.

 procedure(mconcat as) → any as : list?
Fold a list using the monoid.

For most types, the default definition for mconcat will be used, but the function is included in the class definition so that an optimized version can be provided for specific types.

##### 3.2.5Semigroup

 (require algebraic/data/semigroup) package: algebraic

The class of semigroups (types with an associative binary operation).

 class
Instances should satisfy the associativity law:

##### 3.2.5.1Members

 procedure(<> a b) → any a : any/c b : any/c
An associative operation.

 procedure(sconcat as) → any as : (non-empty-listof any/c)
Reduce a non-empty list with <>.

The default definition should be sufficient, but this can be overridden for efficiency.

 procedure(stimes n a) → any n : exact-positive-integer? a : any/c
Repeat a value n times.

Given that this works on a semigroup it is allowed to fail if you request 0 or fewer repetitions, and the default definition wll do so.

##### 3.2.5.2Helpers

 procedure(stimes-default b a) → any b : exact-positive-integer? a : Semigroup
The default implementation of stimes.