inheritance - Scala 中的类型类模式不考虑继承?

标签 inheritance scala implicit typeclass

在某些情况下,我正在使用类型类设计 API,但是我遇到了隐式解析的问题。如下图,如果有类型A的隐式对象但类型为B extends A的对象传递给该方法,则无法找到隐式对象。有没有办法使这项工作或调用者必须将隐式对象放入每个子类的范围内?

下面是一个例子:

class A
class B extends A

class T[+X]

object T {
  implicit object TA extends T[A]
}

def call[X:T](x:X) = println(x)

// compiles
call(new A)
// doesn't compile
call(new B)

var a = new A
// compiles
call(a)

a = new B
// compiles
call(a)

val b = new B
// doesn't compile
call(b)

这无法使用以下输出进行编译:

/private/tmp/tc.scala:16: 错误:找不到 this.T[this.B] 类型的证据参数的隐式值
调用(新 B)
^
/private/tmp/tc.scala:28: 错误:找不到 this.T[this.B] 类型的证据参数的隐式值
电话(二)

最佳答案

来电call(new B)意味着 call[B](new B)(tB)这样 tb 是类型 T[B] 或其子类。 (需要类型为 T 的参数的方法只能需要 T 或 T 的子类,例如, def foo(s: String) 不能用类型为 Any 的参数调用)。 T[A] 不是 T[B] 的子类型

要修复,您可以更改要定义的 T T[-X] .这意味着编译器会将 T[A] 视为 T[B] 的子类型

关于inheritance - Scala 中的类型类模式不考虑继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3869991/

相关文章:

javascript - 如何使用 javascript 创建监听器

c++ - 重写的函数没有反射(reflect)在基类中,这是正常行为吗?

scala - 为什么 Map withDefaultValue 返回 Option = None

Scala:什么时候需要函数参数类型?

scala - 如何询问 Scala 是否存在所有类型参数实例化的证据?

scala - 将scala.math.Integral传递为隐式参数

swift - 使用默认值参数覆盖函数时,如何保持默认值与父类(super class)相同?

iOS 如何在不子类化所有内容的情况下为类引入具有 UDID 的能力?

Scala - 遍历两个数组

c++ - 隐式类型转换编译失败,这是为什么?