Caml は関数型言語です。関数は当然数学的な意味の関数としても使えますし、他のデータと同じように自由に扱うことも出来ます。例として deriv 関数を示します。この関数は浮動小数点関数を引数にとり、導関数の近似を返します。
#let deriv f dx = function x -> (f(x +. dx) -. f(x)) /. dx;;val deriv : (float -> float) -> float -> float -> float = <fun>#let sin' = deriv sin 1e-6;;val sin' : float -> float = <fun>#sin' pi;;- : float = -1.00000000014
関数の合成も定義出来ます。
#let compose f g = function x -> f(g(x));;val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>#let cos2 = compose square cos;;val cos2 : float -> float = <fun>
関数の引数として渡された関数は「汎関数」や「高階関数」と呼ばれます。高階関数は特にイテレータのような、データ構造上の汎用の操作を提供するのに有用です。たとえば、標準 Caml ライブラリに List.map という関数がありますが、この関数は引数に与えられた関数を、すべてのリストの要素に適用し、その結果のリストを返します。
#List.map (function n -> n * 2 + 1) [0;1;2;3;4];;- : int list = [1; 3; 5; 7; 9]
List.map や他のリスト、配列関連の高階関数は、使用頻度が高いので、既にライブラリとして定義されていますが、何も特別なことはしていません。
下に示すように簡単に定義することができるのです。
#let rec map f l = match l with [] -> [] | hd :: tl -> f hd :: map f tl;;val map : ('a -> 'b) -> 'a list -> 'b list = <fun>