Created
March 16, 2018 11:26
-
-
Save joroKr21/a2f0083ebb14e94046b1feb42734f301 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
/** Enable MTL-style programming by avoiding ambiguous implicits. */ | |
class MTL[M](val M: M) extends AnyVal | |
object MTL { | |
type MonadMTL[F[_]] <: Monad[F] | |
implicit def mtl[M](implicit M: M): MTL[M] = new MTL[M](M) | |
private def MonadMTL[M[f[_]] <: Monad[f], F[_]](M: M[F]): MonadMTL[F] = | |
M.asInstanceOf[MonadMTL[F]] | |
/** An artificial hierarchy for MTL type classes. */ | |
object Hierarchy extends Hierarchy1 | |
sealed abstract class Hierarchy0 extends Hierarchy1 { | |
implicit def monadP[F[_]](implicit mtl: MTL[MonadPlus[F]]): MonadMTL[F] = MonadMTL(mtl.M) | |
} | |
sealed abstract class Hierarchy1 extends Hierarchy2 { | |
implicit def monadE[F[_], E](implicit mtl: MTL[MonadError[F, E]]): MonadMTL[F] = MonadMTL(mtl.M) | |
} | |
sealed abstract class Hierarchy2 extends Hierarchy3 { | |
implicit def monadS[F[_], S](implicit mtl: MTL[MonadState[F, S]]): MonadMTL[F] = MonadMTL(mtl.M) | |
} | |
sealed abstract class Hierarchy3 extends Hierarchy4 { | |
implicit def monadR[F[_], R](implicit mtl: MTL[MonadReader[F, R]]): MonadMTL[F] = MonadMTL(mtl.M) | |
} | |
sealed abstract class Hierarchy4 extends Hierarchy5 { | |
implicit def monadT[F[_], W](implicit mtl: MTL[MonadTell[F, W]]): MonadMTL[F] = MonadMTL(mtl.M) | |
} | |
sealed abstract class Hierarchy5 { | |
implicit def monadPlus[F[_]](implicit mtl: MTL[MonadPlus[F]]): MonadPlus[F] = mtl.M | |
implicit def monadError[F[_], E](implicit mtl: MTL[MonadError[F, E]]): MonadError[F, E] = mtl.M | |
implicit def monadState[F[_], S](implicit mtl: MTL[MonadState[F, S]]): MonadState[F, S] = mtl.M | |
implicit def monadReader[F[_], R](implicit mtl: MTL[MonadReader[F, R]]): MonadReader[F, R] = mtl.M | |
implicit def monadTell[F[_], W](implicit mtl: MTL[MonadTell[F, W]]): MonadTell[F, W] = mtl.M | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment