Hatena::ブログ(Diary)

seraphrの日記

2011-09-01 scalaの抽象型について考えてみる

scalaの抽象型について考えてみる

twitter

みたいなことを言っていたら、Expression Problemを解決するという文脈で、以下のコードを書いてもらえた。

https://gist.github.com/1184933

これを、Genericsと比較するために、Generics + 自分型注釈なコードを書いてみた。



trait VisitorsBaseGenerics { self =>
  trait Node[V <: Visitor[V]] {
    def accept(v: V)
  }
  case class Add[V <: Visitor[V]](l: Node[V], r: Node[V]) extends Node[V] {
    def accept(v: V) {
      v.visit(this)
    }
  }
  case class Sub[V <: Visitor[V]](l: Node[V], r: Node[V]) extends Node[V] {
    def accept(v: V) {
      v.visit(this)
    }
  }
  case class Value[V <: Visitor[V]](value: Int) extends Node[V] {
    def accept(v: V) {
      v.visit(this)
    }
  }
  trait Visitor[V <: Visitor[V]] { self: V =>
    def visit(node: Add[V]) {
      println("Add!")
      node.l.accept(this)
      node.r.accept(this)
    }
    def visit(node: Sub[V]) {
      println("Sub!")
      node.l.accept(this)
      node.r.accept(this)
    }
    def visit(node: Value[V]) {
      println("Value: " + node.value)
    }
  }
}

class VisitorsPlusGenerics extends VisitorsBaseGenerics {
  case class Mul[V <: Visitor[V]](l: Node[V], r: Node[V]) extends Node[V] {
    def accept(v: V) {
      v.visit(this)
    }
  }
  case class Div[V <: Visitor[V]](l: Node[V], r: Node[V]) extends Node[V] {
    def accept(v: V) {
      v.visit(this)
    }
  }
  class Visitor[V <: Visitor[V]] extends super.Visitor[V] { self: V =>
    def visit(node: Mul[V]) {
      println("Mul")
      node.l.accept(this)
      node.r.accept(this)
    }
    def visit(node: Div[V]) {
      println("Div")
      node.l.accept(this)
      node.r.accept(this)
    }
  }
}

object VisitorGenericsMain {
  val mVisitorContainer = new VisitorsPlusGenerics
  import mVisitorContainer._

  class UseVisitor extends Visitor[UseVisitor]
  def main(args: Array[String]) {
    val v = new UseVisitor
    Add(Value(1), Value(2)).accept(v)
    Sub(Value(1), Value(2)).accept(v)
    Mul(Value(1), Value(2)).accept(v)
    Div(Value(1), Value(2)).accept(v)
  }
}

実際に使う場合&拡張について考えるため、VisitorsPlusGenericsでは型を確定させないようにしておいた。

自分型注釈についてよくわかってないのは内緒。 あとでドキュメント読む。

時間がないので、とりあえずここまで。

こういう、自己参照(自己言及?)するGenericsコードはたまに書くことがあるんだけど、単純な記述量的な嬉しさは感じた。 それ以外についてはまたあとで考えてみる。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/seraphr/20110901/1314862602