scaladoc中的foldRight[B](B)
如何与实际调用foldRight(0)
args是字符串表示中的整数数组
val elems = args map Integer.parseInt
elems.foldRight(0) (_ + _)
Scaladoc说:
scala.Iterable.foldRight[B](B)((A, B) => B) : B
Combines the elements of this list together using the binary function f, from right to left, and starting with the value z.
@note Will not terminate for infinite-sized collections.
@return f(a0, f(a1, f(..., f(an, z)...))) if the list is [a0, a1, ..., an].
并不是那么重要f(an,z)之后的时期是什么意思?
答案 0 :(得分:6)
如Steve所述,“...”只是省略号,表示可显示的可变数量的参数未显示。
让我们去Scaladoc,并逐步展示:
def foldRight[B](z: B)(op: (B, A) ⇒ B): B
这显示不够。什么是A
?这是在Iterable
类(或其定义的任何其他类)中定义的:
trait Iterable[+A] extends AnyRef // Scala 2.7
trait Iterable[+A] extends Traversable[A] with GenericTraversableTemplate[A, Iterable[A][A]] with IterableLike[A, Iterable[A]] // scala 2.8
好的,所以A
是集合的类型。在您的示例中,A
代表Int
:
val elems = args map Integer.parseInt
接下来,[B]
。这是一个类型参数。基本上,以下两个调用在实践中是相同的,但第一个调用编译器推断出类型参数:
elems.foldRight(0) (_ + _)
elems.foldRight[Int](0) (_ + _)
如果您使用0L
代替0
,则B
代替Long
。如果您通过了""
而不是0
,则B
将代表String
。你可以尝试这些,它们都可以工作。
因此,B
为Int
,z
为0
。请注意,声明中有两组括号。这意味着该功能 curried 。它接收两组参数,以及类型参数([B]
)。这意味着您可以省略第二组参数,并返回一个接受第二组参数的函数,并返回预期结果。例如:
val elemsFolder: ((Int, Int) => Int) => Int = elems.foldRight(0)
然后你可以这样打电话:
elemsFolder(_ + _)
无论如何,第二组收到op
,预计类型为(B, A) => B
。或者,换句话说,一个接收两个参数的函数 - 第一个与z
的类型相同,第二个与集合的类型相同 - 并返回相同类型的结果作为第一个参数。由于A
和B
都是Int
,因此它将是(Int, Int) => Int
的函数。如果您通过""
,那么它将是(String, Int) => String
类型的函数。
最后,集合的返回类型为B
,这意味着z
的类型,foldRight
返回的类型。
关于foldRight
如何运作,它有点像这样:
def foldRight[B](z: B)(op: (B, A) => B): B = {
var acc: B = z
var it = this.reverse.elements // this.reverse.iterator on Scala 2.8
while (!it.isEmpty) {
acc = op(acc, it.next)
}
return acc
}
其中,我希望应该很容易理解。
答案 1 :(得分:5)
您需要了解的有关foldLeft
和foldRight
的所有信息都可以从以下方面收集:
scala> List("1", "2", "3").foldRight("0"){(a, b) => "f(" + a + ", " + b + ")"}
res21: java.lang.String = f(1, f(2, f(3, 0)))
scala> List("1", "2", "3").foldLeft("0"){(a, b) => "f(" + a + ", " + b + ")"}
res22: java.lang.String = f(f(f(0, 1), 2), 3)