Skip to content

Monad Transformer typeclass #4727

@johnynek

Description

@johnynek

I saw this: #4724 and wondered if we have a monad transformer typeclass similar to: https://hackage.haskell.org/package/transformers-0.6.1.2/docs/Control-Monad-Trans-Class.html

I don't see one. I can imagine something like:

trait MonadTrans[T[_[_], _]] {
  def liftK[M[_]: Monad]: FunctionK[M, [A] =>> T[M, A]]
  def lift[M[_]: Monad, A](ma: M[A]): T[M, A]

  implicit def transMonad[M[_]: Monad]: Monad[[A] =>> T[M, A]]
}

And possibly even:

trait MonadTrans[T[_[_], _]] {
  def liftK[M[_]: Monad]: FunctionK[M, [A] =>> T[M, A]]
  def lift[M[_]: Monad, A](ma: M[A]): T[M, A]
  
  implicit def transMonad[M[_]: Monad]: Monad[[A] =>> T[M, A]]
  
  type RunT[_]
  def run[M[_]: Monad, A](fa: T[M, A]): M[RunT[A]]
  def liftRun[M[_]: Monad, A](run: M[RunT[A]]): T[M, A]
}

since I think all the transformers seem to have some notion of a "run" version. The laws would be:

MonadTrans[T].lift(fa) == MonadTrans[T].liftK[M](fa)

MonadTrans[T].lift(Monad[M].pure(a)) == MonadTrans[T].transMonad[M].pure(a)

MonadTrans[T].lift(ma.flatMap(f)) == MonadTrans[T].lift(ma).flatMap(a => MonadTrans[T].lift(f(a)))

MonadTrans[T].liftRun(MonadTrans[T].run(fa)) == fa

The argument against this, I think, would be that it's not clear what useful functions you would write against MonadTrans except perhaps for having a clear way to lift: MonadTrans[OptionT].lift(fa)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions