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 的新手,所以请尽可能简单地回答。谢谢
传递给 foldLeft
和 foldRight
的运算符(函数)的参数顺序相反。
所以在 foldLeft
中你的 _ :: _
以 ys :: xs.head
开头,这没有任何意义。
用foldRight
,最里面的操作是xs.last :: ys
,没问题
参数顺序在运算符版本中更有意义:z /: ws
通过 ws
向右推动 z
(即 foldLeft
),而 ws :\ z
推动z
向左(即 foldRight
)。并且内部参数的顺序与上面的 z
和 w
的顺序一致。
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 完全不同,因此请务必根据您的情况选择更正结果。
我有以下 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 的新手,所以请尽可能简单地回答。谢谢
传递给 foldLeft
和 foldRight
的运算符(函数)的参数顺序相反。
所以在 foldLeft
中你的 _ :: _
以 ys :: xs.head
开头,这没有任何意义。
用foldRight
,最里面的操作是xs.last :: ys
,没问题
参数顺序在运算符版本中更有意义:z /: ws
通过 ws
向右推动 z
(即 foldLeft
),而 ws :\ z
推动z
向左(即 foldRight
)。并且内部参数的顺序与上面的 z
和 w
的顺序一致。
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 完全不同,因此请务必根据您的情况选择更正结果。