高階関数単語

1件
コウカイカンスウ
1.2千文字の記事
  • 2
  • 0pt
掲示板へ

概要

高階関数とは、関数引数として受け取る関数、あるいは返り値として関数を返す関数のこと。(英語では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による計算例とその結果。

> (pow 2 10) ; 2の10乗
1024
> (pow 5 3) ; 5の3乗
125

関連項目

【スポンサーリンク】

  • 2
  • 0pt
記事編集 編集履歴を閲覧

ニコニ広告で宣伝された記事

天外魔境II (単) 記事と一緒に動画もおすすめ!
提供: Haruka Amami
もっと見る

この記事の掲示板に最近描かれたお絵カキコ

お絵カキコがありません

この記事の掲示板に最近投稿されたピコカキコ

ピコカキコがありません

高階関数

4 ななしのよっしん
2009/08/07(金) 11:43:34 ID: G2qreC3Psj
それは別の所に書かなきゃいけないだろlambdaがいと、明示的にreturnも使わなきゃいけないかもしれないし
👍
高評価
0
👎
低評価
0
5 ななしのよっしん
2010/04/11(日) 21:44:28 ID: Zlvft4wnll
引数にできりゃいいなら、C系は高階関数も記述できることになるよな。
戻り値にする意味はわからんが
👍
高評価
0
👎
低評価
0
6 ななしのよっしん
2010/08/01(日) 18:54:32 ID: h/PyAk7hZv
>>4
明示的なreturnはあまり関係がない。

>>5
Cだと動的に新たな関数を生成してそれを 渡す/返す ことができない。
戻り値にすることに意味を見いだせないのは、新たに関数を作り出せないから。
👍
高評価
0
👎
低評価
0
7 ななしのよっしん
2010/11/21(日) 16:50:38 ID: eozl58vYFP
>>3-6
「Cで関数を渡す」のは関数ポインタのことじゃないか?
関数そのものを返しているわけではないから別だと思う。
👍
高評価
0
👎
低評価
0
8 ななしのよっしん
2013/08/22(木) 00:37:42 ID: x6Es+cJAik
函数を生成して返すことが出来ないと,高階関数とは言えない気がする
evalがある言は大抵高階関数持ってるはず
👍
高評価
0
👎
低評価
0
9 ななしのよっしん
2013/11/28(木) 00:07:18 ID: p7UK0dy4/P
デリゲートとかは関係あるんかな・・・?
👍
高評価
0
👎
低評価
0
10 ななしのよっしん
2014/07/21(月) 19:07:40 ID: GvmMUtMgzP
Cの関数first classじゃないから高階関数はない、というのが一般的な定義みたいだな。
もちろん自分でインタプリタみたいな処理を書いてエミュレートすればOKだが、それはメタだから反則と。
👍
高評価
0
👎
低評価
0
11 ななしのよっしん
2021/04/25(日) 16:07:42 ID: f6KX2q0x12
Cで高階関数が使えなくて困るケースってどういうときなんだろ
例えばソート関数を動的に切り替えたいだけなら関数ポインタで、不便はあるけど実現はできるよね

可読性等について、も積もれば山となる系の不便さがあって困るということかな
それはそれで納得できる

evalができないというケースもあると思うけど較的稀なケースな感じがする
👍
高評価
0
👎
低評価
0
12 ななしのよっしん
2021/07/31(土) 15:17:50 ID: GvmMUtMgzP
まあ可読性だよね。first classでない、つまり関数リテラルとして匿名関数を取れないということは、使い捨てで一度しか使わないようなインラインコードに対しても名前を一旦付けなきゃいけないということなので。
👍
高評価
0
👎
低評価
0
13 ななしのよっしん
2021/08/18(水) 05:27:23 ID: P06arb/d0y
高階関数で楽しい所は、ローカル変数を持っていける所なんだよなあ
これを関数ポインタでやると、ソート本体から関数までそのローカル変数を渡す手段が必要になる
最悪グロバル変数
👍
高評価
0
👎
低評価
0