Scala Синтаксис векторной кратки (/: и:\и/: \)

Может ли кто-нибудь предоставить некоторые примеры того, как

/: :\ и /:\

На самом деле привыкаешь? Я предполагаю, что они являются ярлыками для методов сокращения/сбрасывания, но нет примеров того, как они действительно используются в документах Scala, и их невозможно найти в Google/Search на StackOverflow.

Ответы

Ответ 1

/: является синонимом foldLeft и :\ для foldRight.

Но помните, что : применяет /: к объекту справа от него.

Предполагая, что вы знаете, что (_ * _) является анонимной функцией, эквивалентной (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 

то есть. они являются карриными функциями, принимающими начальное значение и функцию, объединяющую начальное значение/аккумулятор с элементом из списка, некоторые примеры:

List(1,2,3).foldLeft(1)(_*_)

что совпадает с

(1 /: List(1,2,3))(_*_)

и

List(1,2,3).foldRight(1)(_*_)

в нотации infix есть

(List(1,2,3) foldRight 1)(_*_)

что совпадает с

(List(1,2,3) :\ 1)(_*_)

Добавьте свои собственные коллекции и функции и наслаждайтесь!

То, что следует помнить с помощью коротких (/: и :\) обозначений, состоит в том, что, поскольку вы используете нотные обозначения infix, вам нужно поместить круглые скобки вокруг первой части, чтобы она могла выбрать второй аргумент правильно списком. Кроме того, помните, что функции foldLeft и foldRight противоположны друг другу, но имеет смысл, если вы визуализируете сгиб в голове.

Ответ 2

Я лично предпочитаю формы /: и :\ foldLeft и foldRight. Две причины:

  • Это более естественное ощущение, потому что вы можете видеть, что вы нажимаете значение влево/вправо коллекции и применяете функцию. Это

    (1 /: ints) { _ + _ }
    
    ints.foldLeft(1) { _ + _ }
    

    Оба эквивалентны, но я склонен думать, что первое подчеркивает мою интуицию относительно того, что происходит. Если вы хотите знать, как это происходит (т.е. Метод, как представляется, вызывается для значения 1, а не для коллекции), потому что методы, заканчивающиеся на двоеточие, являются право-ассоциативными. Это можно увидеть в ::, +: и т.д. И т.д. В другом месте стандартной библиотеки.

  • Порядок параметров Function2 является тем же самым порядком, что и сложенный элемент, и сложенным в:

       (b /: as) { (bb, a) => f(bb, a) }
     // ^    ^      ^   ^
     // ^    ^      ^   ^
     // B    A      B   A
    

    Лучше всего:

    as.foldLeft(b) { (bb, a) => f(bb, a) }
    

    Хотя я признаю, что это было гораздо более важным отличием в эпоху до достойной поддержки IDE: в настоящее время IDEA может сказать мне, какая функция ожидается с помощью простого CTRL-P

Я надеюсь, что также должно быть очевидно, как :\ работает с foldRight - это в основном точно то же самое, за исключением того, что значение, похоже, вставляется с правой стороны. Должен сказать, я стараюсь избегать foldRight в scala из-за того, как он реализован (т.е. Ошибочно).

Ответ 3

Рекс Керр написал хороший ответ о складки здесь. В конце вы можете увидеть пример синтаксиса ярлыков foldLeft и foldRight.