簡體   English   中英

如何表達更高種類的類型的約束

[英]How to express type constraints for higher kinded type

我正在嘗試創建一些特征的列表,這些特征使用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類型的邊界>:沒什么<:A [Y]嚴格於類型_的聲明邊界>:沒什么<:Z forSome {類型Z <:A [Z]} val myList = emptyList [B]()

在我看來, _ <: Z forSome { type Z <: A[Z] }確實至少與Y <: A[Y]一樣嚴格,但也許我缺少了一些東西。

因此,問題是-正確處理B的EmptyList函數上的約束應該是什么?

經過一番嘗試和錯誤后,我開始使用它。 注意:編譯器告訴我們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))
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM