Scala Vector折叠语法(/:和:\和/:\)

chb*_*own 15 syntax scala fold

有人可以提供一些例子

/: :\/:\

实际上习惯了?我假设它们是reduce/fold方法的快捷方式,但是没有关于它们如何在Scala文档中实际使用的示例,并且它们无法在StackOverflow上进行谷歌/搜索.

oxb*_*kes 14

我个人比较喜欢/::\形式foldLeftfoldRight.两个原因:

  1. 它具有更自然的感觉,因为您可以看到您正在将值推入集合的左/右并应用函数.那是

    (1 /: ints) { _ + _ }
    
    ints.foldLeft(1) { _ + _ }
    
    Run Code Online (Sandbox Code Playgroud)

    两者都是等价的,但我倾向于认为前者强调我对正在发生的事情的直觉.如果你想知道这是怎么回事(即方法似乎是在值1而不是集合上调用),那是因为以冒号结尾的方法是右关联的.由此可以看出在::,+:等等等等标准库中的其他地方.

  2. 所述的排序Function2参数是相同的顺序折叠元件和其被折叠成:

       (b /: as) { (bb, a) => f(bb, a) }
     // ^    ^      ^   ^
     // ^    ^      ^   ^
     // B    A      B   A
    
    Run Code Online (Sandbox Code Playgroud)

    各方面都比以下更好:

    as.foldLeft(b) { (bb, a) => f(bb, a) }
    
    Run Code Online (Sandbox Code Playgroud)

    虽然我承认在IDE支持体面之前这是一个非常重要的差异:现在IDEA可以通过一个简单的CTRL-P告诉我预期的功能是什么

我希望也应该明白如何:\使用foldRight - 它基本上是完全一样的,除了值似乎是从右侧推入.我必须说,foldRight由于它是如何实现的(即错误地),我倾向于在scala中很好地避开.


Lui*_*hys 10

/:是的代名词foldLeft,并:\foldRight.

但请记住,:make /:适用于它右侧的对象.

假设你知道这(_ * _)是一个等同于的匿名函数(a, b) => a * b,而且foldLeft和foldRight的签名是

def foldLeft  [B] (z: B)(f: (B, A) ? B): B 
def foldRight [B] (z: B)(f: (A, B) ? B): B 
Run Code Online (Sandbox Code Playgroud)

即,它们是带有起始值的curried函数和将起始值/累加器与列表中的项组合的函数,例如:

List(1,2,3).foldLeft(1)(_*_)
Run Code Online (Sandbox Code Playgroud)

这是一样的

(1 /: List(1,2,3))(_*_)
Run Code Online (Sandbox Code Playgroud)

List(1,2,3).foldRight(1)(_*_)
Run Code Online (Sandbox Code Playgroud)

在中缀符号中

(List(1,2,3) foldRight 1)(_*_)
Run Code Online (Sandbox Code Playgroud)

这是一样的

(List(1,2,3) :\ 1)(_*_)
Run Code Online (Sandbox Code Playgroud)

添加您自己的收藏和功能,享受!

用短(/::\)符号记住的事情是,因为你正在使用中缀符号,你需要在第一部分周围加上括号,以便它正确地获取第二个参数列表.另外,请记住foldLeft和foldRight的功能是相反的方式,但是如果你可以看到头部的折叠,这是有意义的.