编程语言简介/定义和示例
外观
< 编程语言简介
一些编程语言将函数视为 一等公民。换句话说,这些语言中的函数可以分配给变量,并且可以作为参数传递给其他函数并从其他函数中返回。这种能力为程序开发人员开辟了广阔的可能性。在本节中,我们将探讨其中的一些可能性。
我们将在本章中使用的一个基本概念是高阶函数的概念,我们递归地定义如下
- 不接收其他函数作为参数或返回函数的函数的阶数为零。
- 接收或返回阶数为 n - 1 的函数的函数的阶数为 n。
例如,以下在 SML 中实现的函数接收类型为 'a list
的多态列表,以及另一个类型为 'a -> 'b
的函数,并返回一个类型为 'b list
的新列表。我们通过将映射函数应用于输入列表的每个元素来获得此新列表
fun map _ nil = nil
| map f (h::t) = f h :: map f t
我们的 map 函数非常可重用。我们可以将相同的算法与许多不同类型的映射函数和输入列表一起重用。以下是几个示例
- map (fn x => x + 1) [1, 2, 3, 4];
val it = [2,3,4,5] : int list
- map op + [(1, 2), (3, 4)];
val it = [3,7] : int list
- map op ~ [1, 2, 3, 4];
val it = [~1,~2,~3,~4] : int list
- map (fn x => "String: " ^ Int.toString x) [1, 2, 3, 4];
val it = ["String: 1","String: 2","String: 3","String: 4"] : string list
在前面的示例中,map 是一个一阶函数,因为它接收一个零阶函数作为参数。高阶函数在函数式语言中非常常见,例如 SML、Haskell、ocaml、erlang 和 F#。但是,即使是语义更命令式的语言,例如 C#、Python 和 Lua 也提供了此功能。事实上,几乎所有现代编程语言都对高阶函数提供了一些支持。下面我们看到我们的初始示例,即 map 函数,在 Python 中编码
def map(f, l):
return [f(x) for x in l]
print map(lambda x: x > 4, [2,3, 5, 7])
def inc(x): return x + 1
print map(inc, [2, 3, 5, 7])
在 C 中,通过将函数指针作为其他函数的参数传递,也可以使用高阶函数。例如,以下代码实现了我们最初的 map 示例。但是,我们指出这种编码风格在 C 中并不典型,这可能解释了该程序的相对冗长。
#include <stdio.h>
#include <stdlib.h>
int* map (int* a, unsigned size, int (*f)(int)) {
int i = 0;
int* narray = (int*) malloc(size * sizeof(int));
while (i < size) {
narray[i] = (*f)(a[i]);
i++;
}
return narray;
}
int inc(int x) {
return x + 1;
}
int sqr(int x) {
return x * x;
}
void printvec(int* a, unsigned size) {
int i = 0;
while (i < size) {
printf("%8d", a[i++]);
if (! (i % 10) ) {
printf("\n");
}
}
printf("\n");
}
int main(int argc, char** argv) {
int* a = (int*) malloc((argc - 1) * sizeof(int));
int* b;
int* c;
int i = 1;
while(i < argc) {
a[i++] = atoi(argv[i]);
}
printvec(a, argc - 1);
b = map(a, argc - 1, inc);
printvec(b, argc - 1);
c = map(a, argc - 1, sqr);
printvec(c, argc - 1);
}