фона
Недавно я присутствовал начинающую Scala Meetup, и мы говорили о различии между методами и функциями (также обсуждается в углубленном here).Почему Scala не позволяет List.map _ и типа подписи в РЕПЛ
Например:
scala> val one = 1
one: Int = 1
scala> val addOne = (x: Int) => x + 1
addOne: Int => Int = <function1>
Это свидетельствует о том, что Vals может не только иметь целочисленный тип, но может иметь тип функции. Мы можем увидеть тип в лестницу РЕПЛ:
scala> :type addOne
Int => Int
Мы также можем определить методы объектов и классов:
scala> object Foo {
| def timesTwo(op: Int) = op * 2
| }
defined module Foo
И в то время как метод не имеет тип (а скорее имеет тип подписи), мы можем поднять его в функцию, чтобы увидеть, что это такое:
scala> :type Foo.timesTwo
<console>:9: error: missing arguments for method timesTwo in object Foo;
follow this method with `_' if you want to treat it as a partially applied function
Foo.timesTwo
^
scala> :type Foo.timesTwo _
Int => Int
Пока что так хорошо. Мы даже говорили о том, как функции фактически являются объектами с помощью метода применяются и как мы можем де-синтаксических sugarify выражения, чтобы показать это:
scala> Foo.timesTwo _ apply(4)
res0: Int = 8
scala> addOne.apply(3)
res1: Int = 4
Для меня это очень полезно в изучении языка, потому что я могу усвоить то, что синтаксис на самом деле подразумевает.
Проблемные Пример
Мы делали, однако, столкнуться с ситуацией, что мы не смогли определить. Возьмем, например, список строк. Мы можем сопоставить функции над значениями, демонстрирующих основные коллекции Scala и функционального программирования вещи:
scala> List(1,2,3).map(_*4)
res2: List[Int] = List(4, 8, 12)
Итак, что такое тип List (1,2,3) .map()? Я ожидаю, что мы сделали бы то же самое: тип трик в РЕПЛ:
scala> :type List(1,2,3).map _
<console>:8: error: Cannot construct a collection of type Nothing with elements of type Nothing based on a collection of type List[Int].
List(1,2,3).map _
^
Из определения API, я знаю, что подпись:
def map[B](f: (A) ⇒ B): List[B]
Но есть также полная подпись:
def map[B, That](f: (A) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That
Вопрос
Итак, есть две вещи, которые я не совсем понимаю:
- Почему не работает обычная функция трюка с функцией List.map? Есть ли способ де-синтаксического сахара ошибочное утверждение, чтобы продемонстрировать, что происходит?
- Если причина, по которой метод не может быть снят, вызвана полной подписью «неявной», что именно происходит там?
И, наконец, существует ли надежный способ проверки обоих типов и подписи от REPL?
Вопрос о неявной сигнатуре типа объясняется здесь: http://stackoverflow.com/a/18533437/125901 –