Scala 隐式转换问题
Issue with Scala Implicit Conversions
在下面的代码摘录中,最后一条语句无法编译。但是,紧接在该语句之前的语句实际上可以编译。这个倒数第二个语句是我希望编译器将最后一个语句转换为的内容。我不明白为什么它不起作用。感谢任何帮助。
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
将方法隐式转换为 A => C
是有问题的,因为编译器无法轻松枚举 all 可能的 类 C
具有预期的方法 +
,然后去搜索 所有 可能的方法,这些方法采用 B
并给出 C
- 这个搜索将永远进行。
我建议避免为未知类型 C
使用类型 B => C
的隐式参数。如果你想要一个转换器,然后给它一些特定的名称,例如
trait Unwrap[A, B] extends (A => B)
然后您只能在此链式隐式中使用。
您可能会尝试的粗略描述:
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`)
在下面的代码摘录中,最后一条语句无法编译。但是,紧接在该语句之前的语句实际上可以编译。这个倒数第二个语句是我希望编译器将最后一个语句转换为的内容。我不明白为什么它不起作用。感谢任何帮助。
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
将方法隐式转换为 A => C
是有问题的,因为编译器无法轻松枚举 all 可能的 类 C
具有预期的方法 +
,然后去搜索 所有 可能的方法,这些方法采用 B
并给出 C
- 这个搜索将永远进行。
我建议避免为未知类型 C
使用类型 B => C
的隐式参数。如果你想要一个转换器,然后给它一些特定的名称,例如
trait Unwrap[A, B] extends (A => B)
然后您只能在此链式隐式中使用。
您可能会尝试的粗略描述:
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`)