簡體   English   中英

收集問題中的Scala自我類型和this.type

[英]Scala self type and this.type in collections issue

我試圖在scala中圍繞抽象和顯式自我類型。 讓我們考慮這個例子:我想為可擴展樹創建一個簡單的基礎:

trait Tree {
  def children: Iterable[Tree]
  def descendants: Iterable[Tree] = { val dv = children.view; dv ++ (dv.flatMap { _.children }) }
}

但是,我希望能夠使用某些方法擴展樹節點並使用以下方法: tree.children foreach { _.newMethod() }

為此,我嘗試過:

A. this.type:失敗

trait Tree {
    def children: Iterable[this.type] 
    def descendants: Iterable[this.type] = {
      val dv = children.view
      // FAIL: type mismatch;  found   :  scala.collection.IterableView[com.abovobo.data.Tree,Iterable[_]]  required: Iterable[Tree.this.type] 
      // dv ++ (dv.flatMap { _.children })
      // OK: 
      dv.++[this.type, Iterable[this.type]](dv.flatMap[this.type, Iterable[this.type]]{ _.children })
    }
}

工作變體非常笨拙。

B.摘要類型:失敗

trait Tree {
    type Node <: Tree

    def children: Iterable[Node]  
    def descendants: Iterable[Node] = {
        val dv = children.view
        // FAIL: type mismatch;  found   : scala.collection.IterableView[com.abovobo.data.Tree#Node,Iterable[_]]  required: Iterable[Tree.this.Node] 
        dv ++ (dv.flatMap { _.children })
    }
}

根據我的理解,由於路徑特定類型不匹配,根本不起作用。

C.類型params(泛型):好的

trait Tree[+Node <: Tree[Node]] {

    def children: Iterable[Node]

    def descendants: Iterable[Node] = {
       val dv = children.view
       dv ++ (dv.flatMap { _.children })
    }
}

工作正常,但在派生類中維護不太好。

任何想法如何使前兩個變體工作沒有大量的代碼?

另外,使用this.type我遇到了實現問題。

trait BiDTree extends Tree {
    def parent: Option[this.type]
}

// how to accept this param? Option[TreeImpl] doesn't work. 
class TreeImpl(val parent: Option[???]) extends BiDTree {
  // ...
}

謝謝!

如果沒有真正理解你遇到的問題(C),你可以嘗試(B)的變體:

trait Tree {
    type Node <: Tree

    def children: Iterable[Tree#Node]  
    def descendants: Iterable[Tree#Node] = {
        val dv = children.view
        dv ++ (dv.flatMap { _.children })
    }
}

這避免了您的路徑特定類型問題。 順便說一下,你應該看看http://www.assembla.com/spaces/scala-graph/wiki

最后,我已經討論了http://www.scala-lang.org/node/6649中討論的內容:

trait Tree[+Node <: Tree[Node]] {
    this: Node =>

    def children: Iterable[Node]

    def descendants: Iterable[Node] = {
       val dv = children.view
       dv ++ (dv.flatMap { _.children })
    }
}  

即變體(C)但具有明確的自我類型。 這使得有機會在其他方法中使用this (比如方法find(path: String): Option[Node] )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM