В OCaml законно иметь в .mli
:
val f : 'a -> 'a
val g : 'a -> 'a
и .ml
:
let f x = x
let g = f
Однако в F # это отклоняется:
eta_expand.ml(2,5): error FS0034: Module 'Eta_expand' contains
val g : ('a -> 'a)
but its signature specifies
val g : 'a -> 'a
The arities in the signature and implementation differ. The signature specifies that 'g' is function definition or lambda expression accepting at least 1 argument(s), but the implementation is a computed function value. To declare that a computed function value is a permitted implementation simply parenthesize its type in the signature, e.g.
val g: int -> (int -> int)
instead of
val g: int -> int -> int.
Обходным путем является η-расширение определения g:
let g x = f x
Если мой код является чисто функциональным (никаких исключений, никаких побочных эффектов и т.д.), это должно быть эквивалентным (на самом деле это может быть еще лучше в отношении полиморфизма, в зависимости от того, как язык обобщает типы: в частичных приложениях OCaml не производят полиморфных функций, но их η-разложение действительно).
Есть ли какой-либо недостаток систематического η-расширения?
Два ответа ускользают от вопроса о η-расширении:-), и вместо этого предположим, что я добавляю круглые скобки вокруг своего функционального типа. Это связано с тем, что, по-видимому, F # различает уровень ввода между "истинным" определением функций (как λ-выражения и вычисляемые определения, как в частичных приложениях); предположительно это связано с тем, что λ-выражения непосредственно отображаются в функции CLR, тогда как вычисляемые определения сопоставляют делегирование объектов. (Я не уверен в этой интерпретации и буду признателен, если кто-то, кто очень хорошо знаком с F #, может указать на справочные документы, описывающие это.)
Решение заключалось бы в систематическом добавлении скобок ко всем типам функций в .mli
, но я боюсь, что это может привести к неэффективности. Другим было бы обнаружение вычисленных функций и добавление в скобки соответствующих типов в .mli
. Третьим решением было бы η-развернуть очевидные случаи и заключить в скобки другие.
Я недостаточно осведомлен о внутренних функциях F #/CLR, чтобы измерить, какие из них несут существенную производительность или сопрягают штрафы.