39 lines
1.4 KiB

package green.thisfieldwas.embracingnondeterminism.data
/** Functors are structures that define a `map()` operation that allows for
* functions to be applied to them independent of specific knowledge about the
* state of their cases. What this means is that for a Functor in the desired
* case, the function applied via `map()` will be applied to the present
* instances of the term contained within the Functor. If the Functor is in the
* undesired case, then the function will not apply and the undesired case will
* propagate instead.
* @tparam F
* The type of the structure.
trait Functor[F[_]] {
/** Given a structure `F[A]` and function `f: A => B`, if the structure is in
* the desired case, then apply the function such that `F[A] => F[B]`. If the
* structure `F[A]` is in the undesired case, then propagate the undesired
* case as `F[B]`.
* @param fa
* The instance of the structure to apply the function to.
* @param f
* The function to apply, if the structure is in the desired case.
* @tparam A
* The type of instances contained within the structure.
* @tparam B
* The type to map the instances into.
* @return
* The resulting structure.
def map[A, B](fa: F[A])(f: A => B): F[B]
object Functor {
def apply[F[_]: Functor]: Functor[F] = implicitly[Functor[F]]