Higher-Kinded 存在类型

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 = { }

这里有一个错误

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

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

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)

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