1 - Параметризация функций.
Теоретически возможно, чтобы компилятор параметризовал тип функции; можно добавить это как функцию. Это не совсем тривиально, потому что функции контравариантны в своем аргументе и ковариантны в возвращаемом значении:
trait Function1[+T,-R] { ... }
, что означает, что другая функция, которая может принимать больше аргументов, считается подклассом (поскольку она может обрабатывать все, что может обработать суперкласс), и если она выдает меньший набор результатов, это нормально (так как она также подчиняется суперклассу построить так) Но как вы кодируете
def fn[A](a: A) = a
в этих рамках? Все дело в том, что возвращаемый тип равен переданному типу, каким бы он ни был. Тебе понадобится
Function1[ ThisCanBeAnything, ThisHasToMatch ]
как тип вашей функции. «Это может быть что угодно» хорошо представлено Any
, если вы хотите один тип, но тогда вы можете вернуть что угодно, так как исходный тип потерян. Нельзя сказать, что нет никакого способа реализовать это, но он не вписывается в существующую структуру.
2 - Скорость функций.
Это действительно просто: функция - это метод apply
для другого объекта. Вы должны иметь этот объект для вызова его метода. Это всегда будет медленнее (или, по крайней мере, не быстрее), чем вызов вашего собственного метода, поскольку вы уже имеете его.
С практической точки зрения, JVM могут очень хорошо выполнять функции вставки в эти дни; часто нет никакой разницы в производительности, если вы в основном используете свой метод или функцию, не создавая объект функции снова и снова. Если вы глубоко вкладываете очень короткие циклы, вы можете создать слишком много функций; перемещение их в vals вне вложенных циклов может сэкономить время. Но не беспокойтесь, пока не сравнитесь и не узнаете, что там есть узкое место; обычно JVM делает правильные вещи.