2013-12-21 2 views
8

Я слышал, в Scala можно использовать _ как "анонимный параметр" в анонимной функции:Почему Scala не может указать тип _?

List(1,2,3).foreach(print(_)) 

Но этот код не может быть скомпилирован:

scala> def a[T](s: Seq[T]): Seq[T] = s.map(_) 
<console>:7: error: missing parameter type for expanded function ((x$1) => s.map(x$1)) 

И это может:

scala> def a[T](s: Seq[T]): Seq[T] = s.map(x => x) 
a: [T](s: Seq[T])Seq[T] 

Это похоже на вывод типа. Но как мог x => x предоставить более подробную информацию, чем _?

ответ

13

Проблема здесь не в выводе типа.

Как видно из сообщения об ошибке эквивалентного кода для s.map(_) не , но это:

i => s.map(i) 

Так же, как print(_) (на самом деле Predef.print(_)) означает i => Predef.print(i).

Или как "a" + _ средства "a".+(_) средства s => "a".+(s).

Это не имеет смысла в текущем контексте.

Предположим, у вас есть список функций String => String (fs), и вы хотите применить все эти функции к списку String. Вы будете использовать этот код:

fs.map{f => s.map(f)} 

или просто так:

fs.map{s.map(_)} 

Дополнение: Вы можете использовать метод identity вместо если x => x. Он импортируется по умолчанию, но вы могли бы сделать его еще короче, используя импорт добавления:

import Predef.{identity => id} 
List(1, 2, 3) map id 
// List[Int] = List(1, 2, 3) 

Обратите внимание, что identity является хорошо известным именем, так и в команде, вы должны использовать его вместо ваших псевдонимов.

+0

+1 Очень интуитивное объяснение синтаксиса placeholder. –

0

Кажется, что касается типа вывода. Но как x => x предоставить больше информации, чем _?

x => x - это тип Function1, который функция карты ожидает в качестве параметра. Компилятор не может сделать вывод, что анонимная переменная _ типа T действительно является функцией 1.

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