たとえば、枝や葉に追加の値が含まれるように拡張できる一般的なツリー構造を定義しています (たとえば、名前文字列を追加するにはこれが必要です)。
したがって、次のようになります。
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
これが必要だったのは、andのスーパータイプを定義しようとしたときに手に負えなくなってしまいBranchLike
、実装でそのサブタイプを正しくサブタイプにする方法を見つけ出し、取得方法がわからなかったためにパターン マッチングも壊れてしまったためです。正しいエクストラクター。だから、おそらくそれを使うEither
のは悪い考えではないでしょうか?