Câu trả lời:
Có ba cách tiếp cận chính (mà tôi biết) để thực hiện các chức năng bậc cao. Khử nhiễu, chuyển đổi đóng / nâng lambda và tổ hợp.
Hãy ghi cho các loại hình của một hàm bậc cao từ A đến B và A → B cho các loại con trỏ chức năng C-phong cách từ A đến B . (Nếu chúng ta muốn chính thức hóa điều này, chúng ta có thể nói rằng sự trừu tượng hóa con trỏ hàm chỉ được phép trong môi trường trống.)
Nâng Lambda có một cách tiếp cận hơi khác và toàn cầu hơn, trong đó một sự trừu tượng hóa lambda được kéo ra ngoài để chứa phạm vi thêm các biến miễn phí làm tham số trên đường đi, cho đến khi đạt đến phạm vi cấp cao nhất. Trong khi điều này liên quan đến cấu trúc khối, để thực sự xử lý các hàm sử dụng bậc cao hơn đòi hỏi phải cho phép ứng dụng một phần. Sau đó, bạn có thể chuyển qua các hàm được áp dụng một phần, nhưng về cơ bản, đây là biểu diễn giống như chuyển đổi đóng.
Nếu bạn muốn loại bỏ các con trỏ hàm, chúng ta có thể sử dụng hàm khử, trong trường hợp đặc biệt này, chỉ cần tạo ra một phép liệt kê. Có rất ít lý do để làm điều này, vì các con trỏ hàm là các cấu trúc tự nhiên trong hầu hết các ngôn ngữ lắp ráp.
Cách tiếp cận là sử dụng tổ hợp. Điều này về cơ bản giống như nâng lambda và sử dụng các ứng dụng một phần ngoại trừ một bộ chức năng cấp cao nhất định được sử dụng và tất cả các chức năng khác được thể hiện dưới dạng kết hợp của các chức năng đó. (Nếu họ không có bộ tổ hợp cố định được xác định trước, thì đây thường chỉ là cách tiếp cận dựa trên nâng lambda như tôi đã mô tả ở trên.) Hàm bậc cao hơn sau đó sẽ được biểu thị một cách hiệu quả bằng một giá trị trong kiểu dữ liệu bằng cú pháp Haskell như sau (sử dụng SK
tổ hợp ):
data CA = S | K | App CA CA -- plus other things in reality, like primitive values
Một đại diện giống như tính toán cột sống có lẽ có ý nghĩa hơn cho hiệu quả. Hoặc bạn có thể làm một cái gì đó như:
data CA = S0 | S1 CA | S2 CA CA | K0 | K1 CA
Áp dụng một hàm bậc cao hơn sẽ chia thành hai trường hợp: hoặc một tổ hợp đã được áp dụng đầy đủ và do đó nó sẽ được thực thi hoặc chúng ta trả về một giá trị mới đại diện cho ứng dụng (một phần).
Tôi chưa thực hiện một khảo sát toàn diện, nhưng tôi khá tự tin về các biến thể của chuyển đổi đóng là chiến lược thực hiện phổ biến nhất cho các hàm bậc cao hơn (do đó chúng thường được gọi là "đóng"). Nó có các đặc tính tốt là mô-đun, đơn giản và hiệu quả hợp lý ngay cả ở dạng ngây thơ của nó. Cần có một sự lựa chọn tốt về các tổ hợp cơ sở và một số thông minh để có được các phương pháp dựa trên tổ hợp để thực hiện tốt. Khử nhiễu không được sử dụng rộng rãi như tôi có thể nói, nhưng có rất ít lý do để không tận dụng các con trỏ hàm. Trong phạm vi mà bạn làm, ví dụ thay vì phân tích trường hợp lớn, bạn có một bảng các con trỏ hàm mà bạn lập chỉ mục, về cơ bản bạn đã tạo lại chuyển đổi đóng.
Có một số cách tiếp cận khác. Một là khởi tạo mẫu về cơ bản để thực hiện -redtion theo nghĩa đen và chỉ đơn giản là thay thế các thuật ngữ thành các thuật ngữ khác. Thông thường, điều này đòi hỏi phải có và thao tác một cấu trúc giống như cú pháp trừu tượng. Các hàm bậc cao hơn sau đó được biểu diễn bằng các thuật ngữ lambda (cú pháp) hoặc "mẫu" của chúng để có thể đơn giản hóa việc thực hiện các thay thế.