scala - 为什么在 foldLeft 的这个 Scala 实现中需要类型声明

标签 scala

我曾尝试使用以下代码在 LinkedList 上实现 foldLeft,一个是 curry foldLeft2,另一个不是,foldLeft:

sealed trait LinkedList[+E] {
  @tailrec
  final def foldLeft[A](accumulator: A, f: (A, E) => A): A = {
    this match {
      case Node(h, t) => {
        val current = f(accumulator, h)
        t.foldLeft(current, f)
      }
      case Empty => accumulator
    }
  }
  @tailrec
  final def foldLeft2[A](accumulator: A)(f: (A, E) => A): A = {
    this match {
      case Node(h, t) => {
        val current = f(accumulator, h)
        t.foldLeft2(current)(f)
      }
      case Empty => accumulator
    }
  }
}

但是当我使用 foldLeft 时,似乎我需要声明累加器和项目的类型,但对于 foldLeft2,我不需要。有人可以解释为什么会这样吗?
class LinkedListSpecification extends Specification {
  "linked list" should {
    "foldLeft correctly" in {
      val original = LinkedList(1,2,3,4)
      original.foldLeft(0, (acc: Int, item: Int) => acc + item) === 10
    }
  }
  "linked list" should {
    "foldLeft2 correctly" in {
      val original = LinkedList(1,2,3,4)
      original.foldLeft2(0)((acc, item) => acc + item) === 10
    }
  }
}

最佳答案

这是因为 Scala 中的类型推断在参数列表中从左到右工作。
因此在第二个版本中 foldLeft2它能够将类型 A 推断为 Int在它继续到下一个参数列表之前,它现在需要一个函数 (Int,E)=>Int .
虽然在第一个版本 foldLeft它试图推断 A同时通过两个参数( accumulatorf )。它提示你传递给它的匿名函数,因为它没有推断类型 A然而。

关于scala - 为什么在 foldLeft 的这个 Scala 实现中需要类型声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33116629/

相关文章:

scala - 自定义映射到 Slick 中的嵌套案例类结构(超过 22 列)

scala - 嵌入式ES实例中的完成搜索

xml - 隐式 append Scala XML 文字

java - Drools - 检查列表中是否存在/包含字符串<String>

Scala 特征和隐式转换混淆

scala - 使用中间变量时理解失败

scala - 简单的scala宏

list - 用元组附加 ListBuffer

scala - 检查定义了多少对象属性

scala - 如何在 Scala 中重构 (if/else if/else if) 链?