I currently have an issue where I am trying to overload a method contained within quill using an implicit class, normally this is possible with the simple case, i.e. if you have something like
class Test {
def rawr(string: String): String = string
}
You can easily overload this definition of rawr using a different type like so
implicit final class RawrExt(val t: Test) {
def rawr(int: Int): Int = int
}
And this compiles as expected, i.e.
val t = new Test
t.rawr(5)
Even if Test has more complex type parameters, this still works, i.e.
class Test[T <: Number] {
def rawr(string: String): String = string
}
implicit final class RawrExt[N <: Number](val t: Test[N]) {
def rawr(int: Int): Int = int
}
val t = new Test[BigDecimal]
t.rawr(5)
Where I am getting a problem is when I am trying to implement the exact same overloading for the quill-monix-jdbc's transaction. When using monix-quill-jdbc, you have a transaction method that has the following signature
def transaction[A](f: Task[A]): Task[A]
The issue is that we are using TaskResult in our application logic which is Monad Transformer of Either and Task using cats, i.e.
type TaskResult[T] = EitherT[Task, GeneralError, T]
What I am trying to do is to provide an override for transaction which takes TaskResult rather than Task, defining this in an implicit class is quite straight forward
object TaskResultSupport {
implicit final class TaskResultCtxSupport[Dialect <: SqlIdiom, Naming <: NamingStrategy](
val value: MonixJdbcContext[Dialect, Naming]) {
def transaction[A](f: TaskResult[A]): TaskResult[A] =
EitherT(value.transaction(f.value))
}
}
And then when we try to use it we get a compilation error, it can't seem to pick up the implicit class.
val ctx: PostgresMonixJdbcContext[SnakeCase] =
new PostgresMonixJdbcContext(SnakeCase, "database")
val taskResult: TaskResult[Unit] = TaskResult(())
ctx.transaction(taskResult) // This doesn't compile
I tried all various permutations of defining the implicit class, i.e. as an example
implicit final class TaskResultCtxSupport(val value: MonixJdbcContext[_, _]) extends AnyVal
And none seem to work. Here is the compilation error
type mismatch;
found : Playground.this.Implicits.TaskResult[Unit]
(which expands to) cats.data.EitherT[monix.eval.Task,Playground.this.GeneralError,Unit]
required: monix.eval.Task[?]
A scastie demonstrating the problem can be found here https://scastie.scala-lang.org/pqAn8fUPTbmBqToCVIXDXA. Thanks to Martjin Hoekstra, there is a further minimized example here https://scastie.scala-lang.org/4YrhP0HSRzu7F9numrqAGQ. Scala contributors thread can be found here https://contributors.scala-lang.org/t/scala-compiler-unable-to-overload-methods-with-type-parameters/3761