高階関数
高階関数とは、第一級関数をサポートする
プログラミング言語において、以下のいずれかの条件を満たす関数です。
関数を引数として受け取る
関数を返す
概要
高階関数は、関数型言語や
ラムダ計算において頻繁に用いられます。関数を引数として受け取る場合、その引数となる関数は関数引数や手続き引数と呼ばれます。
種類
高階関数には様々な種類があり、プログラマが自由に定義して利用できます。以下に代表的なものを紹介します。
関数を呼び出す関数
与えられた関数に引数を渡して呼び出し、その返り値を返す高階関数です。
def apply_2_3(f):
return f(2, 3)
def add(x, y):
return x + y
print(apply_2_3(add)) # 出力: 5
カリー化
複数の引数をとる関数を、1変数関数に置き換えることをカリー化と呼びます。例えば、二つの数を足し合わせる関数 `add` は以下のようにカリー化できます。
python
def add(x):
def inner(y):
return x + y
return inner
add_2 = add(2)
print(add_2(3)) # 出力: 5
filter
リスト中の各要素を引数として渡し、与えられた関数の返り値が真である要素のみをリストに残します。
python
def is_positive(x):
return x > 0
numbers = [1, 2, -3, -4, 5]
positive_numbers = list(filter(is_positive, numbers))
print(positive_numbers) # 出力: [1, 2, 5]
zip
複数のリストから、タプルを要素とする1つのリストを生成します。
python
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
zipped_list = list(zip(list1, list2))
print(zipped_list) # 出力: [(1, 'a'), (2, 'b'), (3, 'c')]
unzip
`zip` の逆操作で、タプルを要素とする1つのリストから複数のリストを生成します。
map
リスト構造の各要素に対して、順に与えられた関数を適用します。
python
def add_one(x):
return x + 1
numbers = [1, 2, 3]
incremented_numbers = list(map(add_one, numbers))
print(incremented_numbers) # 出力: [2, 3, 4]
for-each
`map` と同様に動作しますが、結果を返しません。副作用を期待して利用します。
fold
リストの各要素に対して、与えられた関数を累積的に適用します。右方向の畳み込み (foldr) と左方向の畳み込み (foldl) があります。
python
from functools import reduce
def add(x, y):
return x + y
numbers = [1, 2, 3]
sum_of_numbers = reduce(add, numbers)
print(sum_of_numbers) # 出力: 6
unfold
初期値から何らかの動作を行い、リストを生成する関数です。
漸化式を
数列に変換する操作に相当します。
直積
複数のリストそれぞれの要素からなるタプルを生成し、それらのタプルを要素とするリストを返します。
prefix scan
リストの各要素に対して繰り返し演算を行い、累積した計算結果のリストを返す高階関数です。特に和の演算は prefix sum とも呼ばれます。
関数型言語以外の言語と高階関数
関数型言語以外の言語でも、関数ポインタなどを利用して高階関数のような処理を実現できます。ただし、言語によってはカリー化やクロージャの機能が制限されている場合があります。C#, C++, Tcl など、ラムダ式をサポートする言語も増えています。
C言語での例:
c
include
int add(int x, int y) {
return x + y;
}
int apply(int (
func)(int, int), int a, int b) {
return func(a, b);
}
int main() {
int result = apply(add, 2, 3);
printf("%d
", result); // 出力: 5
return 0;
}
関連項目
汎関数
* モノイド