Как определить частично параметризовать общий неявный класс? - PullRequest
1 голос
/ 12 мая 2019

Можно ли частично определить параметризованный неявный класс? Например, предположим, у меня есть следующий класс

  implicit class IoExt[L, R](val io: IO[R]) {
    def wrapped(errorCode: String): IO[Either[ProcessingResult[L], R]] = ???
  }

Как я могу определить что-то вроде

type IoExtLocal[R] = IoExt[String, R]

И есть ли IoExtLocal[R] доступным как неявный класс?

Мотивация состоит в том, чтобы при каждом вызове wrapped[](..) клиентский код не указывал параметр типа. Это становится очень многословным.

Ответы [ 2 ]

3 голосов
/ 12 мая 2019

Просто создайте другой неявный класс и импортируйте необходимый

  object ioExt {
    implicit class IoExt[L, R](val io: IO[R]) extends AnyVal {
      def wrapped(errorCode: String): IO[Either[ProcessingResult[L], R]] = ???
    }
  }

  object ioExtLocal { 
    implicit class IoExtLocal[R](val io: IO[R]) extends AnyVal {
      def wrapped(errorCode: String): IO[Either[ProcessingResult[String], R]] = 
        (io: ioExt.IoExt[String, R]).wrapped(errorCode)
    }
  }

  import ioExtLocal._

  trait SomeR
  val x: IO[SomeR] = ???
  x.wrapped(???)
1 голос
/ 12 мая 2019

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

trait IoExtTrait[L, R] extends Any {

  protected def io: IO[R]

  def wrapped(errorCode: String): IO[Either[ProcessingResult[L], R]] =
    io.attempt.map(_.leftMap(ex ⇒ FailureMsg[L](errorCode, Some(ex))))

  def wrappedT(errorCode: String): EitherT[IO, ProcessingResult[L], R] =
    EitherT(wrapped(errorCode))
}

implicit class IoExtLocalString[R](protected val io: IO[R]) extends AnyVal with IoExtTrait[String, R] {
  override def wrapped(errorCode: String) = super.wrapped(errorCode)
}

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

implicit class IoExtLocalString[R](protected val io: IO[R]) extends AnyVal with IoExtTrait[String, R] {}

Если кто-нибудь знает, почему это происходит, пожалуйста, дайте мне знать. Я на Scala 2.12.8 (такое же поведение с 2.13-RC1).

Дальнейший разговор по телефону https://github.com/scala/bug/issues/11526 подтвердил, что распределение происходит в обоих случаях. Жаль.

...