高階関数とは、関数を引数として受け取る関数、あるいは返り値として関数を返す関数のこと。(英語ではhigher-order function)
プログラミングの分野において、特に関数型言語では、関数を数値や文字列などのデータと区別なく扱うため、高階関数を容易に且つ厳密に記述するための文法が備わっている。また、プログラム実行中に必要に応じて関数を作り、値として返したり、変数に代入(束縛)することもできる。
近年、関数型ではないプログラミング言語においても上述した機能に近い処理を実現するための言語仕様やライブラリを導入しようとする傾向が見られる(C++ならば関数オブジェクトやラムダ式など)。
一例として、Lispの派生言語であるSchemeでべき乗計算(例: 210や53といった計算)を高階関数を利用して算出するコードを以下に示す。※ただし、処理効率を考慮すれば推奨できる方法ではないが、あくまでこういうことも可能ということで紹介する。
まず、「『引数で受け取った関数』を合成していく関数」を返す高階関数composite を定義する。
(define composite (lambda (f) (lambda (x) (* x (f x)))))
上の高階関数composite を使って、「引数をn乗する関数」を返す高階関数composite-nth-pow を定義する。(nは0以上の整数とする)
この高階関数は再帰を用いて、返り値となる「無名関数」を動的に組み上げていく。
(define composite-nth-pow (lambda (n func) (cond ((= n 0) (lambda (x) 1)) ; 0乗の場合はとりあえず「定数1を返す関数」を返すことにする ((= n 1) (lambda (x) (func x))) ; 再帰によって組み上げた「関数」を返す (else (composite-nth-pow (- n 1) (composite func))))))
さらに、上で定義した高階関数composite-nth-pow を使って、num(第1引数)をn(第2引数)乗した結果を返す関数pow を定義する。この関数は返り値として数値を返す。
(define pow (lambda (num n) ((composite-nth-pow n (lambda (x) x)) num))) ; compose-nth-pow の第2引数には、「引数をそのまま返す関数」を初期値として渡している ; compose-nth-pow からの返り値:「引数をn乗する関数」に引数numを与えてべき乗の計算結果を得る
> (pow 2 10) ; 2の10乗 1024 > (pow 5 3) ; 5の3乗 125
掲示板
11 ななしのよっしん
2021/04/25(日) 16:07:42 ID: f6KX2q0x12
Cで高階関数が使えなくて困る主なケースってどういうときなんだろ
例えばソートの比較関数を動的に切り替えたいだけなら関数ポインタで、不便はあるけど実現はできるよね
可読性等について、塵も積もれば山となる系の不便さがあって困るということかな
それはそれで納得できる
evalができないというケースもあると思うけど比較的稀なケースな感じがする
12 ななしのよっしん
2021/07/31(土) 15:17:50 ID: GvmMUtMgzP
まあ可読性だよね。first classでない、つまり関数リテラルとして匿名関数を取れないということは、使い捨てで一度しか使わないようなインラインコードに対しても名前を一旦付けなきゃいけないということなので。
13 ななしのよっしん
2021/08/18(水) 05:27:23 ID: P06arb/d0y
高階関数で楽しい所は、ローカル変数を持っていける所なんだよなあ
これを関数ポインタでやると、ソート本体から比較関数までそのローカル変数を渡す手段が必要になる
最悪グローバル変数
急上昇ワード改
最終更新:2025/02/12(水) 01:00
最終更新:2025/02/12(水) 01:00
ウォッチリストに追加しました!
すでにウォッチリストに
入っています。
追加に失敗しました。
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。