Объединение универсального типа: несколько параметров (T, T) или несколько списков параметров (T) (T)? - PullRequest
5 голосов
/ 06 января 2012

Меня немного смущает разница в проверке типов между универсальными функциями с карри и без кэрирования:

scala> def x[T](a: T, b: T) = (a == b)
x: [T](a: T, b: T)Boolean
scala> def y[T](a: T)(b: T) = (a == b)
y: [T](a: T)(b: T)Boolean

Моя интуиция заключалась в том, что и x(1, "one"), и y(1)("one") должны давать ошибки типа, ноЯ был не прав:

scala> x(1, "one")
res71: Boolean = false
scala> y(1)("one")
<console>:9: error: type mismatch;
 found   : java.lang.String("one")
 required: Int
              y(1)("one")
                   ^

Сначала я подумал, что происходит какое-то неявное приведение, но, похоже, это не так:

scala> x(1 :Int, "one" :String)
res73: Boolean = false

Так что же происходитна?Какой должна быть моя интуиция?

Ответы [ 2 ]

10 голосов
/ 06 января 2012

Scala пытается определять типы по одному блоку параметров за раз.Вы можете увидеть это, если добавите еще один параметр и примените его частично:

def x[T](a: T, b: T)(c: T) = (a == b)
scala> x(1, "one") _
res0: Any => Boolean = <function1>

Конечно, и Int, и String равны Any== определено для Any).

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

def y[T,U](a: T)(b: U)(c: (T,U)) = (a == b)
scala> y(1)("one")
res1: (Int, java.lang.String) => Boolean = <function1>

Вы также можете использовать более ранние блоки как значения по умолчанию в более поздних блоках!

def z[T,U](a: T)(b: U)(c: (T,U) = (a,b)) = (c._1 == c._2)
scala> z(1)("one")()
res2: Boolean = false

Таким образом, распределение ваших параметров по нескольким блокам параметров имеет последствия как для вывода типа, так и для дефолта (и для частичного применения).

9 голосов
/ 06 января 2012

Я думаю, что в первом случае это преуменьшение (понижение?) Обоих аргументов так, что T: Any.Во втором - это каррирование для Int, а затем сбой на строке.

Это, кажется, подтверждает меня:

scala> y(1)_
res1: Int => Boolean = <function1>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...