Scala: Value :: is not a member of Int

天涯浪子 提交于 2020-01-05 09:25:14

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!