【问题标题】:Missing parameter type缺少参数类型
【发布时间】:2016-06-13 18:15:32
【问题描述】:

我在 Scala 中重写了一系列 Haskell 函数,遇到了一个我似乎无法解释的编译错误

错误如下:

missing parameter type
    def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs)
                                                        ^
missing parameter type
    def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs)
                                                           ^

代码如下:

object Stuff {
  def main(args: Array[String]): Unit = {
    val lst = List(1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 5, 6, 7)
    println(group(lst))
  }

  def group[A](xs: List[A]): List[List[A]] = groupBy((a, b) => a == b, xs)
  def groupBy[A](fun: (A, A) => Boolean, input: List[A]): List[List[A]] = // stuff
}

我完全不确定这里发生了什么,为什么它抱怨缺少参数类型。据我所知,一切都已定义

【问题讨论】:

    标签: scala types


    【解决方案1】:

    如果您在 groupBy 调用站点提供显式泛型类型参数,它将编译:

    def group[A](xs: List[A]): List[List[A]] = groupBy[A]((a, b) => a == b, xs)
    

    请参阅this post,了解为什么 Scala 的类型推断在这种情况下失败。

    如果您使用 curried 参数列表编写 groupBy,则应正确推断类型信息:

    def group[A](xs: List[A]): List[List[A]] = groupBy(xs)((a, b) => a == b)
    
    def groupBy[A](input: List[A])(fun: (A, A) => Boolean): List[List[A]] = input match {
      case Nil => Nil
      case (x::xs) =>
        val (ys, zs) = span(fun.curried(x), xs)
        (x::ys)::groupBy(zs)(fun)
    }    
    

    【讨论】:

      【解决方案2】:

      这似乎是类型推断系统的限制。您可以尝试以下方法吗:

      def group[A](xs: List[A]): List[List[A]] = groupBy((a: A, b: A) => a == b, xs)
      

      【讨论】:

        【解决方案3】:

        您的函数(a, b) => a == b 未指定其参数的类型。您可以轻松地将其修复为:

        def group[A](xs: List[A]): List[List[A]] = groupBy((a: A, b: A) => a == b, xs)
        

        def group[A](xs: List[A]): List[List[A]] = groupBy[A]((a, b) => a == b, xs)
        

        编辑:

        另一个答案指出,如果您切换参数的位置并将它们咖喱,它将起作用。是的,因为第二个参数会从第一个参数推断出来。请注意,第二个参数列表可以从第一个参数列表中学习,但如果它们是一个参数列表中的两个参数,那么这是不可能的(它在 Scala 规范中)所以这就是我们需要柯里化的原因。但是,我认为简单地表示类型而不是切换参数和 curry 函数更容易。简单而不是不必要的复杂。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-29
          • 2017-10-30
          • 2020-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-28
          相关资源
          最近更新 更多