Let's start with some definitions: (1)(5)(8)

Covariant Functor — defines the operation commonly known as map or fmap.

map ( A=>B ) => ( C[A]=>C[B] )   or   map C[A] => (A=>B) => C[B]

Monad: — defines the operation commonly known as bind, flatMap or =<<.

flatMap ( A=>C[B] ) => ( C[A]=>C[B] )
insert A => C[A]

Monads also define an identity operation, insert

Applicative Functor — defines the operation commonly known as apply or *.

apply ( C[A=>B] ) => ( C[A]=>C[B] )
insert A => C[A]

Applicative functors also define an identity operation, insert

Exponential Functors — defines the operation commonly known as xmap. Also known as invariant functors.

xmap ( (A => B, B => A) ) => ( F[A] => F[B] )

Contravariant Functor — defines the operation commonly known as contramap.

contramap ( B=>A ) => ( C[A]=>C[B] )

Comonad — defines the operation commonly known as extend, coflatMap or <<=.

coflatMap ( F[A] => B ) => ( F[A] => F[B] )
extract F[A] => A

Comonads also define an identity operation, extract

Implementation details:

Let's assume that we have

class Container[T](val value:T)

// Covariant Functor (1)(2)(3)

def map[A,B] ( rawfunc:A=>B ) = (a:Container[A]) => new Container( rawfunc(a.value) )

or

def map[A,B](a:Container[A]): (A=>B)=>Container[B] = (rawfunc:A=>B) => new Container( rawfunc(a.value) )

or

class Container[A](val value:A) {
  def map[A,B](rawfunc:A=>B) = new Container( rawfunc(this.value) )
}

or

implicit class ContainerWrapper[T](w:Container[T]) {
  def flatMap[R](f:T=>Container[R]) = map(f).value // monad
  def map[R](f:T=>R) = new Container(f(w.value)) // functor
}

or (5)

trait Functor[T[_]] {
  def fmap[A,B](f: A=>B)(ta: T[A]): T[B]
}

// Monad (3)(4)

def flatMap[A,B]( func:A=>Container[B] ) = (a:Container[A]) => func( a.value )

or

def flatMap[A,B](func:A=>Container[B]) = (a:Container[A]) => map(func)(a).value

or

def flatMap[A,B](func:A=>MyBox[B]) = (a:MyBox[A]) => flatten(map(func)(a))
def flatten[B](m:MyBox[MyBox[B]]):MyBox[B] = m.value

or (5)

trait Monad[M[_]] extends Applicative[M] {
  def >>=[A,B](ma:M[A])(f:A=>M[B]):M[B] // or bind
}

// Applicative (3)

def apply[A,B] ( b:Container[A=>B] ) = (a:Container[A]) => new Container(b.value(a.value))

or (5)

trait Applicative[T[_]] extends Functor[T] {
  def pure[A](a:A):T[A] // or identity
  def <*>[A,B](tf:T[A=>B])(ta:T[A]):T[B] // or apply
}

or (7)

val applicative: F[Y => Z] => F[Y] => F[Z] =
  f => a => for {
    ff <- f
    aa <- a
  } yield ff(aa)

fib.zip(fib.tail) can be rewritten as zip <*> tail

// Exponential functor (8)

trait Exponential[F[_]] {
  def xmap[A, B](f: (A => B, B => A)): F[A] => F[B]
}

// Contravariant functor (8)

trait Contravariant[F[_]] {
  def contramap[A, B](f: B => A): F[A] => F[B]
}

// Comonad (8)

trait Comonad[F[_]] {
  def coflatMap[A, B](f: F[A] => B): F[A] => F[B]
  def extract[A]: F[A] => A
}

Concrete use:

Writer monad: (4)

class LogBox[T](val value:T, val mesg:String="") {
    def map[B](f:T=>B) = new LogBox(f(value), mesg)
    def flatMap[B](f:T=>LogBox[B]) = flatten( map(f) )
    def flatten[B](m:LogBox[LogBox[B]]) = new LogBox( m.value.value, m.mesg+m.value.mesg+"\n")
}

References: