Sự khác biệt giữa ứng dụng currying và một phần chức năng trong thực tế là gì


8

Tôi hiểu sự khác biệt giữa ứng dụng chức năng một phần và chức năng được xử lý ( f(X x Y x Z) -> Nvs f(X -> (Y -> (Z -> N)))), nhưng tôi không thấy hậu quả của sự khác biệt này là gì khi phát triển phần mềm.

Câu trả lời:


5

Ban đầu, currying là để đơn giản hóa phân tích, thay vì một kỹ thuật lập trình thực tế; trong phép tính lambda, tất cả các hàm là đơn nguyên. Currying thường được sử dụng ở cấp độ ngôn ngữ vì một lý do tương tự: đơn giản hóa mô hình tính toán.

Ứng dụng một phần được sử dụng khi một chức năng hữu ích có tên có thể được triển khai theo nghĩa khác, một chức năng tổng quát hơn chỉ đơn giản bằng cách sửa một đối số.

Chúng vẫn là các hình thức riêng biệt, liên quan đến các phần khác nhau của tính toán. Xem xét:

x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)

Lưu ý rằng hàm được xử lý không có bất kỳ giá trị nào bị ràng buộc với các đối số và đưa các đối số theo một thứ tự cụ thể; một khi bạn cà ri một chức năng, bạn không cà ri kết quả và không thay đổi thứ tự mà chức năng đó đưa ra đối số (mặc dù bạn có thể mở khóa và cà ri để làm như vậy). Ngược lại, một phần hàm có các giá trị ràng buộc với các đối số và có thể được áp dụng thêm một phần dọc theo bất kỳ đối số còn lại nào.

Áp dụng một hàm curried gần với ứng dụng một phần (rốt cuộc, bạn không nên sử dụng một hàm và để nó ở đó; đến một lúc nào đó, bạn sẽ áp dụng nó), đó là nơi sử dụng bắt đầu vượt qua. Khi bạn làm điều này, cà ri chỉ là bước đầu tiên trong hai bước hướng tới ứng dụng một phần.


2

Tôi tin rằng câu hỏi của bạn có thể được nhắc lại như: tại sao các ngôn ngữ có cà ri?

Đây chủ yếu là một câu hỏi về sự thuận tiện:

Trong Ocaml, bạn có thể mã

 let sum3 x y z = x + y + z;;
 let foo xx yy ll = List.map (sum3 xx yy) ll;;

Trong Đề án, bạn cần phải thực hiện một chức năng ẩn danh

 (define (sum3 x y z) (+ x y z))
 (define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))  

Các ngôn ngữ có ứng dụng một phần & currying thực tế cần phải có sự tối ưu hóa để tránh tạo ra sự đóng cửa một phần ở mọi nơi; bạn không muốn việc triển khai luôn được áp dụng sum3như thể nó được định nghĩa là

 let sum3 x = 
    fun y -> 
      (fun z -> x + y + z)

nghĩa là, để phân bổ 2 lần đóng trung gian khi tính toán sum3 1 2 3(được hiểu và phân tích thành ((sum3 1) 2) 3...). Bạn muốn tổng được tính ngay lập tức.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.