FSharp.Core中`id`函数的用途是什么?

MiP*_*MiP 26 .net f# identity

来自Operators.id <'T>功能(F#):

身份功能.

参数:x类型:'T(输入值)

返回值:相同的值

F#核心库版本,支持:2.0,4.0,Portable

为什么有一个返回其输入的函数?

Fyo*_*kin 30

使用高阶函数(即返回其他函数和/或将其他函数作为参数的函数)时,您始终必须提供某些参数,但并不总是需要应用的实际数据转换.

例如,该函数展Seq.collect平序列序列,并获取一个函数,该函数返回"外部"序列的每个元素的"嵌套"序列.例如,这是您可以获得某种UI控件的所有孙子列表的方式:

let control = ...
let allGrandChildren = control.Children |> Seq.collect (fun c -> c.Children)
Run Code Online (Sandbox Code Playgroud)

但很多时候,序列的每个元素本身都已经是一个序列 - 例如,你可能有一个列表列表:

let l = [ [1;2]; [3;4]; [5;6] ]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您传递给的参数函数Seq.collect只需要返回参数:

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

该表达式fun x -> x是一个只返回其参数的函数,也称为" 身份函数 ".

let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect id
Run Code Online (Sandbox Code Playgroud)

当使用高阶函数(例如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]
Run Code Online (Sandbox Code Playgroud)

但是如果你已经开始给出一个Option值列表呢?救援的身份功能!

let toNumbers optionNumbers =
   optionNumbers |> Seq.choose id
Run Code Online (Sandbox Code Playgroud)

  • “ Seq.choose id”示例是一个很好的例子,但是“ Seq.collect id”只是说“ Seq.concat”的一种较不易理解的方式。(也就是说,我很确定我也写了`Seq.collect id`多次,它说明了`id`做得好!) (2认同)

The*_*Fox 12

它对某些高阶函数(将函数作为参数的函数)很有用,这样你就可以id作为参数传递而不是写出lambda (fun x -> x).

[[1;2]; [3]] |> List.collect id  // [1; 2; 3]
Run Code Online (Sandbox Code Playgroud)