为什么class<:< [ - From,+ To]需要在scala标准库中扩展(From => To)?

时间:2017-05-23 08:28:33

标签: scala

我正在研究scala的类型级编程并且对它有一些了解。但我不知道为什么类<:<需要从(From => To)扩展,我在REPL中编写了以下代码。

trait <:<[-T, +U] // just 'plain' generic trait

// an implicit object will looked up by compiler
implicit def implicitAgent[A]: <:<[A, A] = new <:<[A,A] {}

def myFunc[T,U](one:T, two:U)(implicit ev: T <:< U): Unit = {
    println(one, two)

class Base {
    override def toString: String = "base"
}

class Derived extends Base {
    override def toString: String = "Derived"
}

myFunc(new Derived, new Base)

它可以工作和打印:

(Derived,base)

所以我的问题是什么是类&lt;:&lt;的设计决定?为什么它需要扩展From =&gt;到?

1 个答案:

答案 0 :(得分:7)

因为这种方式implicit ev: T <:< U也可以作为从TU的隐式转换,可以自动将类型T的任何值转发为U类型。

<:<中定义Predef

scala> trait Foo
defined trait Foo

scala> def myFunc[T](t: T)(implicit ev: T <:< Foo): Foo = t
myFunc: [T](t: T)(implicit ev: T <:< Foo)Foo

使用<:<

scala> trait <:<[-T, +U]
defined trait $less$colon$less

scala> implicit def implicitAgent[A]: <:<[A, A] = new <:<[A,A] {}
implicitAgent: [A]=> A <:< A

scala> def myFunc[T](t: T)(implicit ev: T <:< Foo): Foo = t
<console>:14: error: type mismatch;
 found   : T
 required: Foo
       def myFunc[T](t: T)(implicit ev: T <:< Foo): Foo = t
                                                          ^

一旦证明某个值是U的实例(即其类型TU类型的子类型),您很可能会想要使用该值作为U的实例,否则为什么首先需要证明?如果<:<是一个功能,您可以自动执行此操作。