ZetCode

F# Lambda

最后修改日期:2025 年 5 月 17 日

本文探讨如何在 F# 中使用 Lambda 表达式及其在函数式编程中的作用。

一个 Lambda 表达式 是一个不需要显式名称的匿名函数。Lambda 表达式使用 fun 关键字定义,允许开发人员创建轻量级的内联函数,这些函数通常用于短暂的操作。它们通过消除不必要的函数声明来提高代码的可读性和可维护性。

当将函数作为参数传递、在高阶函数中定义简洁的逻辑或简化简单计算时,Lambda 表达式特别有用。由于它们是匿名的,并且通常在特定上下文中定义,因此它们不需要在程序中的多个位置重用。

F# 简单 Lambda

在下面的示例中,我们定义了一个简单的 Lambda。

main.fsx
let inc x = x + 1 

let v = inc 90
printfn "%d" v

let r = (fun x -> x + 1) 100
printfn "%d" r

该程序包含一个简单的函数和一个 Lambda。

let inc x = x + 1 

这是名为 inc 的函数的定义,该函数会增加其参数。

let v = inc 90
printfn "%d" v

调用 inc 函数并打印结果。

let r = (fun x -> x + 1) 100

定义了一个 Lambda 函数并立即调用它。该函数是匿名的,无法重用。

λ dotnet fsi main.fsx
91
101

F# Lambda 与高阶函数

Lambda 通常传递给高阶函数以定义谓词。

main.fsx
let vals = [ 2; 1; -5; 8; 9; -2; 0; 5; 4 ]

let res = List.map(fun e -> e * 2) vals
printfn "%A" res

let res2 = List.filter(fun e -> e < 0) vals
printfn "%A" res2

在示例中,我们使用两个 Lambda 为 List.mapList.filter 函数创建谓词。

λ dotnet fsi main.fsx
[4; 2; -10; 16; 18; -4; 0; 10; 8]
[-5; -2]

F# Lambda 参数类型

参数类型在圆括号内提供,每个参数单独指定。

main.fsx
let msg = (fun (name: string)(age: int) -> $"{name} is {age} years old") "John Doe" 34
printfn "%s" msg

我们有一个带有两个参数的 Lambda 表达式:一个字符串和一个整数。参数及其类型在 () 括号内定义。

λ dotnet fsi main.fsx
John Doe is 34 years old

F# Lambda 与 let 绑定

我们可以在 Lambda 中使用 let 绑定。

main.fsx
let names =
    [ "John Doe"
      "Lucy Smith"
      "Benjamin Young"
      "Robert Brown"
      "Thomas Moore"
      "Linda Black"
      "Adam Smith"
      "Jane Smith" ]

names
|> List.sortBy (fun e -> let a = e.Split(" ") in Array.get a 1)
|> printfn "%A"

在程序中,我们按姓氏对姓名列表进行排序。

|> List.sortBy (fun e -> let a = e.Split(" ") in Array.get a 1)

我们按空格拆分每个姓名,然后获取拆分后的第二个元素。

λ dotnet fsi main.fsx
["Linda Black"; "Robert Brown"; "John Doe"; "Thomas Moore"; "Lucy Smith";
 "Adam Smith"; "Jane Smith"; "Benjamin Young"]

F# Lambda 闭包示例

Lambda 可以捕获其周围作用域中的变量,创建闭包。这允许 Lambda 在调用之间记住和更新状态。

closure.fsx
let makeCounter () =
    let mutable count = 0
    fun () ->
        count <- count + 1
        count

let counter = makeCounter ()
printfn "%d" (counter ()) // 1
printfn "%d" (counter ()) // 2
printfn "%d" (counter ()) // 3

在此示例中,makeCounter 返回一个 Lambda,该 Lambda 会递增并返回一个私有计数器。每次调用 counter 都会增加值,这说明了 Lambda 如何对局部变量形成闭包。

λ dotnet fsi closure.fsx
1
2
3

在本文中,我们探讨了 F# 中 Lambda 表达式的基础知识及其在函数式编程中的实际应用。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。