Skip to content

Instantly share code, notes, and snippets.

@fancellu
Created April 26, 2020 12:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fancellu/c8c0e9d42752eb92c60b3bfc2d9209a8 to your computer and use it in GitHub Desktop.
Save fancellu/c8c0e9d42752eb92c60b3bfc2d9209a8 to your computer and use it in GitHub Desktop.
Simple Scala Functor example, no cats
package example
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f)
}
object Functor {
def apply[F[_] : Functor]: Functor[F] = implicitly[Functor[F]]
}
object FunctorApp extends App {
def mapAll[F[_] : Functor, A, B](fa: F[A])(f: A => B): F[B] = Functor[F].map(fa)(f)
def liftAll[F[_] : Functor, A, B](f: A => B): F[A] => F[B] = Functor[F].lift(f)
def mapAll2[F[_] : Functor, G[_] : Functor, A, B](fg: F[G[A]])(f: A => B): F[G[B]] = mapAll(fg)(liftAll(f))
def liftAll2[F[_] : Functor, G[_] : Functor, A, B](f: A => B): F[G[A]] => F[G[B]] = liftAll(liftAll(f))
implicit val functorForOption: Functor[Option] = new Functor[Option] {
def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa match {
case None => None
case Some(a) => Some(f(a))
}
}
implicit val functorForList: Functor[List] = new Functor[List] {
def map[A, B](fa: List[A])(f: A => B): List[B] = fa match {
case head :: tail => f(head) :: map(tail)(f)
case _ => Nil
}
}
def increment(x: Int) = x + 1
val option10 = Option(10)
println(functorForOption.lift(increment)(option10))
println(functorForOption.map(option10)(increment))
println(mapAll(option10)(increment))
println(functorForList.map(List(10, 20))(increment))
println(mapAll(List(10, 20))(increment))
val lo = List(option10, None, mapAll(option10)(_*2))
println(mapAll2(lo)(increment))
// more annoying to use as compiler cannot derive type for func
val func = liftAll2[List, Option, Int, Int](increment)
println(func(lo))
val ol = Option(List(11, 32))
println(mapAll2(ol)(increment))
val ll = List(List(10, 22), List(30, 40))
println(mapAll2(ll)(increment))
}
Some(11)
Some(11)
Some(11)
List(11, 21)
List(11, 21)
List(Some(11), None, Some(21))
List(Some(11), None, Some(21))
Some(List(12, 33))
List(List(11, 23), List(31, 41))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment