9

OCamlで関数を定義する前に宣言する方法はありますか?私はOCamlインタプリタを使用しています。それが作られる前myFunctionAがmyFunctionBを呼び出すことはできませんので、OCaml:定義する前に関数を宣言する

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

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

これは、しかし動作しません:

私は2つの機能を持っています。

私はいくつかのGoogle検索を実行しましたが、何も見つかりませんでした。どうすればこれを達成できますか?

+0

関連キーワード: "ocaml corecursive function" [OCamlに関するメモ:相互再帰関数](http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutually%20recursive%20functions)を参照してください。 –

+1

私は、相互再帰を意味する同時再帰を聞いたことがあるとは言えませんが、それは何を意味するのかはかなり明らかです。 – nlucaroni

答えて

21

あなたが望むのは、これらの2つの機能を相互に再帰的にすることです。次のようにする代わりに「聞かせて... ...てみましょう」を使用して、あなたは「... ... RECせて、」使用する必要があります:

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

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

は実は「RECてみましょう..」非常に深刻なを持っています制限:単一のモジュール内でのみ動作します。これは、プログラマが大きなモジュールを書かないように強制します。

いくつかの回避策がありますが、いずれも不満足です。最初に、関数型の変数を作成し、最初に例外を発生させる関数を格納し、その後、目的の値を格納します。

2番目は、クラスの種類とクラス(および1つの間接参照)を使用することです。相互に再帰的な関数がたくさんある場合、これは(各オブジェクトに単一のオブジェクトを渡すだけでよいため)最良の方法です。

最も簡単で最も醜いのは、関数を引数として渡すことです。これは、すぐに制御が外れる解決策です。すべての定義に従ったモジュールでは、 "let rec"ラッパーのセットを導入することで、呼び出しコードを単純化することができます。残念ながら、これは関数の定義に役立つものではなく、ほとんどの呼び出しはそのような定義で行われることが一般的です。

+0

これは再帰的なモジュールによって幾分緩和されていることに注意してください。例えば:http://stackoverflow.com/a/33482273/2482998。しかし、まだかなり厄介です。 – antron

関連する問題