Scala - метод перегрузки в неявном классе - PullRequest
3 голосов
/ 17 октября 2019

В настоящее время у меня есть проблема, когда я пытаюсь перегрузить метод, содержащийся в quill, используя неявный класс, обычно это возможно в простом случае, например, если у вас есть что-то вроде

class Test {
  def rawr(string: String): String = string
}

Вы можетелегко перегрузить это определение rawr, используя другой тип, например

implicit final class RawrExt(val t: Test) {
  def rawr(int: Int): Int = int
}

И это скомпилируется, как ожидается, т.е.

val t = new Test
t.rawr(5)

Даже если Test имеет параметры более сложного типа,это все еще работает, то есть

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)

Проблема, с которой я сталкиваюсь, это когда я пытаюсь реализовать ту же самую перегрузку для транзакции quill-monix-jdbc. При использовании monix-quill-jdbc у вас есть метод транзакции, имеющий следующую подпись

def transaction[A](f: Task[A]): Task[A]

Проблема заключается в том, что мы используем TaskResult в нашей логике приложения, которая является Monad Transformer из Either иTask с использованием кошек, то есть

type TaskResult[T] = EitherT[Task, GeneralError, T]

Я пытаюсь сделать переопределение для transaction, которое занимает TaskResult вместо Task, определяя это в implicit class:совершенно прямолинейно

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))
  }
}

А потом, когда мы пытаемся использовать его, мы получаем ошибку компиляции, кажется, он не может подобрать implicit class.

val ctx: PostgresMonixJdbcContext[SnakeCase] =
  new PostgresMonixJdbcContext(SnakeCase, "database")

val taskResult: TaskResult[Unit] = TaskResult(())

ctx.transaction(taskResult) // This doesn't compile

Я пыталсявсе различные варианты определения неявного класса, например,

implicit final class TaskResultCtxSupport(val value: MonixJdbcContext[_, _]) extends AnyVal

И, похоже, ни одна из них не работает. Вот ошибка компиляции

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[?]

Scastie, демонстрирующий проблему, можно найти здесь https://scastie.scala -lang.org / pqAn8fUPTbmBqToCVIXDXA . Благодаря Martjin Hoekstra, есть еще один минимизированный пример здесь https://scastie.scala -lang.org / 4YrhP0HSRzu7F9numrqAGQ . Поток участников Scala можно найти здесь https://contributors.scala -lang.org / t / scala-compiler-неспособный перегрузить-методы-с-типом-параметрами / 3761

1 Ответ

0 голосов
/ 18 октября 2019

Оказывается, это была ошибка в текущем компиляторе Scala, решение для 2.13. Подробнее см. https://github.com/scala/scala/pull/7396.

...