[英]Higher-Kinded existential type
我一直在考慮我正在研究的庫中的設計問題,並且我意識到使用存在類型可能允許我以簡化庫的許多部分的方式更改我的設計。 但是,我似乎無法讓它發揮作用。
在我看來, myBuilder
符合類型MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }
,其中Element[X]
是MultiSignalElement[X]
,但編譯器說它確實'噸。 似乎必須要做的事實是E是一種更高級的類型。 為什么這不起作用,有沒有辦法解決它?
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
讓我們一步一步的分析。
首先我們有
def transform[R](builder : MultiSignalBuilder[E, R] forSome { type E[+X] >: Element[X] }) : Unit = { }
這相當於聲明:存在
type E[+X] >: Element[X]
我們可以為此定義
def transform[E[+X] >: Element[X], R[+_]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
這里我們有一個錯誤
錯誤:(7,18)協變類型X出現在類型[+ X]>的逆變位置:E類型的MultiSignal.this.Element [X]
這是事情。 你期待你的神秘的存在協變類型應該是另一種協變類型的超類型。 我認為這是第一件讓編譯器嚇壞的事情。 讓我們改變與子類型的關系
def transform[E[+X] <: Element[X], R[+_]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
現在我們有
錯誤:(7,56)類型參數[E,R]不符合類MultiSignalBuilder的類型參數邊界[-E [+ X] <:MultiSignalElement [X],+ R [+ X] <:MultiSignal [X]]
所以我們忘了要求從R
參數中對MultiSignal[X]
進行子類型化。
讓我們改變它
def transform[E[+X] <: Element[X], R[+X] <: MultiSignal[X]](builder : MultiSignalBuilder[E, R] ) : Unit = { }
現在
multiSignal.transform[MultiSignalElement,MultiSignal](myBuilder)
是成功編譯的。
最后我們可以回到存在主義版本
def transform[R[+X] <: MultiSignal[X]](builder : MultiSignalBuilder[E, R] forSome {type E[+X] <: Element[X]}) : Unit = { }
用哪個
multiSignal.transform[MultiSignal](myBuilder)
是成功編譯的。
可悲的是
multiSignal.transform(myBuilder)
仍然沒有編譯。 我認為編譯器需要解決太多的類型關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.