Scala 部分应用类型参数

Scala 部分应用类型参数,scala,higher-kinded-types,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] scalac只是说:“错误:涉及trait CList的非法循环引用”。如何进行编译?通过谷歌搜索“部分类型应用程序”,我在scala辩

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

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]
scalac只是说:
“错误:涉及trait CList的非法循环引用”
。如何进行编译?

通过谷歌搜索“部分类型应用程序”,我在scala辩论列表上找到了James Iry发布的解决方案(;经过调整,因此参数顺序发生了变化):

cheese louise,这真的是2011年在scala做到这一点的唯一方法吗

编辑:

此操作失败,协方差在
A
:-(


您可能对lambdas类型感兴趣。您在回答中使用的部分应用程序实际上是。 但是,由于代码的可读性越来越差,他们开始使用lambdas类型

({type λ[α] = CList[α,A]})#λ
其工作原理是在结构类型内部的参数化类型
λ
上创建类型投影,从而捕获外部类型参数(在本例中为
a

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

在这些更改之后,您的代码应该如下所示:

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

trait CList[C, +A] extends Access[({type λ[α] = CList[α,A]})#λ]

我知道这是一个很老的问题,但无论如何:

trait AnyAccess {
  type Res[X]
  def access[Z]: Res[Z]
}

trait AnyCList extends AnyAccess { me =>
  type C
  type A
  // this could be a subtype bound instead, if needed
  type Res[X] = AnyCList { type C = X; type A = me.A }
}
case object AnyCList {
  type of[C0, +A0] = AnyCList { type C = C0; type A <: A0 }
}

case object buh {

  def test[C1, C2, A](c: AnyCList.of[C1, A]): AnyCList.of[C2, A] = c.access[C2]
}
trait-AnyAccess{
类型Res[X]
def访问[Z]:分辨率[Z]
}
trait AnyCList扩展AnyAccess{me=>
C型
A型
//如果需要,这可以是子类型绑定
类型Res[X]=AnyCList{type C=X;type A=me.A}
}
case对象AnyCList{
类型[C0,+A0]=AnyCList{type C=C0;类型A只是为了更新东西
将此编译器插件添加到您的sbt中,以进行种类投影,您将使用
获得一个很好的语法
这将删除看起来凌乱的类型投影样板文件!
因此,您可以编写类似于
的内容,如[String,?]

addCompilerPlugin(“org.spire math”%%“kind projector”%%“0.9.7”)

它是用下面相同的旧类型投影实现的



您也可以在这里找到它:

这里有一个方法对我来说“部分应用类型参数”:

我有一个函数,比如

def foo[A, B, C, D, E](...)
因此,我只需要提示一个类型参数,编译器就可以推断出其余的类型参数。这对我来说很有效:

object InferType {
  type InferType[A] = Option[A]
  def apply[A]: Option[A] = None
}
更新foo以获取推断类型的附加参数:

// t parameter is unused in implementation but
// is used by compiler to infer other type parameters
def foo[A, B, C, D, E](..., t: InferType[D]) 
用法:

foo(..., InferType[ConcreteD])

谢谢,这看起来好一点。另外,因为在我的真实情况下,CLIST的类型参数有上界,有一个专用的特性PARTAL2不是很有帮助(我需要为边界添加类型参数)。如果在代码中经常使用类型LAMBDAS,请考虑下面的编译器插件:
// t parameter is unused in implementation but
// is used by compiler to infer other type parameters
def foo[A, B, C, D, E](..., t: InferType[D]) 
foo(..., InferType[ConcreteD])