Scala:Value ::不是Int的成员

时间:2015-07-06 21:10:06

标签: scala exception foldleft

我有以下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的新手,所以请尽可能简单地回复。感谢

3 个答案:

答案 0 :(得分:3)

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

所以在foldLeft _ :: _ ys :: xs.headfoldRight开头,这没有任何意义。

使用xs.last :: ys,最里面的操作是z /: ws,这很好。

参数顺序在运算符版本中更有意义:zws推进foldLeft(即ws :\ z),而z推动foldRight向左(即z)。内部参数的顺序与上面wclass Node(): def __init__(self, value = None, nex = None): self.val = value self.nex = nex class List(Node): def __init__(self): self.head = Node() def ins(self): li = [] for i in range(10): setattr(self,'n' + str(i), Node(i)) #self.n0.nex = self.n1 #self.n1.nex = self.n2 #self.n2.nex = self.n3 #. #. #. #self.n8.nex = self.n9 的顺序一致。

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:1)

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

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

因此第一个操作数是List [Int],第二个操作数是Int。 请注意,以“:”结尾的任何运算符都是特殊的,因为它使用左侧作为参数在右侧侧操作数上操作。这称为“右关联”,而默认通常是“左关联”。

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

在'foldLeft'的情况下,你需要一个左关联函数来添加像':+'这样的单个元素。所以这可行:

(xs foldLeft ys)(_ :+ _)

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