Skip to content

Commit

Permalink
Add examples to Functor
Browse files Browse the repository at this point in the history
  • Loading branch information
YuvalItzchakov committed Sep 10, 2018
1 parent 92236f8 commit ddb27a0
Showing 1 changed file with 87 additions and 18 deletions.
105 changes: 87 additions & 18 deletions core/src/main/scala/cats/Functor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,28 @@ import simulacrum.typeclass
*
* Must obey the laws defined in cats.laws.FunctorLaws.
*/
@typeclass trait Functor[F[_]] extends Invariant[F] { self =>
@typeclass trait Functor[F[_]] extends Invariant[F] {
self =>
def map[A, B](fa: F[A])(f: A => B): F[B]

override def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] = map(fa)(f)

// derived methods

/**
* Alias for [[map]], since [[map]] can't be injected as syntax if
* the implementing type already had a built-in `.map` method.
*
* Example:
* {{{
* scala> import cats.implicits._
*
* scala> val m: Map[Int, String] = Map(1 -> "hi", 2 -> "there", 3 -> "you")
*
* scala> m.fmap(_ ++ "!")
* res0: Map[Int,String] = Map(1 -> hi!, 2 -> there!, 3 -> you!)
* }}}
*/
* Alias for [[map]], since [[map]] can't be injected as syntax if
* the implementing type already had a built-in `.map` method.
*
* Example:
* {{{
* scala> import cats.implicits._
*
* scala> val m: Map[Int, String] = Map(1 -> "hi", 2 -> "there", 3 -> "you")
*
* scala> m.fmap(_ ++ "!")
* res0: Map[Int,String] = Map(1 -> hi!, 2 -> there!, 3 -> you!)
* }}}
*/
final def fmap[A, B](fa: F[A])(f: A => B): F[B] = map(fa)(f)

/**
Expand All @@ -42,38 +43,106 @@ import simulacrum.typeclass
* cast is often much more performant.
* See [[https://github.com/typelevel/cats/issues/1080#issuecomment-225892635 this example]]
* of `widen` creating a `ClassCastException`.
*
* Example:
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForOption
*
* scala> val s = Some(42)
* scala> Functor[Option].widen(s)
* res0: Option[Int] = Some(42)
* }}}
*/
def widen[A, B >: A](fa: F[A]): F[B] = fa.asInstanceOf[F[B]]

/**
* Lift a function f to operate on Functors
*
* Example:
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForOption
*
* scala> val o = Option(42)
* scala> Functor[Option].lift((x: Int) => x + 10)(o)
* res0: Option[Int] = Some(52)
* }}}
*/
def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f)

/**
* Empty the fa of the values, preserving the structure
*
* Example:
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForList
*
* scala> Functor[List].void(List(1,2,3))
* res0: List[Unit] = List((), (), ())
* }}}
*/
def void[A](fa: F[A]): F[Unit] = as(fa, ())

/**
* Tuple the values in fa with the result of applying a function
* with the value
*
* Example:
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForOption
*
* scala> Functor[Option].fproduct(Option(42))(_.toString)
* res0: Option[(Int, String)] = Some((42,42))
* }}}
*/
def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)] = map(fa)(a => a -> f(a))

/**
* Replaces the `A` value in `F[A]` with the supplied value.
*
* Example:
*
* {{{
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForList
*
* scala> Functor[List].as(List(1,2,3), "hello")
* res0: List[String] = List(hello, hello, hello)
* }}}
*/
def as[A, B](fa: F[A], b: B): F[B] = map(fa)(_ => b)

/**
* Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the left.
*/
* Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the left.
*
* Example:
* {{{
* scala> import scala.collection.immutable.Queue
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForQueue
*
* scala> Functor[Queue].tupleLeft(Queue("hello", "world"), 42)
* res0: scala.collection.immutable.Queue[(Int, String)] = Queue((42,hello), (42,world))
* }}}
*/
def tupleLeft[A, B](fa: F[A], b: B): F[(B, A)] = map(fa)(a => (b, a))

/**
* Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the right.
*/
* Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the right.
*
* Example:
* {{{
* scala> import scala.collection.immutable.Queue
* scala> import cats.Functor
* scala> import cats.implicits.catsStdInstancesForQueue
*
* scala> Functor[Queue].tupleRight(Queue("hello", "world"), 42)
* res0: scala.collection.immutable.Queue[(String, Int)] = Queue((hello,42), (world,42))
* }}}
*/
def tupleRight[A, B](fa: F[A], b: B): F[(A, B)] = map(fa)(a => (a, b))

def compose[G[_]: Functor]: Functor[λ[α => F[G[α]]]] =
Expand Down

0 comments on commit ddb27a0

Please sign in to comment.