Обновление (2018 г.): на мои молитвы был дан ответ в Dotty (Type Lambdas), поэтому следующий Q & A является более "Scalac" о связанных
Простой пример из Scala:
scala> def f(x: Int) = x
f: (x: Int)Int
scala> (f _)(5)
res0: Int = 5
Позвольте сделать его общим:
scala> def f[T](x: T) = x
f: [T](x: T)T
scala> (f _)(5)
<console>:9: error: type mismatch;
found : Int(5)
required: Nothing
(f _)(5)
^
Посмотрите на eta-расширение полиморфного метода в Scala:
scala> f _
res2: Nothing => Nothing = <function1>
Сравнение с Haskell:
Prelude> let f x = x
Prelude> f 5
5
Prelude> f "a"
"a"
Prelude> :t f
f :: t -> t
Haskell сделал правильный тип [T] => [T]
здесь.
Более реалистичный пример?
scala> identity _
res2: Nothing => Nothing = <function1>
Еще более реалистично:
scala> def f[T](l: List[T]) = l.head
f: [T](l: List[T])T
scala> f _
res3: List[Nothing] => Nothing = <function1>
Вы не можете сделать псевдоним для идентификации - вам нужно написать свою собственную функцию. Такие вещи, как [T,U](t: T, u: U) => t -> u
(make tuple), невозможно использовать в качестве значений. Более общий - если вы хотите передать некоторую лямбду, которая полагается на общий тип (например, использует общую функцию, например: создает списки, кортежи, каким-то образом модифицирует их) - вы не можете этого сделать.
Итак, как решить эту проблему? Любое обходное решение, решение или аргументация?
P.S. Я использовал термин полиморфный лямбда (вместо функции), поскольку функция называется lambda