[英]Scala: higher-kinded types, type projections and type mismatch error
我有以下代码:
trait M[Type[_]]{
type T[X] = Type[X]
def from[A](f: T[A]): A
}
class ListM extends M[List]{ def from[A](f: T[A]) = f.head }
class Trans[A, X[_], B <: M[X]](val r: X[Option[A]])
trait CurriedTrans[X[_], B <: M[X]]{ type Type[A] = Trans[A, X, B] }
class TransM[X[_], B <: M[X]](val b: B) extends M[CurriedTrans[X, B]#Type]{
def from[A] = (f: T[A]) => b.from(f.r).get
}
我可以通过两种方式实例化TransM类型的变量:
val x1 = new TransM[List, ListM](new ListM)
val x2 = new TransM[ListM#T, ListM](new ListM)
我认为ListM#T是冗余类型参数,所以我试图消除它:
trait M{
type T[X]
def from[A](f: T[A]): A
}
class ListM extends M {
type T[X] = List[X]
def from[A](f: T[A]) = f.head
}
class Trans[A, B <: M](val r: B#T[Option[A]])
class TransM[B <: M](val b: B) extends M {
type T[X] = Trans[X, B]
def from[Y] = (f: T[Y]) => b.from(f.r).get
}
实例化为
val x = new TransM[ListM](new ListM)
不幸的是,由于类型不匹配错误,无法编译第二个实现:
type mismatch;
found : f.r.type (with underlying type B#T[Option[Y]])
required: TransM.this.b.T[?]
def from[Y] = (f: T[Y]) => b.from(f.r).get
^
我可以解决此问题并简化代码,还是应该在各处编写样板ListM#T?
@ziggystar说:删除绑定的B
并直接使用M[X]
:
class TransM[X[_]](val b: M[X]) extends M[CurriedTrans[X, M[X]]#Type] {
def from[A](f: T[A]) = b.from(f.r).get
}
val x1 = new TransM(new ListM)
您可以考虑对Trans
和CurriedTrans
进行相同的CurriedTrans
。 如果需要M
的内部类型,则始终可以通过Trans
和CurriedTrans
的类型成员公开它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.