在scalaz中将函数提升到〜>

问题描述 投票:1回答:1

我有以下类型和声明:

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

scala monads functor scalaz kind-projector
1个回答
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)))

或者,你可以做两个连续的foldMaps,第一个带有身份自然转换:

val tranformed2: Int = ffc.foldMap(NaturalTransformation.refl[FreeContainer]).foldMap(t)
© www.soinside.com 2019 - 2024. All rights reserved.