2015-12-06 40 views
2

我在看,我在一個培訓班看到的和無法理解,在下面的函數結束時使用「()」函數:函數簽名爲什麼會在其他參數之後有單位參數?

let acclock (start:DateTimeOffset) rate() = 
    let now = DateTime.Now 
    let elapsed = now - start 
    start.AddTicks (elapsed.Ticks * rate) 

爲什麼一個函數簽名必須在一個單元參數其簽名上的其他參數結束?

因此,我認爲一個單位參數意味着沒有參數或返回類型,它將類似於「void」。

+1

只是FYI;在像F#這樣的FPL中,像'unit - > int'這樣的函數意味着它是一個取單位值的函數。不像它通常用C語言來解釋;一個不帶值的函數。這對我來說是FP比C語言更多的小好處之一。在C#中,你通常需要對'void'情況進行特殊處理(比如'Task'和'Task <>')。在F#中,函數總是獲取並返回一個值,該單元值不需要特殊處理。它被稱爲單位的原因是因爲它映射到「單位」類別,這是一個只有一個值的類別。 – FuleSnabel

回答

7

這與部分應用程序有關。您可以將此函數綁定到另一個名稱,同時提供startrate參數,從而創建類型爲() -> DateTime的函數。只有當您調用該函數時,纔會執行「elapsed = now - start」和「start.AddTicks」的計算。就像這樣:

let timeThis = 
    let stopClock = acclock DateTime.Now 500 
    doStuff() 
    stopClock() // The function is only executed now 

如果你不會有在年底()參數,你會直接如果添加rate值執行該語句。

let acclock' (start:DateTimeOffset) rate = 
    let now = DateTime.Now 
    let elapsed = now - start 
    start.AddTicks (elapsed.Ticks * rate) 

let timeThis1 = 
    let stopClock = acclock' DateTime.Now 
    doStuff() 
    stopClock 500 // This is only executed now 

// Or 
let timeThis2 = 
    let stopClock = acclock' DateTime.Now 500 // Wait, we calculated it immediately 
    doStuff() 
    stopClock // This is just a value 
4

有了額外的(),您可以通過startrate參數並獲得部分應用函數unit -> DateTime

let partiallyAppliedAcclock = acclock DateTime.Now 1L 

val partiallyAppliedAcclock : (unit -> System.DateTime) 

沒有(),這將是一個DateTime值。

let acclockValue = acclock2 DateTime.Now 1L // acclock defined without() 

val acclockValue : DateTime = 06-12-15 3:20:41 PM 

的差別不是純函數(你可以隨時替換其值設置爲一個純函數的調用)很重要,但acclock不純正。它使用DateTime.Now,所以每次調用結果都會有所不同。

相關問題