考虑以下类型定义:
trait LiftF[F[_], G[_]] {
def liftF[A](fa: F[A]): G[A]
}
Run Code Online (Sandbox Code Playgroud)
在上下文边界中提供对此类隐式的要求时(使用种类投影仪插件),我们必须这样编写:
def func[A, G[_], F[_]: LiftF[?[_], G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
我想摆脱这一?[_]部分,所以我最初的猜测是编写一个To[G[_]]返回的类型,LiftF[?[_], G]以将上述函数定义转换为
def func[A, G[_], F[_]: LiftF.To[G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
但是,在将类型To定义写为
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
我收到以下编译错误:
Error:(17, 20) type ?$ takes type parameters
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
尝试使用存在性类型重写它会产生以下类型定义:
type To[G[_]] = LiftF[F, G] forSome { type F[X] }
Run Code Online (Sandbox Code Playgroud)
这可以很好地编译,但是,毫无疑问,它不能应用于其他类型参数,因此无法实现所需的函数定义。
我设法通过受aux模式启发的代码实现了“部分应用程序”部分:
trait To[G[_]] {
type From[F[_]] = LiftF[F, G]
}
Run Code Online (Sandbox Code Playgroud)
可悲的是,这给我留下了比原始语法差的语法:
def func[A, …Run Code Online (Sandbox Code Playgroud) types scala partial-application higher-kinded-types kind-projector
我在Scala代码中的traits层次结构存在以下问题:
首先,我有一个MyTrait[A]具有这样定义的基本特征:
trait MyTrait[A] {
def v1: A
}
Run Code Online (Sandbox Code Playgroud)
然后是一个Base带有类型成员的特征定义:
trait Base[A] {
type T <: MyTrait[A]
val baseV: T
}
Run Code Online (Sandbox Code Playgroud)
并且,最后,一个特征Gen覆盖了Base类型成员.
trait Gen[A, X <: MyTrait[A]] extends Base[A] {
type T = X
}
Run Code Online (Sandbox Code Playgroud)
问题是在Gen特征中似乎丢失了类型成员的边界.这可以通过以下测试证明:
编译:
trait Test1 {
val x: Base[_]
println(x.baseV.v1)
}
Run Code Online (Sandbox Code Playgroud)
不编译(value v1 is not a member of Test2.this.x.T):
trait Test2 {
val x: Gen[_, _]
println(x.baseV.v1)
}
Run Code Online (Sandbox Code Playgroud)
我想知道这是语言的限制还是有解决方法.针对以上类似问题上stackowerflow问题(1,2)似乎把重点放在比我的不同方面,我真的不知所措,因为我无法找到有关Scala的这种行为多的信息.
可以在 …