从子类型到超类型的默认类型转换,零参数函数
default type conversions from sub to supertype, zero parameter functions
我试图了解 scala 在 scala.Predef 中实现从子类型到超类型的默认类型转换的机制。从我收集到的文献中,这是通过函数
完成的
implicit def conforms[A] = new A<:<A { def apply(a:A)=a }
无参数函数符合[A] returns隐式转换A=>B作为其唯一
函数值(作为类型 A=>A 的可调用对象,因此类型为 A=>B,只要 A<:B)。
然而,当编译器查找隐式类型转换时,它需要一个隐式值
类型 A=>B 不是返回此类值的函数。因此我的问题是:
当从 A=>B 寻找默认类型转换时,其中 A<:B,编译器如何
从函数 conforms[A] 得到它的唯一值。
隐式解析也会寻找子类型,A <: B
=> A => A <: A => B
,如 List[Int] <: Seq[Int]
.
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit val x: List[Int] = List(1, 2, 3)
def f(implicit x: Seq[Int]): Int = x.head
f
// Exiting paste mode, now interpreting.
x: Seq[Int] = List(1, 2, 3)
f: (implicit x: Seq[Int])Int
res1: Int = 1
所以在进行类型转换时,我们寻找 A => B
和 A <: B
,并且 A => A
适合。
我不确定我是否理解正确,但是在搜索所需类型的值时会遵循 defs
。函数是否采用零个、一个或多个参数并不重要。例如零:
implicit def implicitList[A]: List[A] = List() //the only obvious case
scala> implicitly[Seq[Int]]
// res0: Seq[Int] = List()
或两个:
case class Foo(str: String)
case class Bar(str: String)
case class Quux(str: String)
implicit val foo = Foo("foo")
implicit val bar = Bar("bar")
// how to build quux:
implicit def quux(implicit foo: Foo, bar: Bar): Quux = Quux(foo.str + bar.str)
implicitly[Quux]
// res2: Quux = Quux(foobar)
如果我们添加以下任何一项:
implicit def quux2(implicit quux: Quux): Quux = quux
implicit def quux3(implicit foo: Foo): Quux = Quux(foo.str)
implicit val quux4: Quux = Quux("quux")
implicit def quux5[A]: Quux = Quux("poly")
我们使 Quux
的隐式解析不可判定:
scala> implicitly[Quux]
<console>:29: error: ambiguous implicit values:
both method quux of type (implicit foo: Foo, implicit bar: Bar)Quux
and method quux2 of type (implicit quux: Quux)Quux
match expected type Quux
implicitly[Quux]
^
即在范围 中可能只有一个 def
或 val
返回 我们感兴趣的类型。这很容易静态验证。
但如果范围内只有其中任何一个,它们就会起作用。
我试图了解 scala 在 scala.Predef 中实现从子类型到超类型的默认类型转换的机制。从我收集到的文献中,这是通过函数
完成的implicit def conforms[A] = new A<:<A { def apply(a:A)=a }
无参数函数符合[A] returns隐式转换A=>B作为其唯一 函数值(作为类型 A=>A 的可调用对象,因此类型为 A=>B,只要 A<:B)。
然而,当编译器查找隐式类型转换时,它需要一个隐式值 类型 A=>B 不是返回此类值的函数。因此我的问题是:
当从 A=>B 寻找默认类型转换时,其中 A<:B,编译器如何 从函数 conforms[A] 得到它的唯一值。
隐式解析也会寻找子类型,A <: B
=> A => A <: A => B
,如 List[Int] <: Seq[Int]
.
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit val x: List[Int] = List(1, 2, 3)
def f(implicit x: Seq[Int]): Int = x.head
f
// Exiting paste mode, now interpreting.
x: Seq[Int] = List(1, 2, 3)
f: (implicit x: Seq[Int])Int
res1: Int = 1
所以在进行类型转换时,我们寻找 A => B
和 A <: B
,并且 A => A
适合。
我不确定我是否理解正确,但是在搜索所需类型的值时会遵循 defs
。函数是否采用零个、一个或多个参数并不重要。例如零:
implicit def implicitList[A]: List[A] = List() //the only obvious case
scala> implicitly[Seq[Int]]
// res0: Seq[Int] = List()
或两个:
case class Foo(str: String)
case class Bar(str: String)
case class Quux(str: String)
implicit val foo = Foo("foo")
implicit val bar = Bar("bar")
// how to build quux:
implicit def quux(implicit foo: Foo, bar: Bar): Quux = Quux(foo.str + bar.str)
implicitly[Quux]
// res2: Quux = Quux(foobar)
如果我们添加以下任何一项:
implicit def quux2(implicit quux: Quux): Quux = quux
implicit def quux3(implicit foo: Foo): Quux = Quux(foo.str)
implicit val quux4: Quux = Quux("quux")
implicit def quux5[A]: Quux = Quux("poly")
我们使 Quux
的隐式解析不可判定:
scala> implicitly[Quux]
<console>:29: error: ambiguous implicit values:
both method quux of type (implicit foo: Foo, implicit bar: Bar)Quux
and method quux2 of type (implicit quux: Quux)Quux
match expected type Quux
implicitly[Quux]
^
即在范围 中可能只有一个 def
或 val
返回 我们感兴趣的类型。这很容易静态验证。
但如果范围内只有其中任何一个,它们就会起作用。