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

cats.lift.lift.scala Maven / Gradle / Ivy

/**
  * Originally adapted from shapeless-contrib
  * https://github.com/typelevel/shapeless-contrib/blob/v0.4/scalaz/main/scala/lift.scala
  */
package cats.lift

import cats.{Applicative, Apply}
import cats.implicits._

import shapeless._
import shapeless.ops.function._
import shapeless.syntax.std.function._

trait LifterAux[G[_], I <: HList, R, GI <: HList] {
  def apply(gf: G[I => R])(implicit G: Apply[G]): GI => G[R]
}

object LifterAux {

  implicit def liftZero[G[_], R]: LifterAux[G, HNil, R, HNil] = new LifterAux[G, HNil, R, HNil] {
    def apply(gf: G[HNil => R])(implicit G: Apply[G]) = _ =>
      gf map { _(HNil) }
  }

  implicit def liftCons[G[_], H, T <: HList, R, GI <: HList](implicit tail: LifterAux[G, T, R, GI]): LifterAux[G, H :: T, R, G[H] :: GI] = new LifterAux[G, H :: T, R, G[H] :: GI] {
    def apply(gf: G[(H :: T) => R])(implicit G: Apply[G]) = {
      case gh :: gi =>
        tail(G.map2(gh, gf) { (h, f) => t => f(h :: t) })(G)(gi)
    }
  }
}

trait LiftsOps {

  implicit class ApplicativeOps[G[_]](instance: Applicative[G]) {
    def liftA[F, R, I <: HList, GI <: HList, OF](f: F)(
      implicit hlister: FnToProduct.Aux[F, I => R],
      lifter: LifterAux[G, I, R, GI],
      unhlister: FnFromProduct.Aux[GI => G[R], OF]
    ): OF =
      lifter(instance.pure(f.toProduct))(instance).fromProduct
  }

}







© 2015 - 2025 Weber Informatics LLC | Privacy Policy