簡體   English   中英

在Scala中訂購時出現編譯錯誤

[英]Compilation error with Ordered in Scala

我在Scala中實施不可變的BST時遇到了一些麻煩。 問題似乎是由於某種原因,盡管我將K定義為Ordered[K] (第二行),但實際上Scala編譯器認為它是Any 為什么?

abstract class BST
sealed case class Node[K <: Ordered[K], V](key : K, value : V, left : BST, right : BST) extends BST
sealed case class Empty() extends BST

object BST {
  def empty = Empty()

  def add[K <: Ordered[K], V](key : K, value : V, tree : BST) : BST = tree match {
    case Empty() => new Node(key, value, Empty(), Empty())
    case Node(nodeKey, nodeValue, left, right) =>
      if (key < nodeKey) new Node(nodeKey, nodeValue, add(key, value, left), right)
      else if (key > nodeKey) new Node(nodeKey, nodeValue, left, add(key, value, right))
      else new Node(key, value, left, right)
  }

好的,謝謝您的幫助。 但是我認為你們都太復雜了。 唯一的問題似乎是BST也必須也是BST [K,V]:

abstract class BST[K <: Ordered[K], V]
sealed case class Node[K <: Ordered[K], V](key : K, value : V, left : BST[K, V], right : BST[K, V]) extends BST[K, V]
sealed case class Empty[K <: Ordered[K], V]() extends BST[K, V]

object BST {
  def empty = Empty()

  def add[K <: Ordered[K], V](key : K, value : V, tree : BST[K, V]) : BST[K, V] = tree match {
    case Empty() => new Node(key, value, Empty(), Empty())
    case Node(nodeKey, nodeValue, left, right) =>
      if (key < nodeKey) new Node(nodeKey, nodeValue, add(key, value, left), right)
      else if (key > nodeKey) new Node(nodeKey, nodeValue, left, add(key, value, right))
      else new Node(key, value, left, right)
  }
}

這將編譯並按預期方式工作。

告訴編譯器泛型類型KOrdered[K]的子類型,似乎使編譯器感到困惑。 我也對此感到困惑。 這就像說AList[A]的子類型,我也無法繞開它。 類型如何成為該類型列表的子類型? 遞歸定義類型在某些情況下可能會起作用,但我不認為這是其中之一。

從上下文來看,我覺得您想要的實際語法是[K: Ordered] 這告訴編譯器期望泛型K ,其范圍中包含隱式Ordered[K] 它是語法糖,將您的Node類更改為如下形式:

sealed case class Node[K, V](key : K, value : V, left : BST, right : BST)(implicit evidence: Ordered[K]) extends BST

這是因為JVM上的類型擦除-在Scala中已擦除為Any 請參閱此答案,例如有關如何解決此問題的示例: 如何在Scala中對通用類型進行模式匹配? 也可以考慮傳遞一個隱式Ordering如下所示:

sealed case class Node[K, V](key : K, value : V, left : BST, right : BST,
  implicit cmp: Ordering[K]) extends BST

我已經將其簡化為編譯版本,盡管它可能不是最小的,並且可以刪除一些顯式注釋。 如果您需要更多說明,請發表評論。

abstract class BST[K : Ordering, V]
sealed case class Node[K : Ordering, V](key : K, value : V, left : BST[K, V], right : BST[K,V]) extends BST[K, V]
sealed case class Empty[K : Ordering, V]() extends BST[K, V]

object BST {
  def empty[K : Ordering, V] = Empty[K,V]()

  def add[K : Ordering, V](key : K, value : V, tree : BST[K,V]) : BST[K,V] = tree match {
    case Empty() => new Node(key, value, Empty(), Empty())
    case Node(nodeKey, nodeValue, left, right) =>
      if (implicitly[Ordering[K]].lt(key,  nodeKey)) new Node(nodeKey, nodeValue, add(key, value, left), right)
      else if (implicitly[Ordering[K]].gt(key,nodeKey)) new Node(nodeKey, nodeValue, left, add(key, value, right))
      else new Node(key, value, left, right)
  }
}

暫無
暫無

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

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