[英]Higher-Kinded existential type
I've been mulling over a design problem in a library I'm working on, and I realized that using existential types may allow me to change my design in a way that simplifies many parts of my library. 我一直在考虑我正在研究的库中的设计问题,并且我意识到使用存在类型可能允许我以简化库的许多部分的方式更改我的设计。 However, I can't quite seem to get it to work.
但是,我似乎无法让它发挥作用。
It seems to me that myBuilder
conforms to the type MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }
, where Element[X]
is MultiSignalElement[X]
, but the compiler says it does't. 在我看来,
myBuilder
符合类型MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }
,其中Element[X]
是MultiSignalElement[X]
,但编译器说它确实'吨。 It seems to have to do the fact that E is a higher-kinded type. 似乎必须要做的事实是E是一种更高级的类型。 Why doesn't this work, and is there a way to fix it?
为什么这不起作用,有没有办法解决它?
class MultiSignalElement[+T] {
}
abstract class MultiSignal[+T] {
type Element[+X] <: MultiSignalElement[X]
val element : Element[T]
def transform[R[+X] <: MultiSignal[X]](builder : MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }) : R[T] =
builder.buildNew(element)
}
abstract class MultiSignalBuilder[-E[+X] <: MultiSignalElement[X], +R[+X] <: MultiSignal[X]] {
def buildNew[T](element : E[T]) : R[T]
}
object myBuilder extends MultiSignalBuilder[MultiSignalElement, MultiSignal] {
def buildNew[T](e : MultiSignalElement[T]) = new MultiSignal[T]() {
type Element[+X] = MultiSignalElement[X]
val element = e
}
}
val multiSignal = new MultiSignal[Int] {
type Element[+X] = MultiSignalElement[X]
val element = new MultiSignalElement()
}
multiSignal.transform(myBuilder) //type error on this line
multiSignal.transform[MultiSignal](myBuilder) //type error on this line
Let do step-by-step analysis. 让我们一步一步的分析。
First we have 首先我们有
def transform[R](builder : MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }) : Unit = { }
Which is equivalent to statement : there exists 这相当于声明:存在
type E[+X] >: Element[X]
For which we can define 我们可以为此定义
def transform[E[+X] >: Element[X], R[+_]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
Here we have an error 这里我们有一个错误
Error:(7, 18) covariant type X occurs in contravariant position in type [+X] >: MultiSignal.this.Element[X] of type E
错误:(7,18)协变类型X出现在类型[+ X]>的逆变位置:E类型的MultiSignal.this.Element [X]
This is something. 这是事情。 You are expecting your mysterious existential covariant type should be a supertype of another covariant type.
你期待你的神秘的存在协变类型应该是另一种协变类型的超类型。 I think this is the first thing which is freaking the compiler.
我认为这是第一件让编译器吓坏的事情。 Lets change relation to subtyping
让我们改变与子类型的关系
def transform[E[+X] <: Element[X], R[+_]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
Now we have 现在我们有
Error:(7, 56) type arguments [E,R] do not conform to class MultiSignalBuilder's type parameter bounds [-E[+X] <: MultiSignalElement[X],+R[+X] <: MultiSignal[X]]
错误:(7,56)类型参数[E,R]不符合类MultiSignalBuilder的类型参数边界[-E [+ X] <:MultiSignalElement [X],+ R [+ X] <:MultiSignal [X]]
So we forgot to require subtyping of MultiSignal[X]
out of R
parameter. 所以我们忘了要求从
R
参数中对MultiSignal[X]
进行子类型化。
Lets change it 让我们改变它
def transform[E[+X] <: Element[X], R[+X] <: MultiSignal[X]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
Now 现在
multiSignal.transform[MultiSignalElement,MultiSignal](myBuilder)
Is succesfully compiled. 是成功编译的。
Finally we could get back to existential version 最后我们可以回到存在主义版本
def transform[R[+X] <: MultiSignal[X]](builder : MultiSignalBuilder[E, R] forSome {type E[+X] <: Element[X]}) : Unit = { }
With which 用哪个
multiSignal.transform[MultiSignal](myBuilder)
Is succesfully compiled. 是成功编译的。
Sadly 可悲的是
multiSignal.transform(myBuilder)
Still is not compiled. 仍然没有编译。 I think there is too much type relations to resolve for the compiler.
我认为编译器需要解决太多的类型关系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.