如何定义部分参数化泛型隐式class?
How to define partially parameterize generic implicit class?
是否可以定义部分参数化泛型隐式 class?例如假设我有以下 class
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]
作为隐式可用 class ?
这样做的目的是让客户端代码无需在每次调用 wrapped[](..)
时指定类型参数。它变得非常冗长。
只需创建另一个隐式 class 并导入必要的
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(???)
在尝试了多种解决方案后,我发现在每次调用 wrapped
时,无需实例化助手 class 即可完成以下工作
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)
}
另一方面,在每次调用时都会实例化助手 class
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 的进一步对话证实了两种情况都发生了分配。太可惜了。
是否可以定义部分参数化泛型隐式 class?例如假设我有以下 class
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]
作为隐式可用 class ?
这样做的目的是让客户端代码无需在每次调用 wrapped[](..)
时指定类型参数。它变得非常冗长。
只需创建另一个隐式 class 并导入必要的
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(???)
在尝试了多种解决方案后,我发现在每次调用 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)
}
另一方面,在每次调用时都会实例化助手 class
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 的进一步对话证实了两种情况都发生了分配。太可惜了。