[英]Issue with Scala Implicit Conversions
In the below code excerpt, the last statement does not compile.在下面的代码摘录中,最后一条语句无法编译。 However, the statement immediately before that one does in fact compile.
但是,紧接在该语句之前的语句确实可以编译。 This second-to-last statement is what I would expect the compiler would convert the last statement to.
这个倒数第二个语句是我期望编译器将最后一个语句转换为的语句。 I do not understand why it does not work.
我不明白为什么它不起作用。 Any help is appreciated.
任何帮助表示赞赏。
trait ParameterizedBy[A, B] {
val parameterized: B
}
object ParameterizedBy {
implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
implicit f: B => C): C = f(p.parameterized)
}
trait Wraps[A] {
val wrapped: A
}
object Wraps {
implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}
val p = new ParameterizedBy[String, Wraps[Int]] {
override val parameterized: Wraps[Int] = new Wraps[Int] {
override val wrapped = 6
}
}
ParameterizedBy.toParameterized(p)(Wraps.toWrapped) + 5
p + 5
Implicitly converting a method into A => C
is problematic, because the compiler cannot easily enumerate all the possible classes C
that have the expected method +
, and then go and search all the possible methods which take B
and give C
- this search would take forever.将方法隐式转换为
A => C
是有问题的,因为编译器无法轻松枚举具有预期方法+
所有可能类C
,然后去搜索所有可能采用B
并给出C
- 这种搜索需要永远。
I'd suggest to avoid implicit arguments of type B => C
for unknown type C
.对于未知类型
C
我建议避免B => C
类型的隐式参数。 If you want a converter, then give it some specific name, eg如果你想要一个转换器,那么给它一些特定的名字,例如
trait Unwrap[A, B] extends (A => B)
that you then use only in this chained implicit.然后你只在这个链式隐式中使用。
A rough sketch of what you might try instead:您可能会尝试的粗略草图:
import scala.language.implicitConversions
trait ParameterizedBy[A, B] {
val parameterized: B
}
object ParameterizedBy {
implicit def toParameterized[A, B, C](p: ParameterizedBy[A, B])(
implicit f: Unwrap[B, C]): C = f(p.parameterized)
}
trait Wraps[A] {
val wrapped: A
}
object Wraps {
implicit def toWrapped[A](w: Wraps[A]): A = w.wrapped
}
trait Unwrap[A, B] extends (A => B)
object Unwrap {
implicit def unwrap[A]: Unwrap[Wraps[A], A] = new Unwrap[Wraps[A], A] {
def apply(w: Wraps[A]): A = w.wrapped
}
}
val p = new ParameterizedBy[String, Wraps[Int]] {
override val parameterized: Wraps[Int] = new Wraps[Int] {
override val wrapped = 6
}
}
p - 5 // works
(p: Int) + 5 // works with type ascription (to avoid conflicts with `+ String`)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.