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

标签 scala

我正在研究 scala 的类型级编程并对其有所了解。但我不知道为什么 class <:< 需要从 (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)

所以我的问题是 class <:< 的设计决定是什么?为什么它需要扩展 From => To ?

最佳答案

因为那样implicit ev: T <:< U也作为 T 的隐式转换至 U可以自动向上转换任何类型的值 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 的一个实例(即它的类型 T 是类型 U 的子类型)您很可能希望将该值用作 U 的实例。 ,否则你为什么首先需要证明?如 <:<是一个您可以自动执行此操作的功能。

关于scala - 为什么 class < :<[-From, +To] 需要在 Scala 标准库中扩展 (From => To)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129643/

相关文章:

regex - scala 模式与正则表达式lookbehind 运算符匹配

scala - 如何确定scala模块是否作为脚本运行

scala - 为什么删除后 "Banana with Cream"和 "Banana"的类型一样?如何修复?

Scala foreach 成员变量

scala - 如何强制 SBT 始终获取项目依赖项的源?

scala - 使用 Witness 提取类型标签

scala - 使用 scala Array.fill 中的 NPE

scala - 如何使用 bndtools 通过 Scala 创建 OSGi 包?

scala - IntelliJ 似乎没有选择某些 sbt 库,没有代码完成

forms - PlayFramework 2.x - 将错误消息形成/关联到元组的一个元素