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