Trong OCaml, nó là hợp pháp phải có trong .mli
:η-mở rộng bằng một ngôn ngữ chức năng thuần túy
val f : 'a -> 'a
val g : 'a -> 'a
và .ml
:
let f x = x
let g = f
Tuy nhiên, trong F #, điều này bị từ chối:
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.
Một giải pháp thay thế là η mở rộng định nghĩa của g:
let g x = f x
Nếu mã của tôi là hoàn toàn chức năng (không có ngoại lệ, không có tác dụng phụ, vv) này cần phải tương ứng (trên thực tế, nó có thể là tốt hơn đối với đa hình với, tùy thuộc vào cách ngôn ngữ khái quát các loại: trong OCaml các ứng dụng một phần không tạo ra các chức năng đa hình, nhưng các η-mở rộng của chúng không).
Có bất kỳ hạn chế nào đối với việc mở rộng system-hệ thống không?
Hai câu trả lời gợi ý câu hỏi về η-mở rộng :-) và thay vào đó đề nghị tôi thêm dấu ngoặc đơn quanh loại chức năng của mình. Điều này là do, rõ ràng, F # phân biệt ở mức đánh máy giữa định nghĩa "đúng" của các hàm (như các biểu thức and và các định nghĩa được tính toán, như trong các ứng dụng một phần); có lẽ điều này là do các biểu thức directly trực tiếp ánh xạ tới các hàm CLR trong khi các định nghĩa được tính toán ánh xạ tới các đối tượng đại biểu. (Tôi không chắc chắn về cách giải thích này và sẽ đánh giá cao nếu ai đó rất quen thuộc với F # có thể chỉ để tham khảo tài liệu mô tả này.)
Một giải pháp sẽ có thêm hệ thống dấu ngoặc đơn để tất cả các loại chức năng trong .mli
, nhưng Tôi lo sợ điều này có thể dẫn đến sự thiếu hiệu quả. Khác sẽ là để phát hiện các chức năng tính toán và thêm dấu ngoặc đơn các loại tương ứng trong .mli
. Một giải pháp thứ ba sẽ là η-mở rộng các trường hợp rõ ràng, và ngoặc đơn những người khác.
Tôi không đủ quen thuộc với nội dung F #/CLR để đo lường nội dung nào có hiệu suất đáng kể hoặc giao tiếp hình phạt.
Chỉ cần làm cho nó 'val g: ('a ->' a)'. Nó là một tính năng/lỗi đã biết của hệ thống kiểu F #. –
Một lần nữa, "chỉ cần làm cho nó" - có lẽ nếu λ biểu thức và chức năng tính toán không có các loại hoán đổi cho nhau, đó là lý do chính đáng. Hơn nữa, đây là mã được tạo tự động, do đó vấn đề phức tạp hơn một chút so với việc thêm một vài dấu ngoặc đơn bằng tay ... –
Có sự khác biệt giữa hai trường hợp này, một được biên dịch thành một phương thức và phương thức kia thành một giá trị tĩnh. Func 'thuộc tính. Tính tương thích không phải là hai chiều (nghĩa là, 'a -> b: <: (a -> b)', nhưng không phải là '(a -> b): <: a -> b'). –