简体   繁体   English

从子类型到零类型的默认类型转换,零参数函数

[英]default type conversions from sub to supertype, zero parameter functions

I am trying to understand the mechanism with which scala implements default type converions from sub to super type in scala.Predef. 我试图了解scala在scala.Predef中实现从子类型到超类型的默认类型转换的机制。 From the literature I gathered that this is done with the function 从文献中我收集到,这是通过函数完成的

implicit def conforms[A] = new A<:<A { def apply(a:A)=a }

The parameterless function conforms[A] returns the implicit conversion A=>B as its only function value (as a callable of type A=>A and thus of type A=>B, whenver A<:B). 无参数函数conforms [A]返回隐式转换A => B作为其唯一函数值(无论何时A <:B,都作为A => A类型的可调用对象,因此也就成为A => B类型的可调用对象)。

However when the compiler looks for an implicit type conversion it needs an implicit value of type A=>B not a function returning such a value. 但是,当编译器寻找隐式类型转换时,它需要类型A => B的隐式值,而不是返回此类值的函数。 Thus my question: 因此,我的问题是:

When looking for a default type conversion from A=>B, where A<:B, how does the compiler get from the function conforms[A] to its unique value. 当从A => B(其中A <:B)寻找默认类型转换时,编译器如何从函数中获取符合其唯一值的[A]。

The implicit resolution seeks for subtypes too, A <: B => A => A <: A => B , as in List[Int] <: Seq[Int] . 隐式解析也在寻找子类型,如List[Int] <: Seq[Int]A <: B => A => A <: A => B

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

So when making type conversion we look for A => B with A <: B , and A => A fits. 因此,在进行类型转换时,我们寻找A => BA <: B ,并且A => A适合。


I'm not sure if I understood you right, but the defs are followed while searching for value of the needed type. 我不确定我是否理解正确,但是在搜索所需类型的值时会遵循defs It doesn't matter whether function takes zero, one, or more parameters. 函数是否接受零,一个或多个参数都没有关系。 For example with zero: 例如,零:

implicit def implicitList[A]: List[A] = List() //the only obvious case
scala> implicitly[Seq[Int]]
// res0: Seq[Int] = List()

Or two: 或两个:

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)

If we add any of: 如果我们添加以下任何一项:

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")

We make implicit resolution undecidable for Quux : 我们使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]
                    ^

Ie there could be only one def or val in scope returning the type we are interested. 即范围内可能只有一个defval 返回我们感兴趣的类型。 And that is easy to verify statically. 这很容易进行静态验证。

But they will work if any of those is the only one in scope. 但是,只要其中任何一个在范围内,它们都将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM