我想定义一个由上限R
和更高种类的类型构造函数参数化的特征,该构造函数F[_]
只接受R
. 我希望这个 trait 实现一个apply
可以将任何F[A]
转换为 的多态Unit
,前提是A <: R
.
这段代码工作得很好:
import scala.language.higherKinds
// this is the trait with polymorphic `apply`
trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}
// Example:
sealed trait Domain
class Dom1 extends Domain
class Fnctr[X <: Domain]
val c = new CoCone[Domain, Fnctr] {
def apply[D <: Domain](x: Fnctr[D]): Unit = ()
}
(见下文关于命名的备注)
R
现在,如果我通过将其声明为某个模块的类型成员来抽象它,并Fnctr[A <: R]
在该模块中定义,如下所示:
import scala.language.higherKinds
trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}
trait ModuleIntf {
type AbstractDomain
class Fnctr[X <: AbstractDomain]
}
// No mention of an actual concrete `Domain` up to
// this point. Now let's try to implement a concrete
// implementation of `ModuleIntf`:
sealed trait Domain
class Dom1 extends Domain
object ModuleImpl extends ModuleIntf {
type AbstractDomain = Domain
val c = new CoCone[Domain, Fnctr] { // error [1], error [2]
def apply[D <: Domain](x: Fnctr[D]): Unit = ()
}
}
一切都中断了,我收到两条我不知道如何解释的错误消息:
[1] error: kinds of the type arguments (Domain,Main.$anon.ModuleImpl.Fnctr) do not
conform to the expected kinds of the type parameters (type R,type F) in trait CoCone.
Main.$anon.ModuleImpl.Fnctr's type parameters do not match type F's expected parameters:
type X's bounds <: ModuleIntf.this.AbstractDomain are stricter than type _'s declared bounds <: R
val c = new CoCone[Domain, Fnctr] {
^
[2] error: kinds of the type arguments (Domain,Main.$anon.ModuleImpl.Fnctr) do not
conform to the expected kinds of the type parameters (type R,type F) in trait CoCone.
Main.$anon.ModuleImpl.Fnctr's type parameters do not match type F's expected parameters:
type X's bounds <: ModuleIntf.this.AbstractDomain are stricter than type _'s declared bounds <: R
val c = new CoCone[Domain, Fnctr] {
^
我希望编译器能够识别出这三个内部ModuleImpl
都是相同的类型。CoCone[Domain, Fnctr]
Domain = AbstractDomain = R
我在这里遗漏了一些明显的东西,还是scalac
2.12.4 的限制?如果这是一个限制,有人曾经在任何地方报告过吗?
编辑发现类似的东西:问题#10186。是“一样的”吗?不一样”?如果它是一个错误,我应该将它作为另一个测试用例提出吗?如果有人可以确认这不完全是我的错,和/或它确实与相关问题密切相关,那将是问题的可接受解决方案。
Edit2:正如@Evgeny 指出的那样,它不能完全是问题10186,因为它在不同的编译器阶段(refchecks
而不是typer
)失败。
关于名称的备注:我在CoCone
这里将特征称为特征,类似于通常定义~>
的可以被视为自然转换的定义。在某种程度上,CoCone[Dom, Fctr]
类似于Fctr ~> Const_Unit
,但域F
仅限于 的子类型Dom
。实际上,它是可以通过网络发送某些子类CoCone[R, F]
的形状的东西,但这并不重要,所以我已经抽象了名称。这东西是一个比较普通的数学结构,没什么做作的,如果能编译出来就好了。F
R