函数模式

已完成

目前,你已使用重复的表达式,并将这些表达式放入函数中。 现在代码看起来效果更好,更易于阅读。 当你更熟悉使用函数时,就有必要开始了解其中的一些功能强大的模式。 使用这些模式,将使代码更易于阅读和维护。

声明性与命令性

在开始编码时,通常会先编写表达式。 接着会编写一个又一个的表达式。 你会将注意力集中在解决问题上,会具体考虑问题的解决方式。 此方法被称为“命令性”方法。 这没有什么问题,因为能解决当前问题。 但也可以使用另一种方法,即“声明性”方法。 当你使用 SQL 查询数据库时,可以看到声明性方法的示例。

下面是一个示例表达式:

SELECT * 
FROM Students s
WHERE s.Location = "Ohio" 

这段代码之所以是声明性的,是因为你请求获得所需的内容,但没有指定解决问题的方式。 而是让 SQL 来决定方式。

也可以将此方法应用于 F#。 下面的代码使用声明性方法:

let studentsFromOhio = 
    allStudents  
    |> filterLocation "Ohio"

在前面的代码中,对数据进行操作时无需指定具体实现方法即可实现目的。 如果你的代码与上述示例类似,则表示它易于阅读和推断。 为了做到这一点,我们来看看 F# 中支持的一些有用的模式。

函数模式

F# 中有一些有用的模式,可以让你采用功能性更强的方法。 我们将介绍以下模式:

  • 组合:组合就是将多个函数合并到一个函数中。
  • 管道:管道以一个值开始,然后依次调用多个函数,并使用一个函数的输出作为下一个函数的输入。

组合

组合是指合并函数并按特定顺序逐个应用它们。 组合运算符采用两个函数,并返回一个新函数。

在创作代码时,你通常会发现自己在一个接一个地调用函数。 例如,你可能想要订购一个清单,并筛选掉所有折扣产品。

下面的示例中调用了 add2() 函数,并将其结果提供给 multiply3() 函数。

let add2 a = a + 2
let multiply3 a = a * 3 
let addAndMultiply a =
    let sum = add2 a
    let product = multiply3 sum
    product

printfn "%i" (addAndMultiply 2) // 12

此模式很常用以至于 F# 有一个专用于此模式的运算符。 >> 运算符可将两个或多个函数合并为一个更大的函数。 使用 >> 运算符可以简化前面的代码,如下所示:

let add2 a = a + 2
let multiply3 a = a * 3 
let addAndMultiply = add2 >> multiply3

printfn "%i" (addAndMultiply 2) // 12

组合函数 addAndMultiply() 以从左到右的顺序应用它包含的函数。 在此示例中,首先执行 add2(),最后执行 multiply3()

管道

管道运算符 |> 采用一个函数和一个参数,并返回一个值。 我们来通过以下示例看看管道与组合的区别:

let list = [4; 3; 1]
let sort (list: int list) = List.sort list
let print (list: int list)= List.iter(fun x-> printfn "item %i" x) list

list |> sort |> print // item 1 item 3 item 4

在最后一行代码中,从一系列整数开始:list,这些整数充当第一个函数 sort() 的输入。 将该操作的结果送入 print()。 管道和组合的主要区别:管道是从一些数据(在本例中是一个整数列表)开始,然后引导它完成一组函数。