Witchcraft v0.3.0 Witchcraft.Applicative protocol
Applicative functors provide a method of applying a function contained in a data structure to a value of the same type. This allows you to apply and compose functions to values while avoiding repeated manual wrapping and unwrapping of those values.
Properties
Identity
applying a lifted id to some lifted value v does not change v
apply(v, wrap(&id(&1))) == v
Composition
apply composes normally.
apply((wrap &compose(&1,&2)), (apply(u,(apply(v, w))))) == apply(u,(apply(v, w)))
Homomorphism
applying a wrapped function to a wrapped value is the same as wrapping the
result of the function on that value.
apply(wrap x, wrap f) == wrap f(x))
Interchange
The order does not matter when applying to a wrapped value
and a wrapped function.
apply(wrap y, u) == apply(u, wrap &(lift(y, &1))
Functor
Being an applicative functor, apply behaves as lift on wrapped values
lift(x, f) == apply(x, (wrap f))
Notes
Given that Elixir functons are right-associative, you can write clean looking, but much more ambiguous versions:
wrap(y) |> apply(u) == apply(u, wrap(&lift(y, &1)))
lift(x, f) == apply(x, wrap f)
However, it is strongly recommended to include the parentheses for clarity.
Summary
Functions
Sequentially apply lifted function(s) to lifted data
Lift a pure value into a type provided by some specemin (usually the zeroth or empty value of that type, but not nessesarily)
Types
t :: term
Functions
Specs
apply(any, (... -> any)) :: any
Sequentially apply lifted function(s) to lifted data.