Skip to content

Instantly share code, notes, and snippets.

@joroKr21
Created March 16, 2018 11:26
Show Gist options
  • Save joroKr21/a2f0083ebb14e94046b1feb42734f301 to your computer and use it in GitHub Desktop.
Save joroKr21/a2f0083ebb14e94046b1feb42734f301 to your computer and use it in GitHub Desktop.
/** 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