是否可以定义部分参数化的通用隐式类?例如,假设我有以下课程
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[](..)
的客户端代码都不必指定类型参数。它变得非常冗长。
答案 0 :(得分:3)
只需创建另一个隐式类并导入必要的类
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 :(得分:1)
尝试了多种解决方案后,我发现以下操作无需每次调用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处的进一步交谈确认,两种情况都发生了分配。太糟糕了。