问题
I have following Scala code sample and I want to know why I get an Error on foldLeft but not with 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)
I am new to Scala, so please reply as simple as you can. Thanks
回答1:
The arguments for the operator (function) passed to foldLeft
and foldRight
are in opposite order.
So in foldLeft
your _ :: _
starts with ys :: xs.head
, which doesn't make any sense.
With foldRight
, the innermost operation is xs.last :: ys
, which is fine.
The argument order makes more sense in the operator versions: z /: ws
pushes z
righward through ws
(i.e. foldLeft
), while ws :\ z
pushes z
leftward (i.e. foldRight
). And the order of arguments inside agrees with the order of z
vs. w
above.
回答2:
foldLeft and foldRight have different signatures, they accept different arguments
def foldLeft[B](z: B)(op: (B, A) => B): B
def foldRight[B](z: B)(op: (A, B) => B): B
Look at the type of the function op
in both of those. For foldLeft the left argument is the type of the collection you are folding (in your case an int), while for foldRight it is the result type (in your case a collection).
So instead you want to use a different function in foldLeft if you want each subsequent element prepended to your resulting list.
回答3:
In short, the operation '::' is not available on an Int, only on collections. If you perform '(xs foldLeft ys) _' in the Scala REPL, you see that it results in a function
((List[Int], Int) => List[Int]) => List[Int] = <function1>
So the first operand is the List[Int] and the second an Int. Note that any operator ending with ':' is special since it is operated on the right side operand using the left as an argument. This is called 'right-associative' whereas the default normally is 'left-associative'.
Therefore 'aList :: anInt' is translated into 'anInt.::(aList)' and this causes the issue since Int does not have a '::' method.
In the 'foldLeft' case you need a left-associative function to add a single element like ':+'. So this then works:
(xs foldLeft ys)(_ :+ _)
Note that the result is quite different from foldRight so be sure to pick to correct one for your situation.
来源:https://stackoverflow.com/questions/31255688/scala-value-is-not-a-member-of-int