2017-06-14 21 views
17

Operators.id<'T> Function (F#)FSharp.Core中`id`函數的用途是什麼?

身份函數。

參數:x類型:「T(輸入值)

返回值:相同的值

F#核心庫版本,支持的:2.0,4.0,便攜式

爲什麼有沒有一個函數返回它的輸入?

+3

有趣的是還要注意數學背景。有一個'無所作爲'的對象提供了重要的結構。由於零是加法下的數字的同一性,並且一個是乘法下的數字的同一性,所以'id'是組合下的一組函數的標識。在函數式語言中,你經常需要將函數作爲對象進行操作,對它們執行操作等。 –

+0

@matt_t_gregg如果你將它作爲答案發布,我相信你會得到不少讚揚。 –

+0

@FyodorSoikin我很高興你的答案涵蓋了爲什麼需要和使用它的實用性 - 我認爲數學的東西更有趣。 –

回答

24

與高階函數時(即返回其他功能和/或採取其他功能參數的函數),你總是必須提供東西作爲參數,但並不總是實際數據轉換,你想申請。

例如,函數Seq.collect將一系列序列展平,並接受一個函數,該函數爲「外」序列的每個元素返回「嵌套」序列。例如,這就是你怎麼可能得到某種形式的UI控件的所有孫子的列表:

let control = ... 
let allGrandChildren = control.Children |> Seq.collect (fun c -> c.Children) 

但很多次,序列的每個元素都已經被自己的序列 - 例如,你可能有一個列表的列表:

let l = [ [1;2]; [3;4]; [5;6] ] 

在這種情況下,你傳遞給Seq.collect需要參數的函數只返回參數:

let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect (fun x -> x) 

這EXPRES sion fun x -> x是剛剛返回其參數的函數,也稱爲「標識函數」。

let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect id 

其用法作物向上所以經常與高階函數(例如上面Seq.collect),它值得在標準庫的地方工作時。

另一引人注目的例子是Seq.choose - 用於過濾Option值的序列,並在同一時間解開他們的功能。例如,這是你會如何解析字符串的所有數字和拋棄那些無法解析:

let tryParse s = match System.Int32.TryParse s with | true, x -> Some x | _ -> None 
let strings = [ "1"; "2"; "foo"; "42" ] 
let numbers = strings |> Seq.choose tryParse // numbers = [1;2;42] 

但如果你已經給Option值的列表開始嗎?身份識別功能的救援!

let toNumbers optionNumbers = 
    optionNumbers |> Seq.choose id 
+0

'Seq.choose id'示例是一個很好的例子,但是'Seq.collect id'只是一種不太可讀的說'Seq.concat'的方式。 (也就是說,我很確定我已經寫了'Seq.collect id'多次,它說明了'id'做得好!) –

11

這對於某些高階函數(函數取函數作爲參數),這樣就可以通過id作爲參數,而不是寫出來的拉姆達(fun x -> x)有用。

[[1;2]; [3]] |> List.collect id // [1; 2; 3] 
+0

在這種情況下,您可以使用'List.concat',它會更具可讀性:-)。 –

相關問題