Reputation: 136
I am doing something really basic wrong, but I can't, for the life of me, work out what it is...
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)
What I expect is:
Iterations to go 2
Running a test
Iterations to go 1
Running a test
Iterations to go 0
Running a test
val it : unit = ()
What I get is:
Running a test
Iterations to go 2
Iterations to go 1
Iterations to go 0
val it : unit = ()
It seems like the function is being evaluated once, at the beginning, and then ignored.
This question (Wrapping a function with an indeterminate number of parameters in F#) seemed to have an answer, but no.
Upvotes: 0
Views: 74
Reputation: 2764
If you extract out the test
parameter into a separate step,
the problem becomes obvious:
let test = printfn "Running a test"
// expression has run and printed already!
// value of "test" is a simple value (unit) now
testItSeveralTimes (test, 2)
As part of evaluating the let test =
expression, the printfn
function is run immediately.
Then, test
is assigned the value ()
, which is the output of printfn
Inside testItSeveralTimes
, the value of test is just there, but doesn't
do anything.
As John said, you need to make the test
parameter be a function that can be run:
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))
With this change, you also need to define the test
value as a function that
is not run immediately:
let test() = printfn "Running a test"
// value of test is a function and is not run yet
testItSeveralTimes (test, 2)
As a general rule, if you are having problems understanding what is going, try breaking out all the steps into separate values like this -- it makes it easier to debug, because you can evaluate each one in turn (in F# Interactive or REPL) and see what happens!
Upvotes: 5
Reputation: 25516
Here test has a value of unit
.
You want something like
testItSeveralTimes ((fun _ -> printfn "Running a test"), 2)
and change the usage to
test()
Upvotes: 2