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

时间:2015-01-14 14:35:56

标签: scala types

我试图理解scala在scala.Predef中实现从sub到super类型的默认类型转换的机制。从文献中我收集到这是通过函数

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

无参数函数conforms [A]仅返回隐式转换A =&gt; B. 函数值(作为类型A =&gt; A的可调用类型,因此类型A =&gt; B,当A&lt;:B时)。

但是,当编译器查找隐式类型转换时,它需要一个隐式值 类型A => B的类型不是返回这样的值的函数。因此我的问题是:

从A =&gt; B中寻找默认类型转换时,其中A&lt;:B,编译器如何 从函数中获取符合[A]到其唯一值。

1 个答案:

答案 0 :(得分:1)

隐式解决方案也寻求子类型,A <: B =&gt; 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 <: BA => 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]
                    ^

即。范围中只有一个defval可以返回我们感兴趣的类型。这很容易静态验证。

但是如果其中任何一个是范围内唯一的那个,它们就会起作用。