0
我正在定義一個通用的樹結構,即可以擴展的一個例子,以便例如分支和葉子包含附加值(例如,我需要添加一個名稱字符串)。解決令人討厭的模式匹配問題
所以它看起來像這樣:
trait TreeNodes {
val Node = Either
type Node[+B, +L] = Either[B, L]
val IsBranch = Left
type IsBranch[+B, +L] = Left[B, L]
val IsLeaf = Right
type IsLeaf[+B, +L] = Right[B, L]
}
object TreeLike extends TreeNodes {
trait BranchLike[Elem, B, L] {
type N = Node[B, L]
def iterator: Iterator[N]
}
trait LeafLike[Elem] {
def value: Elem
}
}
trait TreeLike[Elem, Repr] {
type Leaf <: TreeLike.LeafLike[Elem]
type Branch <: TreeLike.BranchLike[Elem, Branch, Leaf]
def root: Branch
}
不幸的是,有一個模式匹配錯誤:
def test[Elem, T <: TreeLike[Elem, T]](tree: T): Unit = {
import TreeLike.{IsLeaf, IsBranch}
def printLeaves(b: T#Branch): Unit = b.iterator.foreach {
case IsLeaf(l) => println(l.value)
case IsBranch(c) => printLeaves(c)
}
printLeaves(tree.root)
}
錯誤如下:
[error] during phase: patmat
[error] library version: version 2.10.3
[error] compiler version: version 2.10.3
...
[error] symbol definition: case val x1: b.N
[error] tpe: b.N
[error] symbol owners: value x1
[error] context owners: value x0$1 -> value $anonfun -> method printLeaves ->
method test -> object Voodoo -> package typerbug
...
[error] no-symbol does not have an owner
我懷疑patmat有以某種方式與T#Branch
麻煩。任何想法如何在這裏解決?
我也不是100%滿意的包裝葉子和樹枝在Either
。這是必要的,因爲當我試圖定義一個超類型的LeafLike
和BranchLike
,並弄清楚如何在實現中正確地使用子類型,並且模式匹配打破了,因爲我沒有弄清楚得到正確的提取器。所以也許使用Either
這不是一個壞主意嗎?
使用Scala 2.11.0-M6編譯器不會崩潰... –
我想你會看到[SI- 7891](https://issues.scala-lang.org/browse/SI-7891),並且有一個很長的錯誤列表:/ –
@SRI有趣......那張票並不是說它是在2.11.0-M6中解決,但我應該附上我的例子 –