0

私はScalaが初めてです。型理論の基礎を知っています。

問題は、コールバックを持つノードのグラフ オブジェクトを作成することです。

以下は、現在の実装の簡略化されたバージョンです。これはライブラリの一部です。

それは機能しますが、いっぱいですAny。すべてを取り除くことは不可能だと思いますAnyが、もっと良い方法があると思います。

特に、CallbackNode共変の型パラメータをとりますが、コールバックの型は反変なので、 になりAnyます。
ただし、コールバックはユーザー コードのいたるところにあるためA、使いやすさのために型を使用することをお勧めします。

このような問題に対してどのように設計するか教えてください。

trait Graph[N] {
  var nodes: List[N]
  var edges: List[Edge[N]]

  def register(node: N) { nodes = node :: nodes }
  def dependants(node: N): Seq[N] = { ... }
}

object MyGraph with Graph[CallbackNode[Any]] {
  ...
}

class CallbackNode[+A](getter: => A) {
  var cache: Option[Any]
  MyGraph.register(this)

  def onChange(callback: Any => Unit) { ... }
  def update() {
    val v = getter
    storeInCache(v)
    dependants.foreach { n => n.notify() }
    callbacks.foreach { c => c(v) }
  }

  ...
}
4

2 に答える 2

0

特定のグラフ インスタンスごとに、すべてのコールバックが同じ型 A を持つことを受け入れることができる場合は、その型をグラフ定義の一部として移動できます。おそらく望んでいないので、最初の共通の祖先を使用する必要があります。これは最終的に Any になる可能性があります。

ただし、Scala には、コレクションのように動作するデータ構造を持ちながら、目的どおりに型を保持する方法があります。@MilesSabin shapeless library を見て、それがどのように行われるかを理解する必要があります。 https://github.com/milessabin/shapeless

HList や HMap などの Shapeless の概念を習得したら、HGraph を開発してオープンソースにすることができます :)

于 2013-06-24T11:34:48.603 に答える