I know that Monad
can be expressed in Scala as follows:
trait Monad[F[_]] {
def flatMap[A, B](f: A => F[B]): F[A] => F[B]
}
Functor is for lifting computations to a category.
trait Functor[C[_]] {
def map[A, B](f : A => B): C[A] => C[B]
}
And it works perfectly for a function of one variable.
val f = (x : Int) => x + 1
But for a function of 2 and more, after lifting to a category, we have the following signature:
val g = (x: Int) => (y: Int) => x + y
Option(5) map g // Option[Int => Int]
And it is the signature of a applicative functor. And to apply the following value to a function g
— an aplicative functor is needed.
trait Applicative[F[_]] {
def apply[A, B](f: F[A => B]): F[A] => F[B]
}
And finally:
(Applicative[Option] apply (Functor[Option] map g)(Option(5)))(Option(10))
Applicative functor is a functor for applying a special value (value in category) to a lifted function.