Scala 中的折叠列表

Folding lists in scala

scala 中使用 /: 和 :\ 运算符的折叠列表

我试图查看不同的站点,但他们只谈论 foldRight 和 foldLeft 函数。

def sum(xs: List[Int]): Int = (0 /: xs) (_ + _)
sum(List(1,2,3))
res0: 6

代码段按描述工作。但是我无法完全理解方法定义。我的理解是第一个括号内的那个 -> 0 /: xs 其中 /: 是右关联运算符。对象是 xs,参数是 0。我不确定操作的 return 类型(很可能是另一个列表?)。第二部分是功能部分,将其两个参数相加。但我不明白什么对象调用它?和函数名称。有人可以帮我理解一下吗。

:/的签名是

/:[B](z: B)(op: (B, A) ⇒ B): B

这是一个有多个参数列表的方法,所以当它只是用 on 参数调用时(即在你的例子中是 0 /: xs),return 类型是 (op: (B, A) ⇒ B): B。因此,您必须向它传递一个带有 2 个参数 ( _ + _ ) 的方法,该方法用于组合从 z 开始的列表元素。

这种方法通常被称为foldLeft

(0 /: xs)(_ + _) 等同于 xs.foldLeft(0)(_ + _)

您可以在此处找到更多详细信息:https://www.scala-lang.org/api/2.12.3/scala/collection/immutable/List.html

感谢@HaraldGliebe 和@LuisMiguelMejíaSuárez 的精彩回复。我现在开悟了!我只是在这里总结一下答案,这可能会使阅读此主题的其他人受益。

"/:"实际上是Listclass中定义的函数名。函数的签名是:/:[B](z: B)(op: (B, A) ⇒ B): B --> 其中B是类型参数,z是第一个参数; op 是函数类型的第二个参数。 该函数遵循 curried 版本 --> 这意味着我们可以传递比实际数量更少的参数。如果我们这样做, 部分应用的函数存储在一个临时变量中;然后我们可以使用临时变量来传递剩余的参数。 如果提供所有参数,“/:”可以调用为: x./:(0)(_+_) 其中 x 是列表类型的 val/var。或 "/:" 可以分两步调用,如下所示: step:1 val temp = x./:(0)(_) 我们只传递第一个参数。这导致存储在临时变量中的部分应用函数。 step:2 temp(_+_) 这里使用部分应用函数 temp 与第二个(最终)参数一起传递。

如果我们决定遵循第一种风格(x./:(0)(_+_)),调用第一个参数可以写在运算符概念中,即:x /: 0 由于方法名称以冒号结尾,因此对象将从右侧拉出。所以 x /: 0 是无效的,必须写成 0 /: x 才是正确的。 这个相当于临时变量。在0 /: x之后,还需要传递第二个参数。所以整个构造变成:(0/:x)(_+_)

问题中函数 sum 的定义是这样解释的。

我们必须注意,当我们在运算符概念中使用函数的柯里化版本时,我们必须一次性提供所有参数。

即:(0 /: x) (_)(0 /: x) _ 似乎抛出语法错误。