Scala:类型推断问题

时间:2018-09-20 16:38:16

标签: scala type-inference existential-type type-deduction

我有:

sealed trait Par[A]{def foo = ???}
case class Unit[A](v: () => A) extends Par[A]
case class Map2[L, R, A](parLeft: Par[L],
                         parRight: Par[R],
                         map: (L, R) => A) extends Par[A]

我的问题是,当我在p:Par[A]上进行模式匹配时,会执行以下操作:

def getSequentially: A = this match {
  case Par.Unit(f) => f()
  case Par.Map2(a, b, f) => f(a.getSequentially, b.getSequentially)
}    

LR在Intellij的类型检查器中被推断为Any,并且getSequentially的呼叫以红色突出显示,警告:type mismatch, expected Nothing, actual Any,因为{{ 1}}的类型应为:f。尽管它实际上可以运行和编译。

我认为我了解问题所在,并且应该能够使用(Nothing, Nothing) => A定义中的存在类型解决问题。唯一的问题是Map2参数具有从属类型,因此我不知道该怎么做。也许我应该改变AUX模式?

我的问题是,首先为什么要编译,其次,是否存在一种重组类型依赖关系的方式,以使其不再发出警告。

1 个答案:

答案 0 :(得分:2)

如果您要具有存在性,可以使用键入的模式:

sealed trait Par[A]{
  def getSequentially: A = this match {
    case x: Par.Unit[A] => x.v()
    case x: Par.Map2[_, _, A] => x.map(x.parLeft.getSequentially, x.parRight.getSequentially)
  }
}

object Par {
  case class Unit[A](v: () => A) extends Par[A]
  case class Map2[L, R, A](parLeft: Par[L],
                           parRight: Par[R],
                           map: (L, R) => A) extends Par[A]
}

IntelliJ似乎没有强调这一点。