如何表达更高种类类型的类型约束

Posted

技术标签:

【中文标题】如何表达更高种类类型的类型约束【英文标题】:How to express type constraints for higher kinded type 【发布时间】:2012-11-02 11:16:49 【问题描述】:

我正在尝试创建一些特征列表,由使用 CRTP 的类型参数化,但无法弄清楚如何表达类型约束。下面是一些说明问题的示例代码:

trait A[X] 
  def x: X


trait B[Y <: A[Y]] 
  def y(i: Int): Y


case class C(i: Int) extends A[C] 
  def x = C(i)


case class D(i: Int) extends A[D] 
  def x = D(i)


case class E() extends B[C] 
  def y(i: Int) = C(i)


case class F() extends B[D] 
  def y(i: Int) = D(i)


object Program extends App 
  def emptyList[X[_ <: Z forSome  type Z <: A[Z]  ]]() = collection.mutable.ListBuffer.empty[X[_]]

  val myList = emptyList[B]()
  myList += E()
  myList += F()

  println(myList.map(_.y(2).x))

所以我在这里尝试创建一个符合 B 特征的对象列表。但是这段代码不会编译,并给出以下错误:

类型参数的种类(B)不符合类型参数(类型X)的预期种类。 B 的类型参数与 X 类型的预期参数不匹配:类型 Y 的边界 >:Nothing <: a _>:Nothing <: z forsome type a val mylist="空列表[B]">

在我看来,_ &lt;: Z forSome type Z &lt;: A[Z] 确实至少与 Y &lt;: A[Y] 一样严格,但也许我遗漏了一些东西。

所以问题是 - emptyList 函数应该有什么约束才能正确处理 B?

【问题讨论】:

我认为这里的问题是你真正想要的是说X[_ &lt;: Z forAll type Z &lt;: A[Z] ] - 即你想要一个更高级别的类型。不过,我还没有弄清楚如何实现这一点! 【参考方案1】:

经过反复试验,我得到了它的工作。注意:编译器告诉我们 A[+X] 和 B[+Y] 中的类型参数必须是协变的。

trait A[+X] 
  def x: X


trait B[+Y <: A[Y]] 
  def y(i: Int): Y


case class C(i: Int) extends A[C] 
  def x = C(i)


case class D(i: Int) extends A[D] 
  def x = D(i)


case class E() extends B[C] 
  def y(i: Int) = C(i)


case class F() extends B[D] 
  def y(i: Int) = D(i)



object Test extends App 
  def emptyList[X[Y <: A[Y]]] = collection.mutable.ListBuffer.empty[X[Y forSome type Y <: A[Y] ]]

  val myList = emptyList[B]
  myList += E()
  myList += F()

  println(myList.map(_.y(2).x))

【讨论】:

我也在尝试协方差设置,但没有设法让 emptyList 方法正确。感谢您解决这个问题。

以上是关于如何表达更高种类类型的类型约束的主要内容,如果未能解决你的问题,请参考以下文章

sql server中表达式null=0的值是

DBMS-SQL:连接表达式视图事务完整性约束数据类型与模式授权

Java认识泛型与容器

为啥物化泛型很难与更高种类的类型结合?

广义 HM 与高阶统一

第二章 数据类型运算符和表达式