9

在OCaml中定義它之前是否有辦法聲明一個函數?我正在使用OCaml解釋器。OCaml:在定義它之前聲明一個函數

我有兩個功能:

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

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

這不工作,雖然,因爲myFunctionA不能稱之爲myFunctionB它是由前。

我已經做了幾次谷歌搜索,但似乎無法找到任何東西。我怎樣才能做到這一點?

+0

相關關鍵字:「ocaml corecursive function」。參見[關於OCaml:相互遞歸函數的註釋](http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#Mutually%20recursive%20functions)。 – 2011-09-30 17:06:25

+1

我不能說我曾經聽說過共遞歸意味着相互遞歸 - 儘管這很明顯是什麼意思。 – nlucaroni

回答

21

你想要的是使這兩個函數相互遞歸。而不是使用「let ... let ...」,你必須使用「let rec ...和...」,如下所示:

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

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

其實「let rec ..」有一個很嚴重限制:它只能在單個模塊中使用。這迫使程序員在不需要的地方編寫大型模塊..一個不會發生在低C的問題!

有幾種解決方法,都不令人滿意。首先是創建一個函數類型的變量,並最初存儲一個引發異常的函數,然後存儲所需的值。

第二個是使用類的類和類(和一個間接的)。如果你有很多相互遞歸的函數,這是最好的方法(因爲你只需要傳遞一個對象給它們)。

最簡單也是最醜陋的是將函數作爲參數傳遞給對方,這是一種快速失控的解決方案。在遵循所有定義的模塊中,您可以通過引入一組「let rec」包裝來簡化調用代碼。不幸的是,這並不能幫助定義函數,而且大多數調用都會出現在這樣的定義中。

+0

請注意,現在這可以通過遞歸模塊稍微緩解,例如像這樣:http://stackoverflow.com/a/33482273/2482998。但是,這仍然很尷尬。 – antron