Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Forked from gakuzzzz/functor.scala
Last active December 28, 2015 20:38
Show Gist options
  • Save xuwei-k/7558430 to your computer and use it in GitHub Desktop.
Save xuwei-k/7558430 to your computer and use it in GitHub Desktop.
trait Functor[A, F[_]] { self =>
def fmap[B](f: A => B): F[B]
}
trait ~>[-F[_], +G[_]]{
def apply[A](fa: F[A]): G[A]
}
object Functor {
implicit class list[A](val l: List[A]) extends Functor[A, List] {
def fmap[B](f: A => B): List[B] = l map f
}
implicit class option[A](val o: Option[A]) extends Functor[A, Option]{
def fmap[B](f: A => B): Option[B] = o map f
}
type FunctorConversion[F[_]] = (F[A] => Functor[A, F]) forSome {type A}
}
object Main {
import Functor._
def foo[F[_]: FunctorConversion, G[_]: FunctorConversion](fa: F ~> G): Unit = ???
def bar[A, B, F[_], G[_]](fa: F ~> G)(implicit F: F[A] => Functor[A, F], G: G[B] => Functor[B, G]): Unit = ???
val option2list = new (Option ~> List){
def apply[A](fa: Option[A]) = fa.toList
}
// foo(option2list) // compile error. No implicit view available from Option => .
// foo[Option, List](option2list) // compile error. No implicit view available from Option => .
foo(option2list)(Functor.option _, Functor.list _)
bar(option2list) // success
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment