【问题标题】:Scala: higher-kinded types, type projections and type mismatch errorScala:更高种类的类型、类型投影和类型不匹配错误
【发布时间】:2013-06-08 08:01:34
【问题描述】:

我有以下代码:

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?

【问题讨论】:

  • 第一个代码块没有编译,TransM 中的方法from 定义了错误的签名。
  • 为什么TransM需要B &lt;: M[X]的具体类型? M[X] 不够吗?

标签: scala type-systems higher-kinded-types type-projection


【解决方案1】:

@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)

您可以考虑对TransCurriedTrans 执行相同的操作。如果你需要M的内部类型,你总是可以通过TransCurriedTrans的类型成员来暴露它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 2015-04-30
    • 2020-10-02
    • 2018-12-09
    相关资源
    最近更新 更多