고차 함수

고차 함수(高次函數, )는 수학과 컴퓨터 과학에서 적어도 다음 중 하나를 수행하는 함수이다.
다른 모든 함수들은 일차(first order) 함수이다. 수학에서 고차 함수들은 연산자, 범함수라고도 한다. 미적분에서 미분 연산자가 일반적인 예인데, 그 이유는 함수를 그 미분에 연결시키기 때문이다.
형식화되지 않은 람다 대수에서 모든 함수들은 고차 함수이다. 대부분의 함수형 프로그래밍 언어를 파생시키는 형식화된 람다 대수에서 하나의 함수를 인수로 취하는 고차 함수들은 formula_1의 형태의 값이다.
일반적인 예.
수많은 함수형 프로그래밍 언어에서 볼 수 있는 codice_1 함수는 고차 함수의 한 예이다.
프로그래밍 언어에서의 지원.
직접적인 지원.
파이썬.
»&gt; def twice(function):
... return lambda x: function(function(x))
»&gt; def f(x):
... return x + 3
»&gt; g = twice(f)
»&gt; print g(7)
13
F#.
let twice f = f » f
let f = (+) 3
twice f 7 |&gt; printf "%A" // 13
하스켈.
twice :: (a -&gt; a) -&gt; (a -&gt; a)
twice f = f . f
f :: Num a =&gt; a -&gt; a
f = subtract 3
main :: IO ()
main = print (twice f 7) -- 1
클로저.
(defn twice [function x]
 (function (function x)))
(twice #(+ % 3) 7) ;13
스킴.
 (lambda (y) (+ x y)))
얼랭.
or_else([], _) -&gt; false;
or_else([F | Fs], X) -&gt; or_else(Fs, X, F(X)).
or_else(Fs, X, false) -&gt; or_else(Fs, X);
or_else(Fs, _, {false, Y}) -&gt; or_else(Fs, Y);
or_else(_, _, R) -&gt; R.
or_else([fun erlang:is_integer/1, fun erlang:is_atom/1, fun erlang:is_list/1],3.23).
자바스크립트.
var twice = function(f, v) {
 return f(f(v));
var f = function(v) {
 return v + 3;
console.log(twice(f, 7)); // 13
고.
func twice(f func(int) int, v int) int {
 return f(f(v))
func main() {
 f := func(v int) int {
 return v + 3
 twice(f, 7) // returns 13
스칼라.
def twice(f:Int=&gt;Int) = f compose f
twice(_+3)(7) // 13
자바 (1.8 이상).
Function&lt;Function&lt;Integer, Integer&gt;, Function&lt;Integer, Integer» twice = f -&gt; f.andThen(f);
twice.apply(x -&gt; x + 3).apply(7); // 13
스위프트.
func f(x: Int) -&gt; Int {
 return x + 3
func g(function: (Int) -&gt; Int, paramX: Int) -&gt; Int {
 return function(paramX) * function(paramX)
g(function: f, paramX: 7)
러스트.
// Take function f(x), return function f(f(x))
fn twice&lt;A, F&gt;(function: F) -&gt; Box&lt;Fn(A) -&gt; A&gt;
 where F: 'static + Fn(A) -&gt; A
 Box::new(move |a| function(function(a)))
// Return x + 3
fn f(x: i32) -&gt; i32 {
 x + 3
fn main() {
 let g = twice(f);
 println!("{}", g(7));
C++.
// Generic lambdas provided by C++14.
auto twice = [](auto f, int v)
 return f(f(v));
auto f = [](int i)
 return i + 3;
int main()
 std::cout « twice(f, 7) « std::endl;
// Or, use std::function in C++11
auto twice = [](const std::function&lt;int(int)&gt;&amp; f, int v)
 return f(f(v));
auto f = [](int i)
 return i + 3;
int main()
 std::cout « twice(f, 7) « std::endl;
콜드퓨전 마크업 언어 (CFML).
twice = function(f, v) {
 return f(f(v));
f = function(v) {
 return v + 3;
writeOutput(twice(f, 7)); // 13
PHP.
$twice = function($f, $v) {
 return $f($f($v));
$f = function($v) {
 return $v + 3;
echo($twice($f, 7)); // 13
R.
twice &lt;- function(func) {
 return(function(x) {
 func(func(x))
f &lt;- function(x) {
 return(x + 3)
g &lt;- twice(f)
&gt; print(g(7))
[1] 13
XACML.
rule allowEntry{
 permit
 condition anyOfAny(function[stringEqual], citizenships, allowedCitizenships)
대안.
함수 포인터.
double square(double x)
 return x * x;
double cube(double x)
 return x * x * x;
/* Compute the integral of f() within the interval [a,b] */
double integral(double f(double x), double a, double b, int n)
 int i;
 double sum = 0;
 double dt = (b - a) / n;
 for (i = 0; i &lt; n; ++i) {
 sum += f(a + (i + 0.5) * dt);
 return sum * dt;
int main()
 printf("%g\n", integral(square, 0, 1, 100));
 printf("%g\n", integral(cube, 0, 1, 100));
 return 0;
오브젝트.
program example;
type
 int = integer;
 Txy = record x, y: int; end;
 Tf = function (xy: Txy): int;
function f(xy: Txy): int;
begin
 Result := xy.y + xy.x;
end;
function g(func: Tf): Tf;
begin
 result := func;
end;
var
 a: Tf;
 xy: Txy = (x: 3; y: 7);
begin
 a := g(@f); // return a function to "a"
 writeln(a(xy)); // prints 10
end.
기능상실.
// Defunctionalized function data structures
template&lt;typename T&gt; struct Add { T value; };
template&lt;typename T&gt; struct DivBy { T value; };
template&lt;typename F, typename G&gt; struct Composition { F f; G g; };
// Defunctionalized function application implementations
template&lt;typename F, typename G, typename X&gt;
auto apply(Composition&lt;F, G&gt; f, X arg) {
 return apply(f.f, apply(f.g, arg));
template&lt;typename T, typename X&gt;
auto apply(Add&lt;T&gt; f, X arg) {
 return arg + f.value;
template&lt;typename T, typename X&gt;
auto apply(DivBy&lt;T&gt; f, X arg) {
 return arg / f.value;