[Scala]View BoundとContext Boundについて

2011年12月2日

View BoundとContext Boundとは

「頻出する暗黙(implicit)変換・パラメータの利用方法」のシンタックスシュガー

implicitとは

scala> implicit val a:Int = 1
scala> implicit val s:String = "a"

scala> def some(implicit v:Int) : Int = v

scala> some
res0: Int = 1

def some[Int](implicit v:Int) : Int = v
def some[String](implicit v:String) : String = v

scala> some[Int]
res1: Int = 1
scala> some[String]
res2: String = a

View Boundとは

def f1[T](implicit f2: T => A[T])

は、

def f1[T <% A[T]]

と書くことが出来る
これがView Bound

実際どーいう事かというと

trait Listable[T]{
  def list:List[T]
}

implicit def intLister(a: Int) = new Listable[Int]{def list: List[Int] = (1 to a).toList}
implicit def strLister(a: String) = new Listable[String]{def list: List[String] = (1 to a.toInt).toList.collect{case x => x.toString()}}

// 暗黙変換を使った処理
def lister[T](a: T)(implicit f: T => Listable[T]) = a.list

// ここが上記の関数をView Boundを適用した書き方
def lister2[T <% Listable[T]](a: T) = a.list

Context Boundとは

def f[T]( implicit a:A[T] )

def f[T:A]

と書ける

trait Listable[T] {
  def lister(a:T,b:T):List[T]
}

implicit object IntLister extends Listable[Int]{
  def lister(a:Int, b:Int):List[Int] = (a to b).toList
}

implicit object StringLister extends Listable[String]{
  def lister(a:String, b:String):List[String] = (a.toInt to b.toInt).toList.collect{case x => x.toString()}
}

def Lister[T](a:T,b:T)( implicit comp:Listable[T] ):List[T] = comp.lister(a,b)

Lister(1, 10)
Lister("1", "10")

def Lister2[T:Listable](a:T,b:T):List[T] = implicitly[Listable[T]].lister(a,b)

Lister2(1, 10)
Lister2("1", "10")

Scala

Posted by GENDOSU