Created
July 31, 2012 12:00
-
-
Save YoEight/3216489 to your computer and use it in GitHub Desktop.
Coproduct implicit resolution
This file contains hidden or 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
object coprod { | |
trait Functor[F[_]]{ | |
def map[A, B](fa: F[A])(f: A => B): F[B] | |
} | |
implicit val optionFunctor = new Functor[Option]{ | |
def map[A, B](fa: Option[A])(f: A => B) = fa map f | |
} | |
implicit val listFunctor = new Functor[List]{ | |
def map[A, B](fa: List[A])(f: A => B) = fa map f | |
} | |
implicit val streamFunctor = new Functor[Stream]{ | |
def map[A, B](fa: Stream[A])(f: A => B) = fa map f | |
} | |
/*implicit def coproductFunctor[F[_], G[_]](implicit F: Functor[F], G: Functor[G]) = new Functor[coproduct[F, G]#ap]{ | |
def map[A, B](ea: Either[F[A], G[A]])(f: A => B) = ea match { | |
case Left(fa) => Left(F.map(fa)(f)) | |
case Right(ga) => Right(G.map(ga)(f)) | |
} | |
} | |
trait coproduct[F[_], G[_]]{ | |
type or[H[_]] = coproduct[({type f[x] = Either[F[x], G[x]]})#f, H] | |
type ap[A] = Either[F[A], G[A]] | |
}*/ | |
trait Coproduct[F[_], G[_], A]{ | |
def fold[Z](inl: (=> F[A]) => Z, inr: (=> G[A]) => Z): Z | |
def map[B](f: A => B)(implicit F: Functor[F], G: Functor[G]): Coproduct[F, G, B] = this match { | |
case Inl(fa) => Inl(F.map(fa)(f)) | |
case Inr(ga) => Inr(G.map(ga)(f)) | |
} | |
} | |
object Inl { | |
def apply[F[_], G[_], A](v: => F[A]): Coproduct[F, G, A] = new Coproduct[F, G, A]{ | |
def fold[Z](inl: (=> F[A]) => Z, inr: (=> G[A]) => Z) = inl(v) | |
} | |
def unapply[F[_], G[_], A](co: Coproduct[F, G, A]) = | |
co.fold(Some(_), _ => None) | |
} | |
object Inr { | |
def apply[F[_], G[_], A](v: => G[A]): Coproduct[F, G, A] = new Coproduct[F, G, A]{ | |
def fold[Z](inl: (=> F[A]) => Z, inr: (=> G[A]) => Z) = inr(v) | |
} | |
def unapply[F[_], G[_], A](co: Coproduct[F, G, A]) = | |
co.fold(_ => None, Some(_)) | |
} | |
trait :+:[F[_], G[_]]{ | |
type ap[A] = Coproduct[F, G, A] | |
} | |
implicit def coproductFunctor[F[_], G[_]](implicit F: Functor[F], G: Functor[G]) = new Functor[(F :+: G)#ap]{ | |
def map[A, B](fa: Coproduct[F, G, A])(f: A => B) = fa map f | |
} | |
type To = (Option :+: Stream)#ap :+: List | |
val f = implicitly[Functor[((Option :+: Stream)#ap :+: List)#ap]] // error | |
val g = implicitly[Functor[(Option :+: Stream)#ap]] // works | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment