作者PkmX (阿猫)
看板PLT
标题Re: [问题] scala 的 <:<
时间Tue Jan 22 20:22:41 2013
※ 引述《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)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.113.235.102
※ 编辑: PkmX 来自: 140.113.235.102 (01/22 20:23)
1F:推 mRiver:了解,非常感谢 01/22 20:37
2F:推 coolcomm:推 学到一招 01/22 23:27