计算机科学基础/高阶函数
高阶函数提供了一种更强大的方法来概括问题的解决方案,它们允许代码块将代码块作为参数,并返回一个代码块作为返回值。所有其他函数被称为一阶函数。数学中一个高阶函数的例子是导数函数,它将函数作为输入,并产生另一个函数(第一个函数的导数)作为输出。在计算机科学中,map 函数接受一个任意函数和一个数据集(例如列表),并将函数应用于集合中的每个数据项。另一个例子是 reduce(或 fold)函数,它接受一个输入函数和数据集,并使用函数生成数据集中所有项目的聚合。例如,如果输入函数是加法,则 reduce 函数返回数据集中所有项目的总和作为输出。如果输入函数是乘法,则 reduce 函数产生数据集中所有项目的乘积。高阶函数还允许我们使用现有的函数在运行时创建函数的组合。例如,给定两个函数 和 以及 和 我们就可以创建一个函数 使得 .
以下脚本使用内置的 map 代码块/函数将同一个代码块/函数应用于列表中的每个元素。
为了应用不同的函数,我们只需要找到或实现该函数,并将它用作 map 代码块的第一个参数。下一个示例使用乘法函数,该函数接受两个参数。Snap! 足够智能,能够检测到这一点,并在应用函数时使用列表的每个元素作为两个参数。所以结果列表应该包含原始列表中元素的自乘结果。
这个 map 代码块将对多个数据项应用同一个函数的这种模式概括为一个代码块。它并非简单的编程,因为有人必须编写这个 map 代码块(查看源代码以了解它有多复杂),但它让程序员更开心,因为它让思考部分变得更简单。作为程序员,我们可以从担心列表的迭代中解脱出来,从而专注于需要应用于列表的函数。
以下两个示例使用 Snap! 中的内置 reduce 函数来计算一组数字的总和和乘积。
请注意,reduce(与…合并)函数可以接受任何具有两个输入参数的函数来将一组值聚合为单个值。通过使用高阶函数,我们可以创建可以定制以解决更大范围问题的通用解决方案。
以下代码块演示了代码块作为数据的用法。在这个代码块中,两个报告代码块被作为参数传入,然后用于形成报告值 - 一个新的代码块。新代码块将两个输入报告代码块应用于某个未知的输入值。请注意,报告值周围的“环”(灰色框架)非常重要。任何包含在“环”中的内容都将被视为数据而不是程序。两个函数的应用不会被评估,而是简单地返回为数据,而不进行评估,这正是我们在这个高阶函数中想要的。
为了使用组合后的函数,我们可以使用两个输入函数调用 compose 函数,并使用“call”代码块对输入值执行组合后的代码块,如以下脚本所示。
有了这个“compose”代码块,我们可以通过在运行时结合现有的函数来定义新函数 - 当我们需要它们时。这是一种强大的概括方法,如果没有使用高阶函数,我们就无法实现。