I've probably encountered a version of chained implicit conversions problem (http://docs.scala-lang.org/tutorials/FAQ/chaining-implicits.html). And I cannot figure out how to work it around.
I attached a SSCCE example below which illustrates the issue. Let me add some details here:
1) I want to have a method like the following one:
def chainedTransform[A, B, C](a: A)(f1: F[A, B], f2: F[B, C]): C
It should transform value from type A to type C.
2) It may happen that the transformer F with necessary type parameters is not present in scope, but a satisfying implicit conversion is.
3) The whole approach is demonstrated in the snippet below.
test("Mutliple conversions") {
val f1: Function1[String, Int] = (s) => s.toInt
val f2: Function1[Int, Boolean] = (i) => i > 0
val f3: Function[Option[Int], Option[Boolean]] = (iOpt) => iOpt map (_ > 0)
implicit def toOptFun[A, B](f: Function1[A, B]): Function1[Option[A], Option[B]] =
new Function1[Option[A], Option[B]] {
override def apply(v1: Option[A]): Option[B] = v1 map f
}
case class Test[A](param: A) {
def transform[B](t1: Function1[A, B]): B = t1(param)
def chainedTransform[B, C](t1: Function1[A, B], t2: Function1[B, C]): C = t2(t1(param))
}
val test1 = Test("123")
assert(test1.chainedTransform(f1, f2))
val test2 = Test(Option("123"))
//toOptFun implicit conversion is applied successfully
assert(test2.transform(f1) == Some(123))
//Does not compile:
//test2.chainedTransform(f1, f2)
// [error] found : Int => Boolean
// [error] required: Option[Int] => Boolean
// [error] test2.chainedTransform(f1, f2)
// [error] ^
//f3 is exactly what toOptFun(f2) would produce if applied
assert(test2.chainedTransform(f1, f3) == Some(true))
}
Any ideas how to make it work?