2012-02-10 173 views
2

所以我有,我已經從一個教程拉到功能:如何在另一個函數中嵌入函數調用?

let sumOfSquares nums = 
    nums 
    |> Seq.map sqr 
    |> Seq.sum 

我已經決定了,我要測試其性能。在蠻力的方法,我會做這樣的事情:

let timeFunction nums = 
    let sw = new System.Diagnostics.Stopwatch() 
    sw.Start() 
    nums 
     |> Seq.map sqr 
     |> Seq.sum 
    sw.Stop() 
    sw.ElapsedMilliseconds 

然而,這給我的印象很好的例子爲F#應該如何治療功能一等公民。於是,我像做以下,而不是:

let timeFunction fn x = 
    let sw = new System.Diagnostics.Stopwatch() 
    sw.Start() 
    fn x 
    sw.Stop() 
    sw.ElapsedMilliseconds 

然後我試圖把它叫做:

let sequenceOfNums = [for i in 1..20 -> i] 
let print n = System.Console.WriteLine(n.ToString()) 
print "Time Trial" 
print (timeFunction sumOfSquares sequenceOfNums) 

然而,這種失敗,出現以下錯誤:

Type mismatch. Expecting a 'a -> unit but given a 'a -> int The type 'unit' does not match the type 'int'

在調用該函數的行上。我在這裏是否有某種語法錯誤,或者我是否嚴重誤解了一個概念?

回答

4

由於fn的結果未被使用,因此推斷爲unit。您可以通過將結果傳遞給ignore函數來解決此問題。它的簽名是'a -> unit,所以它使返回類型fn通用(這是你想要的)。

let timeFunction fn x = 
    let sw = new System.Diagnostics.Stopwatch() 
    sw.Start() 
    fn x |> ignore 
    sw.Stop() 
    sw.ElapsedMilliseconds 
+0

而管道忽略不會導致它被優化掉或什麼,對吧? – GWLlosa 2012-02-10 02:48:24

+0

對。它絕對不會。 – Daniel 2012-02-10 02:58:44

相關問題