這是Scala中左側堆的實現。隱式從Int到有序轉換的問題
package my.collections
sealed abstract class Heap[E](implicit val ordering:Ordering[E]) {
import ordering._
def empty: Heap[E] = Heap.empty
def isEmpty: Boolean
def insert(e: E): Heap[E]
def merge(h: Heap[E]): Heap[E] = {
def makeT(e:E,a:Heap[E],b:Heap[E]):Heap[E] = if (a.rank >= b.rank) Node(e,a,b,b.rank+1) else Node(e,b,a,a.rank+1)
(this,h) match {
case (Nil(),_) => h
case (_,Nil()) => this
case (Node(x,l1,r1,_),Node(y,l2,r2,_)) => if (x < y) makeT(x,l1,r1.merge(h)) else makeT(y,l2,this.merge(r2))
}
}
def findMin: E
def deleteMin: Heap[E]
protected def rank:Int
}
object Heap {
private val emptyEl = new Nil[Nothing]
def empty[E] = emptyEl.asInstanceOf[Heap[E]]
}
private case class Node[E](e: E, left: Heap[E], right: Heap[E], rank: Int)(implicit ordering:Ordering[E]) extends Heap[E]()(ordering) {
def deleteMin = left.merge(right)
val findMin = e
def insert(e: E):Heap[E] = Node(e,empty,empty,1).merge(this)
def isEmpty = false
}
private case class Nil[E]()(implicit ordering:Ordering[E]) extends Heap[E]()(ordering) {
def deleteMin = throw new NoSuchElementException
def findMin = throw new NoSuchElementException
def insert(e: E):Heap[E] = Node[E](e,Heap.empty,Heap.empty,1)
def isEmpty = true
protected def rank = 0
}
object PG {
def main(args: Array[String]) {
val e:Heap[Int] = Heap.empty[Int]
val e1:Heap[Int] = e insert 3
val e2:Heap[Int] = e1 insert 5
val e3:Heap[Int] = e2.deleteMin
println()
}
}
這失敗,出現以下錯誤:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to scala.math.Ordered
at scala.math.LowPriorityOrderingImplicits$$anon$3.compare(Ordering.scala:117)
at scala.math.Ordering$class.lt(Ordering.scala:71)
at scala.math.LowPriorityOrderingImplicits$$anon$3.lt(Ordering.scala:117)
at scala.math.Ordering$Ops.$less(Ordering.scala:100)
at my.collections.Heap.merge(Heap.scala:27)
at my.collections.Node.insert(Heap.scala:53)
at my.collections.PG$.main(Heap.scala:77)
at my.collections.PG.main(Heap.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
我的問題是:
- 究竟我做錯了,以及如何解決這個問題?
- 有沒有一種理解這種錯誤的系統方法?
爲了補充這一點,在我看來,問題在於,通過調用'Nil [Nothing]',它是'Ordering [Nothing]'作爲隱含傳遞的,並且由於'asInstanceOf'謊言。 – 2011-04-05 00:24:53
當然你是對的,對我來說這是一個完整的白癡時刻,但是這是可以修復的,因此只有一個空節點的實例? – user44242 2011-04-05 06:33:47
@ user44242爲什麼只需要一個實例?正如我所說的,你可以嘗試在'E'中設置'Heap'協變,然後你可以使用'Nil [Nothing]'。 Scala的'List'類是這樣構造的,'Nil'是一個case對象。 – 2011-04-05 12:27:22