Last active
May 28, 2019 22:36
-
-
Save djspiewak/6cd3f9313dac7421f0afaab03fedb8fd to your computer and use it in GitHub Desktop.
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
// ...get it? | |
final case class InductT[F[_], A](run: F[A]) | |
// assume InductT is defined in some upstream library, so it knows nothing of the following | |
trait Functor[F[_]] | |
object Functor { | |
implicit def inductTFunctor[F[_]: Functor]: Functor[InductT[F, ?]] = new Functor[InductT[F, ?]] | |
} | |
// assume this is defined in the "enterprise-java-monads" library | |
trait Monad[F[_]] extends Functor[F[_]] | |
object Monad { | |
implicit def inductTMonad[F[_]: Monad]: Monad[InductT[F, ?]] = new Monad[InductT[F, ?]] | |
} | |
// and *this* is defined in "enterprise-java-traverses", which depends on "enterprise-java-functor" but not on the monad one | |
trait Traverse[F[_]] extends Functor[F] | |
object Traverse { | |
implicit def inductTTraverse[F[_]: Traverse]: Traverse[InductT[F, ?]] = new Traverse[InductT[F, ?]] | |
} | |
// finally, in a fifth library... | |
final case class Box[A](a: A) | |
object Box { | |
implicit object instance extends Monad[Box] with Traverse[Box] | |
} | |
// here's the call site | |
def foo[F[_]: Monad: Traverse] = implicitly[Functor[F]] // fails to compile! | |
def bar[F[_]](implicit F: Monad[F] with Traverse[F]) = implicitly[Functor[F]] // compiles! | |
bar[Box] // all good | |
bar[InductT[Box, ?]] // not so much | |
/** | |
* So to be clear, we have five independent compilation groups (i.e. separate libraries): | |
* | |
* 1. InductT | |
* 2. Functor (depends on InductT) | |
* 3. Monad (depends on Functor) | |
* 4. Traverse (depends on Functor) | |
* 5. Box/foo/bar (depends on Monad, Traverse) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment