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.