「同じような計算を繰り返すときは、関数を使うと簡単になる」という話をしましたが、次のような場合はどうでしょうか。
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 -> ...は「xとyを順に受け取って...を返す」という無名関数を表現する構文です。より一般に、引数の名前はxやyでなくても良いですし、引数は一個でも三個以上でも構いません。