I'm trying to wrap a Java API of a library in multiple Scala-friendly ways. So the base API looks like this:
trait Keyer[K]
class Base[T] {
def keyBy[K](keyer: Keyer[K]): Base[K] = ???
}
We want to add a lambda method, so we don't need to write new Keyer[K] { def ??? } all the time. Extending the base class works:
class Child[T] extends Base[T] {
def keyBy[K](fun: T => K): Base[K] = ???
}
new Child[Int].keyBy(x => x) // no issues so far
But doing similar thing using implicit classes fails:
trait ChildOps[T] {
def keyBy[K](fun: T => K): Base[K] = ???
}
implicit class BaseOps[T](base: Base[T]) extends ChildOps[T]
new Base[Int].keyBy(x => x) // compile error: missing parameter type
I also tried to move the keyBy method directly to the implicit class without extending anything, but the compile error is still there:
implicit class BaseOps2[T](base: Base[T]) {
def keyBy[K](fun: T => K): Base[K] = ???
}
new Base[Int].keyBy(x => x) // compile error: missing parameter type
Giving up and annotating keyBy method with types is also problematic:
implicit class BaseOps2[T](base: Base[T]) {
def keyBy[K](fun: T => K): Base[K] = ???
}
new Base[Int].keyBy[Int]((x: Int) => x)
// type mismatch;
// found : Int => Int
// required: com.test.ImplicitTest.Keyer[Int]
// new Base[Int].keyBy[Int]((x: Int) => x)
So the question is: how can I add a generic overridden method with lambda parameter in an implicit class? And why all my attempts above giving a compile errors?
Code fails on Scala 2.13.8 and 2.12.15, but compiles successfully on 3.1.2.