部分应用类型参数

0__*_*0__ 13 scala higher-kinded-types

我拼命想要解决以下问题:

trait Access[Res[_]] { def access[C]: Res[C] }

trait CList[C1, A] extends Access[CList[_, A]] // ?!

def test[C1, C2, A](c: CList[C1, A]): CList[C2, A] = c.access[C2]
Run Code Online (Sandbox Code Playgroud)

scalac只是说:"error: illegal cyclic reference involving trait CList".我该怎么做这个编译?

Mor*_*itz 14

您可能对lambdas类型感兴趣.您在答案中使用的部分应用程序实际上是在scalaz中实现的.由于代码往往不太可读,因此他们开始使用lambda类型.有问题的类型可以写成

({type ?[?] = CList[?,A]})#?
Run Code Online (Sandbox Code Playgroud)

这通过?在结构类型内的参数化类型上创建类型投影来工作,从而捕获外部类型参数(在这种情况下A).

您的答案中描述的与方差有关的另一个问题可以通过使Res参数变为Access协变来解决.

完成这些更改后,您的代码应如下所示:

trait Access[+Res[_]] { def access[C] : Res[C]}

trait CList[C, +A] extends Access[({type ?[?] = CList[?,A]})#?]
Run Code Online (Sandbox Code Playgroud)