您可以执行此操作以将隐式转换转换为链:
package language
object chainedImplicits {
implicit def chainImplicits[A, B, C](a: A)(implicit conv1: A => B, conv2: B => C): C = conv2(conv1(a))
}
但这显然不安全。
我看不出这个版本有什么问题,但是:
package language
package chainedImplicits {
final class Chained[A, B] private[chainedImplicits] (val f: A => B)
trait Low { this: `package`.type =>
implicit def startChaining(implicit conv: A => B): Chained[A, B] = new Chained[A, B](conv)
implicit def chainImplicits[A, B, C](implicit conv1: Chained[A, B], conv2: B => C): Chained[B, C] = new Chained(conv1.f andThen conv2)
}
}
package object chainedImplicits extends Low {
implicit def endChain[A, B](a: A)(implicit conv: Chained[A, B]): B = conv.f(a)
}
这里有捕获吗?
答案 0 :(得分:0)
首先,我无法得到你的第一个“显然不安全”的例子:
import language.implicitConversions
object Test {
implicit def chain[A, B, C](a: A)(implicit ab: A => B, bc: B => C): C = bc(ab(a))
case class X()
case class Y()
case class Z()
implicit def xy(x: X) = Y()
implicit def yz(y: Y) = Z()
val z: Z = X()
}
...
type mismatch;
found : Test.X
required: Test.Z
val z: Z = X()
^
接下来,第二个例子中明显的“捕获”是它不能编译。你真的尝试过吗?无论如何,在“修复”它之后,它仍然没有做你想要的:
import language.implicitConversions
class Convert[A, B](val convert: A => B) extends AnyVal
trait Convert0 {
implicit def convert[A, B](implicit ab: A => B): Convert[A, B] = new Convert(ab)
implicit def convert[A, B, C](implicit ab: Convert[A, B], bc: B => C): Convert[A, C] = new Convert(ab.convert andThen bc)
}
object Convert extends Convert0 {
implicit def convert[A, B](a: A)(implicit convert: Convert[A, B]): B = convert.convert(a)
}
object Test {
case class X()
case class Y()
case class Z()
implicit def xy(x: X) = Y()
implicit def yz(y: Y) = Z()
val z: Z = X()
}
这会产生相同类型的不匹配错误。据我所知,如果你想要隐式转换链接,你必须明确它:
import language.implicitConversions
object test {
case class X()
case class Y()
case class Z()
// anything convertible to X is convertible to Y
implicit def xy[A <% X](x: A) = Y()
// anything convertible to Y is convertible to Z
implicit def yz[B <% Y](y: B) = Z()
val z: Z = X()
}