Type classes, implicits, monads, higher-kinded types.
To start with:
- Semigroup ->
combine(x: A, y: A): A
associative - Monoid extends Semigroup ->
zero: A
means(combine(x, zero) == combine(zero, x) == x)
(zero can be call empty, id)
And/Then:
- Functor defines map ->
map[A, B](fa: F[A])(f: A => B): F[B]
- Applicative extends Functor with ap and pure
pure[A](a: A): F[A]
ap[A,B](ff: F[A => B])(fa: F[A]): F[B]
- Monad extends Applicative with flatten, hence flatMap ->
flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
Monads (flatMap) give function composition for effectul functions A => F[B], B => F[C]
. Obviously, the effect F
has to be the same