我有以下类型和声明:
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
是否可以将Container ~> Id
提升为FreeContainer ~> Id
?
答案 0 :(得分:3)
是的,通过foldMap
:
val t: Container ~> Id
val tt: FreeContainer ~> Id = new (FreeContainer ~> Id) {
def apply[A](fc: FreeContainer[A]): A = fc.foldMap(t)
}
使用polymorphic lambda syntax of kind-projector,可以简化为
val tt: FreeContainer ~> Id = λ[FreeContainer ~> Id](_.foldMap(t))
所以你可以做到
val tranformed2: Int = ffc.foldMap(λ[FreeContainer ~> Id](_.foldMap(t)))
或者,你可以连续两个foldMap
,第一个带有身份自然转换:{/ p>
val tranformed2: Int = ffc.foldMap(NaturalTransformation.refl[FreeContainer]).foldMap(t)