【问题标题】:Using a type constructor in a type refinement在类型细化中使用类型构造函数
【发布时间】:2020-10-28 20:25:25
【问题描述】:

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

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[_] 的类型别名。但是,它不起作用(代码中的错误消息)。如果有人能帮我一把,我将不胜感激。

【问题讨论】:

    标签: scala typeclass


    【解决方案1】:

    您是指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(isMain: MainTC[A] {type E = _ E}).TCconvert(isMain: MainTC[A] {type E = _ E}).TC 不同

    【讨论】:

    • 感谢您的回复。我正在使用type CN[_] = _CN [_] 细化来实际设置isMainTC.CN[],而是将_CN[] 设置为它的别名,以便我可以使用CN[ i>] 在其他隐式参数中。类似于Aux 模式。
    • 双重检查:你的意思是说类型构造函数CN[_]是所有类型的通配符类型_CN[_]的类型构造函数?也就是说,type CN[X] = (_CN[A] forSome { type A })
    • 我想把_CN[_]本身变成一个类型构造函数,这样我以后可以在type Out = _CN[Int]中使用它
    • _CN[A] 已经是一个类型构造函数,因为它已在convertDoubleToInt 的签名中声明。 type CN[X] = _CN[_] 只是意味着任何XCN[X] 现在等于存在通配符_CN[_](或_CN[A] forSome { type A} ),而不是等于_CN[X] 相同的X
    猜你喜欢
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-05
    • 2021-02-13
    相关资源
    最近更新 更多