Last active
June 29, 2018 14:52
-
-
Save LukaJCB/3a24b17d4bfce642c939e0a45512c2c0 to your computer and use it in GitHub Desktop.
Easy monad transformer lifting?
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
trait MonadTrans[T[_[_], _]] { | |
def lift[M[_]: Monad, A](ma: M[A]): T[M, A] | |
def hoist[M[_]: Monad, N[_]: Monad, A](tma: T[M, A])(f: M ~> N): T[N, A] | |
} | |
object MonadTrans { | |
def apply[T[_[_], _]: MonadTrans]: MonadTrans[T] = implicitly | |
} | |
implicit def applicativeAskMonadTrans[T[_[_], _]: MonadTrans, M[_]: Monad, R] | |
(implicit T: Monad[T[M, ?]], A: ApplicativeAsk[M, R]): ApplicativeAsk[T[M, ?], R] = new DefaultApplicativeAsk[T[M, ?], R] { | |
val applicative: Applicative[T[M, ?]] = T | |
def ask: T[M, R] = MonadTrans[T].lift(A.ask) | |
} | |
implicit def monadTransForOptionT: MonadTrans[OptionT] = new MonadTrans[OptionT] { | |
def lift[M[_]: Monad, A](ma: M[A]): OptionT[M, A] = OptionT.liftF(ma) | |
def hoist[M[_]: Monad, N[_] : Monad, A](tma: OptionT[M, A])(f: M ~> N): OptionT[N, A] = tma.mapK(f) | |
} | |
def foo[F[_]](implicit F: ApplicativeAsk[F, Int]): F[Int] = | |
F.applicative.map(F.ask)(_ + 1) | |
val result: Int = | |
foo[OptionT[Kleisli[Eval, Int, ?], ?]].value.run(42).value.getOrElse(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment