【问题标题】:What determines 'A' type in foldLeft?什么决定了 foldLeft 中的“A”类型?
【发布时间】:2015-02-13 16:54:53
【问题描述】:

在这个 foldLeft 的定义中,Ints 的列表被颠倒了:

  val l = List(1, 2)                              //> l  : List[Int] = List(1, 2)
  l.foldLeft(List[Int]())((b, a) => a :: b)       //> res2: List[Int] = List(2, 1)

A 如何在 foldLeft 函数中输入 Int?

foldLeft 的来源是:

  def foldLeft[B](z: B)(f: (B, A) => B): B = {
    var acc = z
    var these = this
    while (!these.isEmpty) {
      acc = f(acc, these.head)
      these = these.tail
    }
    acc
  }

什么决定了A 类型?是否有一些 Scala 隐式逻辑从类型参数 List[Int] 确定 Int 类型?

更新:

foldLeft 在 LinearSeqOptimized 中定义。

当使用val l = List(1,2) 创建列表时,这也将A 参数键入到LinearSeqOptimized,因为它是其对象层次结构的一部分:

sealed abstract class List[+A] extends AbstractSeq[A]
                                  with LinearSeq[A]
                                  with Product
                                  with GenericTraversableTemplate[A, List]
                                  with LinearSeqOptimized[A, List[A]]
                                  with Serializable {

这就是为什么在 foldLeft 中将类型 A 键入 Int 的原因?

【问题讨论】:

  • A 是列表元素类型。
  • 如果我们在类型级别和值级别进行命名一样谨慎,不是很好吗?
  • @acjay 同意,但是类型的单字符变量名称使得从这些名称中提取含义更加困难,我认为这可能会导致错误。

标签: scala


【解决方案1】:

foldLeft[B]List[A] 的成员(以及许多不同的集合类型)。所以A 只是你要折叠的集合的类型参数。

List(1, 2)List[Int],所以A = Int

B 就是你要折叠的类型(fold 的返回类型)。它可能与A 相同,但也可能不同。在你的例子中,你折叠成一个List[Int],所以B = List[Int](不是Int)。

【讨论】:

  • 谢谢,请查看更新。我理解正确吗?
  • @blue-sky 我不确定我是否理解您的后续问题。您的编辑并没有真正说明B。你能详细说明一下吗?
  • 抱歉,我已将问题更新为“这就是为什么类型 A 在 foldLeft 中被输入到 Int”而不是“这就是为什么类型 B 在 foldLeft 中被输入到 Int”。
  • @blue-sky 是的,A 被推断为 Int,当您创建 List(1, 2) 时,List 混入的所有特征也必须相同。跨度>
【解决方案2】:

简而言之

List(1, 2, 3).foldLeft(List[Int]())((b, a) => a :: b)
     ^                 ^
     A                 B

【讨论】:

    猜你喜欢
    • 2014-04-26
    • 2012-04-04
    • 1970-01-01
    • 2015-07-21
    • 2014-08-03
    • 2019-10-03
    • 2012-02-13
    • 1970-01-01
    相关资源
    最近更新 更多