【问题标题】:Scala: type inference issueScala:类型推断问题
【发布时间】:2018-09-20 16:38:16
【问题描述】:

我有:

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 的类型检查器中被推断为 AnygetSequentially 调用以红色突出显示,警告:type mismatch, expected Nothing, actual Any,因为 f 预计为:@987654330 @。虽然它实际上可以运行和编译。

我想我理解问题所在,我应该能够使用Map2 定义中的存在类型来解决它。唯一的问题是 map 参数有一个依赖类型,所以我不知道该怎么做。也许我应该做一个 AUX 模式的变体?

我的问题是,首先它为什么会编译,其次,是否有办法重组类型依赖关系,使其不再发出警告。

【问题讨论】:

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


    【解决方案1】:

    如果你想拥有存在主义,你可以使用类型化模式:

    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 似乎没有强调这一点。

    【讨论】:

    • 谢谢!出于好奇,Par.Map2[_, _, A] 的简写版本是什么?即如何编写forSome 两种类型LR 的表达式?
    • Par.Map2[_, _, A]Par.Map2[L, R, A] forSome { type L; type R }。但是您可以在def foo[A](x: Par.Map2[L, R, A] forSome { type L; type R }) = ??? 中的类型位置以这种形式编写它。在我们的例子中Par.Map2[_, _, A] 不是一个类型,它是一个类型模式(参见here 从“• 参数化类型模式T[a1,…,an] ...”开始)所以你不能写它在这里forSome
    猜你喜欢
    • 1970-01-01
    • 2013-02-19
    • 2011-11-07
    • 1970-01-01
    • 2023-03-17
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多