我正在做一些非常基本的错误,但我不能,因为我的生活,弄清楚它是什么......
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 = ()
似乎函数在开始时被评估一次,然后被忽略.
这个问题(在F#中包含一个具有不确定数量参数的函数)似乎有一个答案,但没有.
如果将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)
作为一般规则,如果您在理解正在发生的事情时遇到问题,请尝试将所有步骤分解为单独的值 - 这样可以更容易调试,因为您可以依次评估每个步骤(在F#Interactive或REPL中)看看会发生什么!