### MonoidK

There’s also `MonoidK`.

``````@typeclass trait MonoidK[F[_]] extends SemigroupK[F] { self =>

/**
* Given a type A, create an "empty" F[A] value.
*/
def empty[A]: F[A]

/**
* Given a type A, create a concrete Monoid[F[A]].
*/
override def algebra[A]: Monoid[F[A]] =
new Monoid[F[A]] {
def empty: F[A] = self.empty
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}

....
}
``````

This adds `empty[A]` function to the contract. The notion of emptiness here is defined in terms of the left and right identity laws with regards to `combineK`. Given that `combine` and `combineK` behave differently, `Monoid[F[A]].empty` and `MonoidK[F].empty[A]` could also be different.

``````import cats._, cats.syntax.all._

Monoid[Option[Int]].empty
// res0: Option[Int] = None

MonoidK[Option].empty[Int]
// res1: Option[Int] = None
``````

In case of `Option[Int]` they happened to be both `None`.

#### MonoidK laws

``````trait MonoidKLaws[F[_]] extends SemigroupKLaws[F] {
override implicit def F: MonoidK[F]

def monoidKLeftIdentity[A](a: F[A]): IsEq[F[A]] =
F.combineK(F.empty, a) <-> a

def monoidKRightIdentity[A](a: F[A]): IsEq[F[A]] =
F.combineK(a, F.empty) <-> a
}
``````