暗黙のパラメータについて少し調べたのでポストします。
「暗黙のパラメータは一つだけ」と私は勘違いしていたのですが
それは以下のような感じで・・
val curry = (i:Int) => (j:Int, k:String) => i + j + k.toInt
// curry: (Int) => (Int, String) => Int = <function1>
上記を元にj、kをimplicit宣言しようとすると
以下のようにエラーになるからでした。
val curry = (i:Int) => (implicit j:Int, k:String) => i + j + k.toInt
// error: '=>' expected but ',' found.
// val curry = (i:Int) => (implicit j:Int, k:String) => i + j + k.toInt
// ^
しかし、メソッド宣言の形で以下のように定義すると
j、kをimplicitにすることができるんですね。
def curry(i:Int)(implicit j:Int, k:String) = i + j + k.toInt
// curry: (i: Int)(implicit j: Int, implicit k: String)Int
これをかなり多用しているのが
scalacheckのorg.scalacheck.Propオブジェクトです。
このソースコードを読んでこの事を知りました。
https://github.com/rickynils/scalacheck/blob/master/src/main/scala/org/scalacheck/Prop.scala
複数の暗黙パラメータはこんな感じで値を渡すだけでなく
implicit val str: String = "YAMADA"
implicit val int: Int = 12
def profile(firstName:String)(implicit lastName: String, age: Int) = {
firstName + " " + lastName.toUpperCase + "(" + age + ")"
}
println(profile("Taro")) // "Taro YAMADA(12)"
function型も暗黙のパラメータにすることができます。
implicit val toS = (i:Int) => i.toString
def printInt(i:Int)(implicit toS: (Int) => String) = println(toS(i))
printInt(123) // "123"
implicit val p = (s:String) => println(s)
def printInt(i:Int)(implicit toS:(Int) => String, p:(String) => Unit )
= p(toS(i))
printInt(123) // "123"
参考まで。