在类型细化中使用类型构造函数

时间:2020-10-28 10:21:55

标签: scala typeclass

我遇到的一个问题可能最好用代码表达-下面是一个简化的示例:

abstract class MainTC[A] {
  type E
  // A type constructor for the implementing type:
  type CN[_]  
  implicit val ev: CN[A] =:= A  // check that CN works as a type constructor for A
  def get(self: A): E
  def set[B](self: A, other: B): CN[B] { type E = B }
  def convert[B](self: A)(implicit conv: Convert[A, E, B]) = conv.convert(self)(this)
}

abstract class Convert[A, _E, B] {
  type Out
  def convert(self: A)(implicit isMain: MainTC[A] { type E = _E }): Out 
}
object Convert {
  implicit def convertDoubleToInt[A, _CN[_]](implicit 
    isMain: MainTC[A] { type E = Double; type CN[_] = _CN[_] },
  ): Convert[A, Double, Int] = new Convert[A, Double, Int] {
    type Out = _CN[Int] { type E = Int }
    def convert(self: A): Out = {
      val toInt = isMain.get(self).toInt
      isMain.set[Int](self, toInt)
      // type mismatch - 
      // found: isMain.CN[Int]{type E = Int} (which expands to) _CN[_]{type E = Int}
      // required: this.Out (which expands to) _CN[Int] {type E = Int}
    }
  }
}

这里的基本情况非​​常简单-我正在使用类型类来实现多态convert函数。棘手的部分是我将类型构造函数作为抽象类型存储在MainTC类型类中。在转换Convert类型类时,我想使用该类型构造函数创建一个新类型作为输出类型(例如CN[Int])。我正在尝试使用类似Aux模式的方法来实现此目的,其中_CN[_]被创建为isMain.CN[_]的类型别名。但是,它不起作用(代码中的错误消息)。如果有人可以帮助我,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

您是指type CN[_] = _CN[_]还是type CN[X] = CN[X]?如果将其更改为后者,则会遇到以下问题

def convert(self: A): Out

无法实现

def convert(self: A)(implicit isMain: MainTC[A] { type E = _E }): Out

因为它缺少隐式参数。请记住,Scala隐式不一定必须是连贯的:convertDoubleToInt的{​​{1}}与(isMain: MainTC[A] {type E = _ E}).TC的{​​{1}}

不同