简体   繁体   中英

Lifting a function to ~> in scalaz

I have the following types and declarations:

import scalaz._, Scalaz._

trait Container[T] 
type FreeContainer[A] = Free[Container, A]
type FreeFreeContainer[A] = Free[FreeContainer, A]

val fc: FreeContainer[Int]
val ffc: FreeFreeContainer[Int]

val t: Container ~> Id

val tranformed: Int = fc.foldMap(t)   //ok
val tranformed2: Int = ffc.foldMap(t) //error

Is it possible to lift Container ~> Id to FreeContainer ~> Id ?

Yes, via foldMap :

val t: Container ~> Id

val tt: FreeContainer ~> Id = new (FreeContainer ~> Id) {
  def apply[A](fc: FreeContainer[A]): A = fc.foldMap(t)
}

Using the polymorphic lambda syntax of kind-projector , this can be simplified to

val tt: FreeContainer ~> Id = λ[FreeContainer ~> Id](_.foldMap(t))

So you can do

val tranformed2: Int = ffc.foldMap(λ[FreeContainer ~> Id](_.foldMap(t)))

Alternatively, you can just do two consecutive foldMap s, the first one with the identity natural transformation:

val tranformed2: Int = ffc.foldMap(NaturalTransformation.refl[FreeContainer]).foldMap(t)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM