在 Scala 中,为什么下限在这里不能很好地工作?
In scala, why doesn't lower bound work well here?
这些代码编译得很好:
abstract class CodeTree
case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
case class Leaf(char: Char, weight: Int) extends CodeTree
def weight(tree: CodeTree): Int = tree match {
case Fork(left, right, chars, weight) => weight
case Leaf(char, weight) => weight
}
def insert_orderedCodeTreeList[T >: CodeTree](leaf: CodeTree, orderedCodeTrees: List[CodeTree]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}
但是我这样用会报错:
insert_orderedCodeTreeList[Leaf](Leaf(theChar, theInt), makeOrderedLeafList(tail))
type arguments [patmat.Huffman.Leaf] do not conform to method insert_orderedCodeTreeList's type parameter bounds [T >: patmat.Huffman.CodeTree]
[error] case (theChar, theInt) :: tail => insert_orderedCodeTreeList[Leaf](Leaf(theChar, theInt), makeOrderedLeafList(tail))
[error] ^
[error] one error found
可以看出,类型参数T
使用CodeTree
作为下界,因此,我认为将参数列表中的CodeTree替换为T
可能就可以了insert_orderedCodeTreeList
:
def insert_orderedCodeTreeList[T >: CodeTree](leaf: T, orderedCodeTrees: List[T]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}
但是,编译器会抱怨:
[error] found : T
[error] required: patmat.Huffman.CodeTree
[error] if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
[error] ^
有人对此有想法吗?
看完the document about bounds,我发现正确的写法是这样写的:
def insert_orderedCodeTreeList[T <: CodeTree](leaf: T, orderedCodeTrees: List[T]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}
这些代码编译得很好:
abstract class CodeTree
case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
case class Leaf(char: Char, weight: Int) extends CodeTree
def weight(tree: CodeTree): Int = tree match {
case Fork(left, right, chars, weight) => weight
case Leaf(char, weight) => weight
}
def insert_orderedCodeTreeList[T >: CodeTree](leaf: CodeTree, orderedCodeTrees: List[CodeTree]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}
但是我这样用会报错:
insert_orderedCodeTreeList[Leaf](Leaf(theChar, theInt), makeOrderedLeafList(tail))
type arguments [patmat.Huffman.Leaf] do not conform to method insert_orderedCodeTreeList's type parameter bounds [T >: patmat.Huffman.CodeTree]
[error] case (theChar, theInt) :: tail => insert_orderedCodeTreeList[Leaf](Leaf(theChar, theInt), makeOrderedLeafList(tail))
[error] ^
[error] one error found
可以看出,类型参数T
使用CodeTree
作为下界,因此,我认为将参数列表中的CodeTree替换为T
可能就可以了insert_orderedCodeTreeList
:
def insert_orderedCodeTreeList[T >: CodeTree](leaf: T, orderedCodeTrees: List[T]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}
但是,编译器会抱怨:
[error] found : T
[error] required: patmat.Huffman.CodeTree
[error] if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
[error] ^
有人对此有想法吗?
看完the document about bounds,我发现正确的写法是这样写的:
def insert_orderedCodeTreeList[T <: CodeTree](leaf: T, orderedCodeTrees: List[T]): List[T] = orderedCodeTrees match {
case Nil => List(leaf)
case head :: tail => {
if (weight(leaf) <= weight(head)) leaf :: orderedCodeTrees
else head :: insert_orderedCodeTreeList(leaf, tail)
}
}