gpt4 book ai didi

scala - 使用种类投影仪在 Scala 中部分应用类型 lambda

转载 作者:行者123 更新时间:2023-12-04 14:53:54 24 4
gpt4 key购买 nike

考虑以下类型定义:

trait LiftF[F[_], G[_]] {
def liftF[A](fa: F[A]): G[A]
}

当在上下文边界(使用 kind 投影插件)中提供这种类型的隐式要求时,我们必须这样写:
def func[A, G[_], F[_]: LiftF[?[_], G]](a: F[A]): G[A]

我想摆脱 ?[_]部分,所以我最初的猜测是写一个类型 To[G[_]]返回 LiftF[?[_], G]为了将上述函数定义转化为
def func[A, G[_], F[_]: LiftF.To[G]](a: F[A]): G[A]

但是,写类型时 To定义为
type To[G[_]] = LiftF[?[_], G]

我收到以下编译错误:
Error:(17, 20) type Λ$ takes type parameters
type To[G[_]] = LiftF[?[_], G]

尝试用存在类型重写它会产生以下类型定义:
type To[G[_]] = LiftF[F, G] forSome { type F[X] }

这编译得很好,但不出所料,不能应用于其他类型参数,因此无法实现所需的函数定义。

我设法使用受辅助模式启发的代码实现了“部分应用程序”部分:
trait To[G[_]] {
type From[F[_]] = LiftF[F, G]
}

可悲的是,这给我留下的语法可能比原始语法更糟糕:
def func[A, G[_], F[_]: LiftF.To[G]#From](a: F[A]): G[A]

我的问题是 - 我可以在实物投影仪的帮助下在 Scala 中实现最初提出的语法,或者我应该坚持使用 ?[_] ?

最佳答案

据我了解, kind-projector 在这里无法真正帮助您:

type To[G[_]] = LiftF[?[_], G]

会简单地被机械地改写成类似的东西
type To[G[_]] = ({ type T[F[_]] = LiftF[F, G] })#T

但它在 2.12.x 中无效,因为它期望类型为 *在定义的右侧。

如果移动参数 F到左侧,你最终得到
type To[G[_], F[_]] = LiftF[F, G]

然后您必须将其用作 To[G, ?[_]] ,这显然也不会给您带来任何好处,它只是交换了参数的顺序。因此我建议只使用 LiftF[?[_], G]并从您不必写出 ({ type L[F[_]] = LiftF[F, G] })#L 的事实中获得安慰明确地。

顺便说一句,在 Dotty 中,这很好用:
trait LiftF[F[_], G[_]] {
def liftF[A](fa: F[A]): G[A]
}

type To[G[_]] = [F[_]] => LiftF[F, G]
def f[A, G[_], F[_]: To[G]](a: F[A]): G[A] = implicitly[LiftF[F, G]].liftF(a)

关于scala - 使用种类投影仪在 Scala 中部分应用类型 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55278487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com