All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalaz.MonadTrans.scala Maven / Gradle / Ivy

package scalaz

/** Class of monad transformers. */
trait MonadTrans[F[_[_], _]] {
  /** A component of `Applicative.point` for the transformer stack. */
  def liftM[G[_] : Monad, A](a: G[A]): F[G, A]

  /** A version of `liftM` that infers the type constructor `G`. */
  final def liftMU[GA](a: GA)(implicit G: Unapply[Monad, GA]): F[G.M, G.A] =
    liftM[G.M, G.A](G(a))(using G.TC)

  def wrapEffect[G[_]: Monad, A](a: G[F[G, A]]): F[G, A] =
    apply[G].join(liftM(a))

  /** The [[scalaz.Monad]] implied by this transformer. */
  implicit def apply[G[_] : Monad]: Monad[F[G, *]]

  def mapF[G[_], A, B](fa: F[G, A])(f: A => G[B])(implicit M: Monad[G]): F[G, B] =
    Monad[F[G, *]].bind(fa)(a => liftM(f(a)))

  trait MonadTransLaw {
    /** Lifted `point` is `point` of this transformer's monad. */
    def identity[G[_], A](a: A)(implicit G: Monad[G], FA: Equal[F[G, A]]): Boolean =
      FA.equal(liftM(G.point(a)), Monad[F[G, *]].point(a))

    /** `bind` and then `liftM` is the same as `liftM` and then `bind` */
    def composition[G[_], A, B](ga: G[A], f: A => G[B])(implicit G: Monad[G], FB: Equal[F[G, B]]): Boolean =
      FB.equal(liftM(Monad[G].bind(ga)(f)), Monad[F[G, *]].bind(liftM(ga))(a => liftM(f(a))))
  }
  def monadTransLaw: MonadTransLaw = new MonadTransLaw {}
}

object MonadTrans {
  def apply[F[_[_], _]](implicit F: MonadTrans[F]): MonadTrans[F] = F
}

trait Hoist[F[_[_], _]] extends MonadTrans[F] {
  def hoist[M[_]: Monad, N[_]](f: M ~> N): F[M, *] ~> F[N, *]
}

object Hoist {
  def apply[F[_[_], _]](implicit F: Hoist[F]): Hoist[F] = F
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy