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.