Scala中的类型模式不考虑继承? [英] Type class pattern in Scala doesn't consider inheritance?

查看:134
本文介绍了Scala中的类型模式不考虑继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am designing an API using type classes in some cases however I have encountered a problem with implicit resolution. As shown below, if there is an implicit object for type A but an object of type B extends A is passed to the method, then an implicit object cannot be found. Is there a way to make this work or do callers have to put implicit objects into scope for each subclass?

这是一个例子:

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)

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

This fails to compile with the following output:


/private/tmp/tc.scala:16: error: could not find implicit value for evidence parameter of type this.T[this.B]
call(new B)
    ^
/private/tmp/tc.scala:28: error: could not find implicit value for evidence parameter of type this.T[this.B]
call(b)


推荐答案

呼叫呼叫(新B)表示呼叫[B](新B)(tB)这样tb是T [B]类型或它的子类。 (期望类型T的参数只能期望T的T或子类的方法,例如 def foo(s:String)不能使用类型<$ c的参数调用$ C>任何)。 T [A]不是T [B]的子类型

The call call(new B) means call[B](new B)(tB) such that tb is of type T[B] or subclass of it. (A method that expects argument of type T can only expect T or subclass of T, e.g., def foo(s: String) cannot be called with argument of type Any). T[A] is not a subtype of T[B]

要修复,您可以将T更改为 T [-X] 。这意味着编译器会将T [A]视为T [B]

To fix, you can change T to be defined T[-X]. This means that the compiler will consider T[A] to be a subtype of T[B]

这篇关于Scala中的类型模式不考虑继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆