Skip to content

Instantly share code, notes, and snippets.

@markandrus
Last active August 29, 2015 14:06
Show Gist options
  • Save markandrus/03868aa239b7e2940dbc to your computer and use it in GitHub Desktop.
Save markandrus/03868aa239b7e2940dbc to your computer and use it in GitHub Desktop.
test.scala
import scala.language.higherKinds
object Test {
// Functors
trait Functor[F[_]] {
def fmap[A, B](fa: F[A])(f: A => B): F[B]
}
implicit def OptionFunctor: Functor[Option] = new Functor[Option] {
def fmap[A, B](fa: Option[A])(f: A => B) = fa map f
}
implicit def Tuple2Functor[C]: Functor[({type λ[α] = Tuple2[C, α]})#λ] = new Functor[({type λ[α] = Tuple2[C, α]})#λ] {
def fmap[A, B](fa: (C, A))(f: A => B) = (fa._1, f(fa._2))
}
implicit def ListFunctor: Functor[List] = new Functor[List] {
def fmap[A, B](fa: List[A])(f: A => B) = fa map f
}
// Functor Composition
class Compose[F[_]: Functor, G[_]: Functor, A](val unCompose: F[G[A]])(implicit val F: Functor[F], implicit val G: Functor[G]) extends Functor[({type λ[α] = Compose[F, G, α]})#λ] {
def fmap[A, B](composed: Compose[F, G, A])(f: A => B) =
// new Compose(F.fmap(composed.unCompose)(G.fmap(_)(f)))(F, G, F, G)
compose(F.fmap(composed.unCompose)(G.fmap(_)(f)))(F, G)
}
def compose[F[_]: Functor, G[_]: Functor, A](unCompose: F[G[A]]): Compose[F, G, A] =
new Compose(unCompose)
// The fixed-point of a Functor
class Fix[F[_]: Functor](val unFix: F[Fix[F]])(implicit val F: Functor[F]) {
def cata[A](fixed: Fix[F])(phi: F[A] => A): A = {
phi(F.fmap(fixed.unFix)(cata(_)(phi)))
}
}
def fix[F[_]: Functor](f: F[Fix[F]]): Fix[F] = new Fix(f)
}
@markandrus
Copy link
Author

Thanks to /u/real_huitz for help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment