高階関数、無名関数

 

「同じような計算を繰り返すときは、関数を使うと簡単になる」という話をしましたが、次のような場合はどうでしょうか。

 

1.        (3 + 7) + (123 + 456)

2.        (3 - 7) - (123 - 456)

3.        (3 * 7) * (123 * 456)

4.        let h x y = x * x + y in
h (h 3 7) (h 123 456)

 

今度は出てくる数字は同じなのですが、計算のほうが違っています。ただしlet ... in ... というのは、inの中でだけ使えるローカル変数や関数を定義するOCamlの構文です。

 

MLでは、こういうときも関数を利用することができます。

 

# let f g = g (g 3 7) (g 123 456) ;;

val f : (int -> int -> int) -> int = <fun>

 

fは「関数gを受け取って、g (g 3 7) (g 123 456)を計算した結果を返す」という関数になります。fのように、関数を引数として受け取る(ないし関数を結果として返す)ような関数のことを高階関数といいます。高階関数を使うと、先のような処理の繰り返しも簡単になります。

 

# let g1 x y = x + y in f g1 ;;

- : int = 589

# let g2 x y = x - y in f g2 ;;

- : int = 329

# let g3 x y = x * y in f g3 ;;

- : int = 1177848

# let g4 x y = x * x + y in f g4 ;;

- : int = 15841

 

いちいちg1, g2, g3, g4などを定義するのが面倒だったら、

 

# f (fun x y -> x + y) ;;

- : int = 589

# f (fun x y -> x - y) ;;

- : int = 329

# f (fun x y -> x * y) ;;

- : int = 1177848

# f (fun x y -> x * x + y) ;;

- : int = 15841

 

のように書くこともできます。fun x y -> ...は「xyを順に受け取って...を返す」という無名関数を表現する構文です。より一般に、引数の名前はxyでなくても良いですし、引数は一個でも三個以上でも構いません。

 

次へ進む