2013-12-17 3 views
3

Scala's <- стрелка кажется немного странной. Большинство операторов реализованы где-то в источнике как функция, определенная по типу данных, прямо или косвенно. <-, с другой стороны, только кажется непригодным для использования вне определения for, где он действует как синтаксический элемент, используемый для сигнализации привязки новой переменной в монадическом контексте (через map).Is <- доступно только компилятору

Это единственный экземпляр, в котором я могу думать о том, где Scala имеет синтаксический элемент, выглядящий в операторе, который используется только в определенном контексте и не является фактической функцией.

Я не прав, как работает <-? Является ли это особым символом случая, используемым только компилятором, или каким-то образом разработчик мог использовать это поведение при написании собственного кода?

Например, было бы возможно написать макрос для преобразования

forRange (i <- 0 to 10) { print(i) } 

в

{ var i = 0; while (i <= 10) { print(i) } } 

вместо стандартного map эквивалента? Насколько я могу судить, любое использование i <- ... вне контекста for вызывает исключение из-за ссылки на неизвестное значение.

ответ

6

Короче говоря, да <- является зарезервированным оператором в Скале. Это компилятор.

Foreach

Существует сильное различие между foreach и for yield, но синтаксис только синтаксический сахар, преобразованный во время компиляции.

for (i <- 1 to 10) { statement } выражение переведено на:

Range.from(1, 10).foreach(..) 

нескольких переменных: for (i <- 1 to 10; y <- 2 to 100) {..} становится:

Range.from(1, 10).foreach( el => {Range.from(2, 100).foreach(..)});

со всеми вариациями определяется по формуле:

for (x <- someList) = someList.foreach(..).

Проще говоря, все они получают de-sugared до foreach заявлений. Конкретный foreach, который вызывается, задается используемой коллекцией.

Для получения урожая

for yield синтаксис является сахар для flatMap и map. Здесь применяется правило stay in the monad.

for (x <- someList) yield {..} переведен на someList.flatMap(..).

Цепные операции становятся иерархические цепочки map/flatMap комбо:

for { x <- someList; y <- SomeOtherList } yield {} становится:

someList.flatMap(x => { y.flatMap(..) }); и так далее.

Точка

Дело в том, что оператор <- не более чем синтаксический сахар, чтобы сделать код более удобным для чтения, но он всегда заменяется во время компиляции.

Чтобы подчеркнуть точку Роба

Роб делает отличные примеры других Scala синтаксический сахар.

Контекст связанный

package somepackage; 
class Test[T : Manifest] {} 

фактически переведен на:

class Test[T](implicit evidence: Manifest[T])

В качестве доказательства, попробуйте псевдоним типа с контекстом, связанным:

type TestAlias[T : Manifest] = somepackage.Test // error, the : syntax can't be used.. Возможно, легко увидеть, как часть : Manifest фактически не является параметром типа.

Легче набрать class Test[T : Manifest], а не class Test[T](implicit evidence: Manifest[T].

+0

Я полагаю, что Скала испортила мне немного. Было несколько вещей, которые я изначально считал синтаксическим сахаром, специфичным для компилятора, который в конечном итоге строился на языковых функциях. Это одна из моих любимых вещей о Scala; большая часть его дизайна позволяет избежать особых дел. К сожалению, я не знаю, как еще вы это разработали. +1 и ** принять ** для вас. – KChaloux

2

Оператор - это зарезервированное слово на этом языке (см. Scala Language Specification, стр. 4), но он не одинок. => также является зарезервированным словом, а не функцией. (Также _, :, =, <:, <%, >:, # и @.) Таким образом, вы не можете создать функцию с этим именем. Я не верю, что вы могли бы адаптировать его так, как вы предлагаете, (хотя, возможно, кто-то более умный будет знать способ). Вы можете создать функцию под названием `<-` (с окружающими обратными тиками), но это, вероятно, будет более неудобно, чем того заслуживает.

+0

Я должен был ожидать, что => было то же самое. Просто не думал об этом. +1 для полезной информации. Жаль, что это функция компилятора, а не встроенная функция языка. Я не знаю, как вы это сделаете, но Скала удивила меня, сделав много вещей, которые * выглядят * как синтаксический сахар из простых языковых конструкций ('->' для создания кортежей, например). – KChaloux

Смежные вопросы