Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created July 29, 2023 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xuwei-k/ccf4cbca4a059e13be401ac28efed99c to your computer and use it in GitHub Desktop.
Save xuwei-k/ccf4cbca4a059e13be401ac28efed99c to your computer and use it in GitHub Desktop.
impl Functor use PolyFunction
scalaVersion := "3.4.0-RC1-bin-20230727-ac69c66-NIGHTLY"
crossScalaVersions += "3.3.0"
package example
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def fromPolyFunction[F[_]](x: [A, B] => (fa: F[A]) => (f: A => B) => F[B]): Functor[F] =
new Functor[F] {
def map[A, B](fa: F[A])(f: A => B): F[B] = x(fa)(f)
}
implicit val list: Functor[List] =
fromPolyFunction([A, B] => (fa: List[A]) => (f: A => B) => fa.map(f))
implicit val vector: Functor[Vector] =
fromPolyFunction([A, B] => (fa: Vector[A]) => (f: A => B) => fa.map(f))
implicit val option: Functor[Option] =
fromPolyFunction([A, B] => (fa: Option[A]) => (f: A => B) => fa.map(f))
implicit def either[L]: Functor[[a] =>> Either[L, a]] =
fromPolyFunction([A, B] => (fa: Either[L, A]) => (f: A => B) => fa.map(f))
}
object FunctorExplicitInstances {
val list: Functor[List] =
new Functor[List] {
def map[A, B](fa: List[A])(f: A => B) = fa map f
}
val vector: Functor[Vector] =
new Functor[Vector] {
def map[A, B](fa: Vector[A])(f: A => B) = fa map f
}
val option: Functor[Option] =
new Functor[Option] {
def map[A, B](fa: Option[A])(f: A => B) = fa map f
}
def either[L]: Functor[[a] =>> Either[L, a]] =
new Functor[[a] =>> Either[L, a]] {
def map[A, B](fa: Either[L, A])(f: A => B) = fa map f
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment