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% 満足しているわけではありませんEitherLeafLikeこれが必要だったのは、andのスーパータイプを定義しようとしたときに手に負えなくなってしまいBranchLike、実装でそのサブタイプを正しくサブタイプにする方法を見つけ出し、取得方法がわからなかったためにパターン マッチングも壊れてしまったためです。正しいエクストラクター。だから、おそらくそれを使うEitherのは悪い考えではないでしょうか?

4

1 に答える 1

0

型エイリアスNは「問題」です (WTF)。

  trait BranchLike[Elem, B, L] {
    def iterator: Iterator[Node[B, L]]
  }

これにより、コンパイルされます。それが崩壊しようとしている場合、私はこの構造を構築し続ける意欲があまりありません:-(

于 2013-10-30T10:19:24.773 に答える