问题:
trait UpperBound[O]
trait High[F[O] <: UpperBound[O]]
def canEqual(that :Any) = that.isInstanceOf[High[_]]
def high(h :High[_]) = ???
不编译,因为scalac看到的是_
类型,而不是它所期望的类型构造函数。如何在不写小说的情况下修复它?
最初的问题(在对德米特罗的回答进行编辑之前(是:
def canEqual(that :Any) = that.isInstanceOf[High[m forSome { type m[O] <: UpperBound[O] }]]
def high(h :High[m forSome { type m[O] <: UpperBound[O] }] = ???
有没有一种通过使用通配符表达式来编写上述两种方法的较短方法?简单地在High
的类型参数位置使用_
是不起作用的,因为类型不匹配,而且_[_]
甚至不是有效的类型表达式。
-
如果在
High
之外进行存在量化,那么它只是type T = High[F] forSome { type F[O] <: UpperBound[O] } def canEqual(that: Any) = that.isInstanceOf[T] def high(h: T) = ???
-
如果你在
High
内部进行存在量化,那么由于implicitly[(n forSome { type n <: Upper}) =:= Upper] implicitly[(m[O1] forSome { type m[O] <: UpperBound[O]}) =:= UpperBound[O1]]
(反之亦然(它只是
High[UpperBound]
implicitly[High[m forSome { type m[O] <: UpperBound[O] }] =:= High[UpperBound]] def canEqual(that: Any) = that.isInstanceOf[High[UpperBound]] def high(h: High[UpperBound]) = ???
其中
𝑄
包含子句类型𝑡[tps]>:𝐿<:𝑈
的存在类型𝑇 forSome { 𝑄 }
等价于其中𝑇′
通过用𝑈
替换𝑇
中𝑡
的每个协变出现和用𝐿
替换𝑇
中𝑡
的每个逆变出现而由𝑇
产生的类型𝑇′ forSome { 𝑄 }
。https://scala-lang.org/files/archive/spec/2.13/03-types.html#simplification-规则