9

Czy istnieje sposób deklarowania funkcji przed jej zdefiniowaniem w OCaml? Używam interpretera OCaml.OCaml: Deklaracja funkcji przed jej zdefiniowaniem

Mam dwie funkcje:

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

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

to nie zadziała jednak, ponieważ myFunctionA nie można nazwać myFunctionB zanim zostanie wykonany.

Zrobiłem kilka wyszukiwań google, ale nie mogę znaleźć niczego. Jak mogę to zrobić?

+0

Istotne słowa kluczowe: "funkcja rdzeniowania ocaml". Zobacz [Uwagi na temat OCaml: Wzajemnie rekursywne funkcje] (http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutual%20recursive%20functions). –

+1

Nie mogę powiedzieć, abym kiedykolwiek usłyszał współrekurencję, która sugerowałaby wzajemną rekurencję - choć oczywiste jest, co by to miało znaczyć. – nlucaroni

Odpowiedz

21

To, czego chcesz, to sprawić, aby te dwie funkcje były wzajemnie rekurencyjne. Zamiast korzystać z "niech ... niech ...", trzeba użyć "let rec ... i ..." w następujący sposób:

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

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

Właściwie "let rec .." ma bardzo poważne ograniczenie: działa tylko w ramach jednego modułu. Zmusza to programistę do pisania dużych modułów tam, gdzie nie jest to pożądane. Problem, który nie występuje w niskim C!

Istnieje kilka obejść, wszystkie są niezadowalające. Pierwszym z nich jest utworzenie zmiennej typu funkcji i początkowo przechowywanie funkcji podnoszącej w niej wyjątek, a następnie zapamiętanie żądanej wartości.

Drugi to użycie typów klas i klas (i jednego kierunku pośredniego). Jeśli masz wiele funkcji rekurencyjnych, to jest to najlepszy sposób (ponieważ musisz przekazać tylko jeden obiekt do każdego z nich).

Najprostszym i najbardziej brzydkim jest przekazywanie sobie nawzajem funkcji jako argumentów, rozwiązanie, które szybko wymyka się spod kontroli. W module zgodnym ze wszystkimi definicjami można uprościć kod wywołujący, wprowadzając zestaw wrapperów "let rec". Niestety, nie pomaga to w definiowaniu funkcji, i często zdarza się, że większość wywołań pojawia się w takich definicjach.

+0

Zauważ, że moduły rekursywne są teraz nieco złagodzone, na przykład: http://stackoverflow.com/a/33482273/2482998. Wciąż jest jednak dość niezręcznie. – antron

Powiązane problemy