Re: [问题] scala 的 <:<

楼主: PkmX (阿猫)   2013-01-22 20:22:41
※ 引述《mRiver (月河)》之铭言:
: 请问 scala 的 <:< 是怎么工作的?
: 我看 scala in depth 里面 P.157 的 peek 范例,
: 无法理解编译器是如何提供 implicit 参述给 peek
: 编译器会自动推导 conforms 的参数吗?
: 谢谢
import Predef.{<:< => _, conforms => _, _}
sealed abstract class <:<[-From, +To] extends (From => To)
implicit def conforms[T]: T <:< T = new (T <:< T) {
def apply(x: T): T = x
}
case class Foo[A](a: A) {
def fn(implicit evidence: A <:< CharSequence) = a.length
}
scala> Foo("kerker").fn
res0: Int = 6
scala> Foo(1).fn
error: could not find implicit value for parameter evidence: <:<[Int,CharSequence]
Foo(1).fn
^
以上是简易版的<:<的定义,当我们呼叫Foo[A].fn时,
scala会想办法找一个type为A <:< CharSequence的implicit value,
假设我们呼叫:Foo("kerker").fn,这时候A的型态为String,
也就是要找型态为String <:< CharSequence的implicit value,
这里唯一eligible的只有conforms[T],型态为T <:< T,因此我们有:
T <:< T
String <:< CharSequence
这时候有两个可能:[T = String] or [T = CharSequence]
T = String
conforms[String]是一个可被视为type为String <:< String的implicit value,
由于<:<中定义第二个参数To为covariant,
所以String <:< String也是一个String <:< CharSequence,
这样compiler就找到A <:< CharSequence存在的证据(evidence)了
T = CharSequence
conforms[CharSequence]可被视为type为CharSequence <:< CharSequence,
而<:<定义From为Contravariant,
所以CharSequence <: CharSequence也可当作String <:< CharSequence用,
这样两个方式都能成功,不过基本上compiler只要找到任意一个就可以了
然后因为<:< extends =>,相当于提供一个implicit conversion,
所以在fn里面就可以把a当作CharSequence来用,也就可以呼叫a.length
希望这样解释你能理解
(附录:<:< in Predef.scala http://goo.gl/qyBQa)
作者: mRiver (等 一 个 晴 天 .)   2013-01-22 20:37:00
了解,非常感谢
作者: coolcomm (coolcomm)   2013-01-22 23:27:00
推 学到一招

Links booklink

Contact Us: admin [ a t ] ucptt.com