gpt4 book ai didi

scala - Higher-Kinded 存在类型

转载 作者:行者123 更新时间:2023-12-04 02:16:34 26 4
gpt4 key购买 nike

我一直在思考我正在处理的库中的一个设计问题,我意识到使用存在类型可能允许我以一种简化库的许多部分的方式更改我的设计。但是,我似乎无法让它正常工作。

在我看来,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 = { }

这里有一个错误

Error:(7, 18) covariant type X occurs in contravariant position in type [+X] >: MultiSignal.this.Element[X] of type E

这是一个东西。您期望您神秘的存在协变类型应该是另一个协变类型的父类(super class)型。我认为这是让编译器感到恐惧的第一件事。让我们改变与子类型的关系

def transform[E[+X] <: Element[X], R[+_]](builder : MultiSignalBuilder[E, R] ) : Unit = { }

现在我们有

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]]

所以我们忘了要求从 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)

仍然没有编译。我认为编译器需要解决的类型关系太多。

关于scala - Higher-Kinded 存在类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33390224/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com