2015-12-09 101 views
0

我做的東西真的錯了基本的功能,但我不能,我的生活,工作,它是什麼?運行遞歸F#

let rec testItSeveralTimes (test, times) = 
     printfn "Iterations to go %O" times 
     match times with 
      | 0 ->() 
      | _ -> 
       test 
       testItSeveralTimes (test, (times - 1)) 

    testItSeveralTimes ((printfn "Running a test"), 2) 

我想到的是:

Iterations to go 2 
Running a test 
Iterations to go 1 
Running a test 
Iterations to go 0 
Running a test 
val it : unit =() 

我得到的是:

Running a test 
Iterations to go 2 
Iterations to go 1 
Iterations to go 0 
val it : unit =() 

好像功能被計算一次,一開始,然後忽略。 (Wrapping a function with an indeterminate number of parameters in F#)似乎有答案,但沒有。

回答

5

如果你解壓出來test參數轉換成一個單獨的步驟, 問題變得很明顯:

let test = printfn "Running a test" 
// expression has run and printed already! 
// value of "test" is a simple value (unit) now 
testItSeveralTimes (test, 2) 

作爲評估let test =的一部分表達方式,printfn 函數立即運行

然後,test被賦值爲(),這是printfn

testItSeveralTimes輸出,測試的價值就在那裏,但不 做任何事情。

正如約翰說,你需要做的test參數是可以運行的函數:

let rec testItSeveralTimes (test, times) = 
    printfn "Iterations to go %O" times 
    match times with 
     | 0 ->() 
     | _ -> 
      test() // test parameter is now a function 
      testItSeveralTimes (test, (times - 1)) 

隨着這一變化,您還需要定義test值作爲功能 不運行立刻:

let test() = printfn "Running a test" 
// value of test is a function and is not run yet 
testItSeveralTimes (test, 2) 

作爲一般規則,如果你有問題的理解是怎麼回事,試圖打破了所有步驟爲這樣的獨立價值 - 它可以更容易調試,因爲你可以evaluat每個人依次(在F#Interactive或REPL中)看看會發生什麼!

2

此處的測試值爲unit

你想要的東西,像

testItSeveralTimes ((fun _ -> printfn "Running a test"), 2) 

和改變使用到

test() 
+0

我改成了這樣: 讓REC testItSeveralTimes(測試時間)= printfn「迭代走%氧氣」與 倍 比賽時間| 0 - >() | _ - > 試驗(+) testItSeveralTimes(測試(時間 - 1)) testItSeveralTimes((FUN _ - > printfn 「運行測試」),2) 和它的作品,但我不知道爲什麼。是否因爲test()強迫它被評估爲函數? –