我正在做一些非常基本的错误,但我不能,因为我的生活,弄清楚它是什么......
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#)似乎有答案,但没有。
答案 0 :(得分: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的值就在那里,但没有
做任何事。
正如约翰所说,你需要让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)
作为一般规则,如果您在理解正在发生的事情时遇到问题,请尝试将所有步骤分解为单独的值 - 这样可以更容易调试,因为您可以依次评估每个步骤(在F#Interactive中)或REPL)看看会发生什么!
答案 1 :(得分:2)
此处test的值为unit
。
你想要像
这样的东西testItSeveralTimes ((fun _ -> printfn "Running a test"), 2)
并将使用情况更改为
test()