Scala: Value :: 不是 Int 的成员

Scala: Value :: is not a member of Int

我有以下 Scala 代码示例,我想知道为什么我在 foldLeft 上出现错误,而在 foldRight 上却没有?

val xs = List(1,2,3) 
val ys = List(4,5,6)
(xs foldLeft ys) (_::_) // Error: Value :: is not a member of Int
(xs foldRight ys) (_::_) // Res: List(1, 2, 3, 4, 5, 6)

我是 Scala 的新手,所以请尽可能简单地回答。谢谢

传递给 foldLeftfoldRight 的运算符(函数)的参数顺序相反。

所以在 foldLeft 中你的 _ :: _ys :: xs.head 开头,这没有任何意义。

foldRight,最里面的操作是xs.last :: ys,没问题

参数顺序在运算符版本中更有意义:z /: ws 通过 ws 向右推动 z(即 foldLeft),而 ws :\ z 推动z 向左(即 foldRight)。并且内部参数的顺序与上面的 zw 的顺序一致。

foldLeft 和 foldRight 具有不同的签名,它们接受不同的参数

def foldLeft[B](z: B)(op: (B, A) => B): B
def foldRight[B](z: B)(op: (A, B) => B): B

查看这两个函数的类型 op。对于 foldLeft,left 参数是您要折叠的集合的类型(在您的例子中是 int),而对于 foldRight,它是结果类型(在您的例子中是集合)。

因此,如果您希望每个后续元素都添加到结果列表中,您需要在 foldLeft 中使用不同的函数。

简而言之,'::' 操作在 Int 上不可用,仅在集合上可用。 如果您在 Scala REPL 中执行 '(xs foldLeft ys) _',您会看到它产生了一个函数

((List[Int], Int) => List[Int]) => List[Int] = <function1>

所以第一个操作数是List[Int],第二个是Int。 请注意,任何以“:”结尾的运算符都是特殊的,因为它使用左侧作为参数在 right 侧操作数上进行操作。这称为 'right-associative' 而默认值通常是 'left-associative'.

因此 'aList :: anInt' 被翻译成 'anInt.::(aList)',这会导致问题,因为 Int 没有 '::' 方法。

在 'foldLeft' 的情况下,您需要一个左关联函数来添加单个元素,例如“:+”。这样就可以了:

(xs foldLeft ys)(_ :+ _)

请注意,结果与 foldRight 完全不同,因此请务必根据您的情况选择更正结果。