[Scala]View BoundとContext Boundについて
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")