9

Có cách nào để khai báo hàm trước khi xác định hàm trong OCaml không? Tôi đang sử dụng một thông dịch viên OCaml.OCaml: Khai báo hàm trước khi xác định hàm

Tôi có hai chức năng:

let myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *) 

let myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *) 

này không hoạt động mặc dù, kể từ myFunctionA không thể gọi myFunctionB trước khi nó thực hiện.

Tôi đã thực hiện một vài tìm kiếm trên google nhưng dường như không thể tìm thấy bất kỳ thứ gì. Làm thế nào tôi có thể thực hiện điều này?

+0

Từ khóa có liên quan: "ocaml corecursive function". Xem [Ghi chú về OCaml: Chức năng đệ quy lẫn nhau] (http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutually%20recursive%20functions). –

+1

Tôi không thể nói rằng tôi đã bao giờ nghe đồng đệ quy để ngụ ý đệ quy lẫn nhau - mặc dù, nó là khá rõ ràng những gì sẽ có nghĩa là. – nlucaroni

Trả lời

21

Điều bạn muốn là làm cho hai hàm này đệ quy cùng nhau. Thay vì sử dụng "let ... let ...", bạn phải sử dụng "let rec ... và ..." như sau:

let rec myFunctionA = 
(* some stuff here..... *) myFunctionB (*some stuff *) 

and myFunctionB = 
(* some stuff here .... *) myFunctionA (* some stuff *) 
2

Thực ra "let rec .." rất nghiêm trọng giới hạn: nó chỉ hoạt động trong một mô-đun duy nhất. Điều này buộc các lập trình viên viết các mô-đun lớn, nơi nó không phải là mong muốn .. một vấn đề mà không xảy ra trong C thấp!

Có một số cách giải quyết, tất cả đều không đạt yêu cầu. Đầu tiên là tạo một biến của kiểu hàm và ban đầu lưu trữ một hàm nâng cao một ngoại lệ trong nó, sau đó lưu trữ giá trị mong muốn.

Cách thứ hai là sử dụng các loại và lớp học (và một hướng dẫn). Nếu bạn có rất nhiều hàm đệ quy lẫn nhau thì đây là cách tốt nhất (vì bạn chỉ cần truyền một đối tượng cho mỗi đối tượng).

Cách dễ nhất và xấu nhất là chuyển các hàm này với nhau dưới dạng đối số, một giải pháp nhanh chóng vượt khỏi tầm kiểm soát. Trong một mô-đun theo tất cả các định nghĩa, bạn có thể đơn giản hóa mã gọi bằng cách giới thiệu một bộ trình bao bọc "let rec". Thật không may, điều này không giúp xác định các chức năng, và nó là phổ biến mà hầu hết các cuộc gọi sẽ xảy ra trong các định nghĩa như vậy.

+0

Lưu ý rằng điều này bây giờ phần nào được giảm bớt bởi các mô-đun đệ quy, ví dụ như vậy: http://stackoverflow.com/a/33482273/2482998. Nó vẫn còn khá khó xử, tuy nhiên. – antron