selective

library selective

module Selective

module type Basic

module Make

argument 1S

module Applicative_infix


module type S

module Applicative_infix



include Base.Applicative.Basic
val return : 'a > 'a t
The following identities ought to hold for every Applicative (for some value of =):
 identity:
return Fn.id <*> t = t
 composition:
return Fn.compose <*> tf <*> tg <*> tx = tf <*> (tg <*> tx)
 homomorphism:
return f <*> return x = return (f x)
 interchange:
tf <*> return x = return (fun f > f x) <*> tf
Note: <*> is the infix notation for apply.
The map
argument to Applicative.Make
says how to implement the applicative's map
function. `Define_using_apply
means to define map t ~f = return f <*> t
. `Custom
overrides the default implementation, presumably with something more efficient.
Some other functions returned by Applicative.Make
are defined in terms of map
, so passing in a more efficient map
will improve their efficiency as well.
val select : ( 'a, 'b ) Base.Either.t t > ( 'a > 'b ) t > 'b t
Selective applicative functors. You can think of select
as a selective function application: you apply a function only when given a value First a
. Otherwise, you can skip the function and associted effects and return the b
from Second b
.
Note that it is not a requirement for selective functors to skip unnecessary effects. It may be counterintuitive, but this makes them more useful. Why? Typically, when executing a selective computation, you would want to skip the effects (saving work); but on the other hand, if your goal is to statically analyse a given selective computation and extract the set of all possible effects (without actually executing them), then you do not want to skip any effects, because that defeats the purpose of static analysis.
The type signature of select
is reminiscent of both <*>
and >>=
, and indeed a selective functor is in some sense a composition of an applicative functor and the Either
monad.