Created
April 26, 2020 12:45
-
-
Save fancellu/c8c0e9d42752eb92c60b3bfc2d9209a8 to your computer and use it in GitHub Desktop.
Simple Scala Functor example, no cats
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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