2011-12-12 29 views
5

Tôi tự hỏi tại sao chúng ta cần chức năng như "% identity", giống như let a = a. Nó sẽ cải thiện hiệu suất bằng cách sử dụng nó?ocaml% identity function

Tôi đang giới thiệu đánh máy ảo trong chương trình của mình, gọi hàm nhận dạng một lần để chuyển đổi loại, tò mò nếu "% nhận dạng" có thể giảm một chút chi phí.

Trả lời

10

Chức năng %identity là một phần của quá trình triển khai, không phải là một phần của ngôn ngữ OCaml. Nó nói với trình biên dịch (về bản chất) rằng không có gì để làm để thay đổi tham số của hàm thành giá trị trả về của nó. Nói cách khác, nó cho trình biên dịch tiếp tục sử dụng cùng một giá trị nhưng để thay đổi ý tưởng của nó về kiểu. Nếu được sử dụng không chính xác, về cơ bản nó sẽ che giấu tất cả các đảm bảo an toàn tuyệt vời của hệ thống loại OCaml. Ngoài ra, tất nhiên, nó không được đảm bảo để làm việc trong bất kỳ triển khai ngôn ngữ nào khác (bao gồm cả các phiên bản tương lai của trình biên dịch INRIA).

Khả năng nội tuyến của trình biên dịch OCaml đã đảm bảo rằng không có mã nào được tạo cho các hàm nhận dạng. Vì vậy, tôi khuyên bạn nên tiếp tục sử dụng chúng.

Cập nhật

Để trả lời một câu hỏi không liên quan trong các ý kiến ​​.... Giả sử bạn có hàm hợp và hàm sắc:

let (<<) f g x = f (g x) 
let id x = x 

Sau đó, đây là chức năng để thêm các yếu tố của một danh sách, để nhân các yếu tố của danh sách và để soạn tất cả các chức năng trong danh sách:

# let sum l = List.fold_right (+) l 0;; 
val sum : int list -> int = <fun> 
# let product l = List.fold_right (*) l 1;; 
val product : int list -> int = <fun> 
# let composition l = List.fold_right (<<) l id;; 
val composition : ('a -> 'a) list -> 'a -> 'a = <fun> 

Ví dụ s:

# sum [2; 3; 5; 7];; 
- : int = 17 
# product [2; 4; 17];; 
- : int = 136 
# let mx = composition [(+) 1; (*) 10];; 
val mx : int -> int = <fun> 
# mx 2;; 
- : int = 21 

Điểm là 0 là nhận dạng để thêm, 1 cho phép nhân và id cho thành phần chức năng. id hữu ích mọi lúc, giống như 0 và 1.

+0

Khi nào chúng tôi sử dụng chức năng 'identity' (không nhất thiết là'% identity') bình thường? –

+0

Điều này phần nào giống như hỏi khi chúng ta sử dụng các số 0 và 1. Trong một ngôn ngữ mà các hàm là các giá trị hạng nhất, hàm nhận dạng rất hữu ích. –

+0

xin lỗi, tôi đoán câu hỏi của tôi nên giống như bạn có thể vui lòng cho tôi một trường hợp hữu ích trong đó 'let f x = x' phải là hoặc phải được sử dụng? –

1

Sử dụng %identity làm nguyên thủy ở nước ngoài có thể và sẽ giảm chi phí liên quan đến việc đánh giá việc đóng cửa (fun x -> x) mỗi khi được áp dụng.

Các OCaml trình biên dịch đặc biệt hợp cụ thể các % nguyên thủy: bytecomp/translcore.ml cộng mỗi một với một đặc biệt tích hợp nút AST (trong trường hợp của %identity nó được ánh xạ tới các Pidentity); trình biên dịch khớp với nút và đơn giản hóa biểu thức được áp dụng cho. Trong trường hợp của trình biên dịch bản xứ, các dòng liên quan là:

  • asmcomp/closure.ml dòng 197 và ss .: đơn giản hóa %identity áp dụng cho một cuộc tranh luận liên tục để các lập luận riêng của mình:

    begin match p with 
        Pidentity -> make_const_int x 
    | Pnegint -> make_const_int (-x) 
    
  • asmcomp/cmmgen.ml dòng 1047 và ss .: đơn giản hóa %identity làm LHS của ứng dụng để đánh giá đối số trực tiếp:

    match p with 
        (* Generic operations *) 
        Pidentity -> 
         transl arg 
    

Trình biên dịch mã byte có các quy tắc đơn giản hóa tương tự cho nguyên thủy.