Type class pattern in Scala doesn't consider inheritance?

岁酱吖の 提交于 2019-11-30 19:35:39

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]

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]

The following works fine:

scala> def call[X](x: X)(implicit evidence: T[X]<:<T[X])  = println(x)
call: [X](x: X)(implicit evidence: <:<[T[X],T[X]])Unit

scala> call(new A)
line0$object$$iw$$iw$A@1d869b2

scala> call(new B)
line2$object$$iw$$iw$B@b3a5d1

scala> val b = new B
b: B = B@30e4a7

scala> call(b)
line2$object$$iw$$iw$B@30e4a7

In your case compilation fails, because def call[X:T](x:X) = println(x) is treated as call: [X](x: X)(implicit evidence$1: T[X])Unit. In order to pass the subtype, you may use generalized type constraints.

Try this:

object T {
  implicit def TA[X <: A] = new T[X]
}

import T._

or simply:

implicit def TA[X <: A] = new T[X]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!