Scala - Overloading method in implicit class

Viewed 150

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

1 Answers
Related