2013-11-27 164 views
0

我想在SML中實現遞歸調用函數。我的代碼是SML遞歸調用函數

CM.make "$cml/cml.cm"; 
open CML; 
fun sender n()= if (n<100) 
then 
(
TextIO.print (Int.toString(n)^"\n"); 
sender n+1 
) 
else 
exit() 

fun main() = let 
    val _ = spawn (sender 3); 
    val tid1 = getTid(); 
in 
    TextIO.print("MY TID"^(tidToString tid1)^"\n") 
end; 
RunCML.doit(main, NONE); 

我提示以下錯誤:

Cml.sml:3.5-10.8 Error: right-hand-side of clause doesn't agree with function result type [circularity] expression: unit -> 'Z result type: 'Z in declaration: sender = (fn arg => (fn <pat> => <exp>))

我在做什麼錯?

回答

1

你的功能sender開始與

fun sender n()= ... 

這使得它的類型

sender : int -> unit -> 'a 

,因爲你需要爲你在main定義。但是,當你以後遞歸調用它,你把它作爲

sender n+1 

現在,即使你寫爲

sender (n+1) 

才能得到正確的優先級,你仍然可以得到,而你想要的類型unit -> 'a類型'a。因此,所有你需要做的是通過一個額外() : unit它,你sender功能類型檢查:

fun sender n() = 
    if (n<100) 
    then (
     TextIO.print (Int.toString(n)^"\n"); 
     sender n+1()) 
    else exit() 
+0

由於工作就像一個魅力,我對在SML()運算符有些懷疑我的代碼工作,如果我刪除。並且在調用sender時不要傳遞(),那麼在代碼中使用它有什麼意義? – user2433145

+0

你可以定義'fun sender'n = ...',它可以在沒有額外的'()'的情況下很好地工作,但後來你想用'spawn'來產生一個並行執行'sender'的線程。按照設計,'spawn'需要一個'unit - > unit',所以你必須使用'sender'來符合這個。當然,你可以通過'spawn(fn()=> sender'3)'來做到這一點。 – creichen