diff --git a/core/src/main/scala/cats/CoflatMap.scala b/core/src/main/scala/cats/CoflatMap.scala index 4db0e50668..ff26802c13 100644 --- a/core/src/main/scala/cats/CoflatMap.scala +++ b/core/src/main/scala/cats/CoflatMap.scala @@ -3,11 +3,47 @@ package cats import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.CoflatMapLaws. - */ + * `CoflatMap` is the dual of `FlatMap`. + * + * Must obey the laws in cats.laws.CoflatMapLaws + */ @typeclass trait CoflatMap[F[_]] extends Functor[F] { + + /** + * `coflatMap` is the dual of `flatMap` on `FlatMap`. It applies + * a value in a Monadic context to a function that takes a value + * in a context and returns a normal value. + * + * Example: + * {{{ + * scala> import cats.std.option._ + * scala> import cats.Monad + * scala> import cats.CoflatMap + * scala> val fa = Monad[Option].pure(3) + * scala> def f(a: Option[Int]): Int = a match { + * | case Some(x) => 2 * x + * | case None => 0 } + * scala> CoflatMap[Option].coflatMap(fa)(f) + * res0: Option[Int] = Some(6) + * }}} + */ def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B] + /** + * `coflatten` is the dual of `flatten` on `FlatMap`. Whereas flatten removes + * a layer of `F`, coflatten adds a layer of `F` + * + * Example: + * {{{ + * scala> import cats.std.option._ + * scala> import cats.Monad + * scala> import cats.CoflatMap + * scala> val fa = Monad[Option].pure(3) + * fa: Option[Int] = Some(3) + * scala> CoflatMap[Option].coflatten(fa) + * res0: Option[Option[Int]] = Some(Some(3)) + * }}} + */ def coflatten[A](fa: F[A]): F[F[A]] = coflatMap(fa)(fa => fa) } diff --git a/core/src/main/scala/cats/Comonad.scala b/core/src/main/scala/cats/Comonad.scala index b29a17596a..7e8e9c6f88 100644 --- a/core/src/main/scala/cats/Comonad.scala +++ b/core/src/main/scala/cats/Comonad.scala @@ -2,9 +2,29 @@ package cats import simulacrum.typeclass + /** - * Must obey the laws defined in cats.laws.ComonadLaws. - */ + * Comonad + * + * Comonad is the dual of Monad. Whereas Monads allow for the composition of effectful functions, + * Comonads allow for composition of functions that extract the value from their context. + * + * Must obey the laws defined in cats.laws.ComonadLaws. + */ @typeclass trait Comonad[F[_]] extends CoflatMap[F] { + + /** + * `extract` is the dual of `pure` on Monad (via `Applicative`) + * and extracts the value from its context + * + * Example: + * {{{ + * scala> import cats.Id + * scala> import cats.Comonad + * scala> val id: Id[Int] = 3 + * scala> Comonad[Id].extract(id) + * res0: cats.Id[Int] = 3 + * }}} + */ def extract[A](x: F[A]): A }