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

scalaz.SelectT.scala Maven / Gradle / Ivy

package scalaz

import scalaz.Id.Id

/** Selection monad transformer.
  *
  * @see [[https://www.cs.bham.ac.uk/~mhe/papers/selection-escardo-oliva.pdf]]
  * @see [[https://arxiv.org/pdf/1406.2058.pdf]]
  * @see [[https://github.com/ghc/packages-transformers/blob/0_5_4_0/Control/Monad/Trans/Select.hs]]
  */
final case class SelectT[R, M[_], A](run: (A => M[R]) => M[A]) { self =>

  def map[B](f: A => B)(implicit F: Functor[M]): SelectT[R, M, B] =
    SelectT(x =>
      run.andThen(F.map(_)(f)).apply(x.compose(f))
    )

  def flatMap[B](f: A => SelectT[R, M, B])(implicit F: Bind[M]): SelectT[R, M, B] =
    SelectT { k =>
      val h = f.andThen(_.run(k))
      F.bind(run(h.andThen(F.bind(_)(k))))(h)
    }

  def toContT(implicit F: Bind[M]): ContT[R, M, A] =
    ContT(k => F.bind(run(k))(k))

}

sealed abstract class SelectTInstances7 {
  implicit def selectTFunctor[R, M[_]: Functor]: Functor[SelectT[R, M, *]] =
    new SelectTFunctor[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances6 extends SelectTInstances7 {
  implicit def selectTBind[R, M[_]: Bind]: Bind[SelectT[R, M, *]] =
    new SelectTBind[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances5 extends SelectTInstances6 {
  implicit def selectTPlus[R, M[_]: Plus]: Plus[SelectT[R, M, *]] =
    new SelectTPlus[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances4 extends SelectTInstances5 {
  implicit def selectTPlusEmpty[R, M[_]: PlusEmpty]: PlusEmpty[SelectT[R, M, *]] =
    new SelectTPlusEmpty[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances3 extends SelectTInstances4 {
  implicit def selectTMonad[R, M[_]: Monad]: Monad[SelectT[R, M, *]] =
    new SelectTMonad[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances2 extends SelectTInstances3 {
  implicit def selectMonad[R]: Monad[Select[R, *]] =
    SelectT.selectTMonad[R, Id](using Id.id)
}

sealed abstract class SelectTInstances1 extends SelectTInstances2 {
  implicit def selectTMonadPlus[R, M[_]: MonadPlus]: MonadPlus[SelectT[R, M, *]] =
    new SelectTMonadPlus[R, M] {
      override def F = implicitly
    }
}

sealed abstract class SelectTInstances extends SelectTInstances1 {
  implicit def selectTMonadTrans[R]: MonadTrans[({type l[x[_], y] = SelectT[R, x, y]})#l] =
    new MonadTrans[({type l[x[_], y] = SelectT[R, x, y]})#l] {
      override def liftM[G[_]: Monad, A](a: G[A]) =
        SelectT(_ => a)

      override def apply[G[_]: Monad] =
        SelectT.selectTMonad[R, G]
    }
}

object SelectT extends SelectTInstances {

}

private trait SelectTFunctor[R, M[_]] extends Functor[SelectT[R, M, *]] {
  protected implicit def F: Functor[M]

  override final def map[A, B](fa: SelectT[R, M, A])(f: A => B) =
    fa map f
}

private trait SelectTBind[R, M[_]] extends Bind[SelectT[R, M, *]] with SelectTFunctor[R, M] {
  protected implicit def F: Bind[M]

  override def bind[A, B](fa: SelectT[R, M, A])(f: A => SelectT[R, M, B]) =
    fa flatMap f
}

private trait SelectTMonad[R, M[_]] extends Monad[SelectT[R, M, *]] with SelectTBind[R, M] {
  protected def F: Monad[M]

  override def point[A](a: => A): SelectT[R, M, A] =
    SelectT(_ => F.point(a))
}

private trait SelectTPlus[R, M[_]] extends Plus[SelectT[R, M, *]] {
  protected def F: Plus[M]

  override def plus[A](a: SelectT[R, M, A], b: => SelectT[R, M, A]) =
    SelectT(k => F.plus(a.run(k), b.run(k)))
}

private trait SelectTPlusEmpty[R, M[_]] extends PlusEmpty[SelectT[R, M, *]] with SelectTPlus[R, M] {
  protected def F: PlusEmpty[M]

  override def empty[A] =
    SelectT(_ => F.empty[A])
}

private trait SelectTMonadPlus[R, M[_]] extends MonadPlus[SelectT[R, M, *]] with SelectTPlusEmpty[R, M] with SelectTMonad[R, M] {
  protected def F: MonadPlus[M]
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy