Reputation: 24403
So I have a function that I've pulled from a tutorial:
let sumOfSquares nums =
nums
|> Seq.map sqr
|> Seq.sum
I have decided that I want to test its performance. In a brute-force approach, I would do something like:
let timeFunction nums =
let sw = new System.Diagnostics.Stopwatch()
sw.Start()
nums
|> Seq.map sqr
|> Seq.sum
sw.Stop()
sw.ElapsedMilliseconds
However, this struck me as a good example for how F# is supposed to treat functions as first-class citizens. So I tried to do something like the following, instead:
let timeFunction fn x =
let sw = new System.Diagnostics.Stopwatch()
sw.Start()
fn x
sw.Stop()
sw.ElapsedMilliseconds
And then I tried to call it:
let sequenceOfNums = [for i in 1..20 -> i]
let print n = System.Console.WriteLine(n.ToString())
print "Time Trial"
print (timeFunction sumOfSquares sequenceOfNums)
However, this fails with the following error:
Type mismatch. Expecting a 'a -> unit but given a 'a -> int The type 'unit' does not match the type 'int'
on the line that calls the function. Do I have some sort of syntactical error here, or have I grossly misunderstood a concept?
Upvotes: 2
Views: 160
Reputation: 47904
Because the result of fn
isn't being used it's inferred to be unit
. You can fix this by piping the result to the ignore
function. It's signature is 'a -> unit
, so it makes the return type of fn
generic (which is what you want).
let timeFunction fn x =
let sw = new System.Diagnostics.Stopwatch()
sw.Start()
fn x |> ignore
sw.Stop()
sw.ElapsedMilliseconds
Upvotes: 4