第 8 章:把函数作为参数

函数也可以作为值传给另一个函数。比如“执行两次”不必限定执行什么操作:加一可以执行两次,给文本追加感叹号也可以执行两次。接收函数或返回函数的函数叫高阶函数。

先看要完成的计算

我们希望写出一个函数,接收操作和初始值,先执行一次,再把结果交给同一个操作。若操作是加一、初始值是 10,过程就是 10 → 11 → 12

下面是完整程序:

寻观「标准库」之书。

「执行两次」乃承「甲」而化(化「甲」而「甲」)而化「甲」而「甲」也。
「执行两次」者受「甲」而会「操作」而会「初值」而
    「操作」于(「操作」于「初值」)也。

「结果」乃「整数」也。
「结果」者「执行两次」授以「整数」
    于(会「数」而「加」于「数」于「一」)
    于「一零」也。

「打印行」于(「整数表示」于「结果」)。

输出为 12会「数」而「加」于「数」于「一」 是直接写在参数位置的函数,没有另起名称,称为匿名函数。它和单独定义一个加一函数的作用相同。

为什么类型里出现了“甲”

执行两次只要求操作的输入类型和输出类型一致,否则第一次的结果就不能交给第二次调用。它不要求这个类型一定是整数。

「甲」 是这里的类型参数,可以在一次调用中取为整数,在另一次调用中取为字符串。这样的函数称为多态函数。

写法 在本例中的作用
承「甲」而…… 在类型声明中引入隐式类型参数甲
化(化「甲」而「甲」)而…… 接收一个从甲到甲的操作函数
化「甲」而「甲」 接着接收初值,最终返回同类型结果
受「甲」而…… 在定义中接收类型参数
授以「整数」 在调用中明确指定甲为整数

授以 指定这里的类型参数, 传入操作和初值。编译器在一些情况下能推断隐式参数,教程显式写出它们,方便对照类型。

标准库如何使用高阶函数

列表处理中经常用到以下三种操作:

函数 交给它的操作 结果
「态射」 把单个元素转换成另一个值的函数 转换后的列表
「滤」 返回爻值的判断函数 只保留判断为真的元素
「从左折叠」 把当前元素合并进累计值的函数 一个最终累计值

假设已定义整数列表 「数列」 和整数平方函数 「平方」,映射调用是:

「态射」授以「整数」授以「整数」于「数列」于「平方」

两个类型参数分别是输入元素类型和输出元素类型,普通参数先传列表、再传函数。第十三章会把这三种操作放进同一个程序,并逐步展示结果。

练习

把完整程序中的类型参数改为 「字符串」,操作改为在末尾拼接 『!』,初值改为 『你好』,并直接打印结果。预期输出 你好!!「执行两次」 的定义不需要修改。

上一章 · 下一章:编写递归函数 · 目录