サーチ…
構文
-
val (|>) : 'a -> ('a -> 'b) -> 'b -
val (@@) : ('a -> 'b) -> 'a -> 'b
一般的なアルゴリズム
高次関数を使用して汎用アルゴリズムを実装し、ユーザーに最終的な詳細を提供する責任を放棄することができます。例えば、 List.sortは、さまざまなソート方法を実装できる比較関数を必要とします。ここでは大文字小文字を区別しない文字列のソートを実装しています:
let string_case_insensitive_sort lst =
let case_insensitive_compare a b =
String.compare (String.lowercase a) (String.lowercase b)
in
List.sort case_insensitive_compare lst
高次関数の豊富なリストが標準ライブラリ、特にListモジュールでList.fold_leftにList.sortれています(例えばList.fold_leftとList.sortを参照)。より高度な例は、サードパーティのライブラリにあります。良い例は、 ocaml-gslで実装されたシミュレーテッドアニーリング です 。 シミュレーテッドアニーリングは、問題の状態の集合と誤差関数(ここではエネルギー関数と呼ばれる)を探索するために使用される関数によってパラメータ化される一般的な最適化手順です。
C ++をよく知っているユーザーは、これをStrategyパターンと比較できます。
例外が発生してもシステムリソースを廃棄する
処理が例外を発生させた場合でも、高次関数を使用してシステムリソースが確実に廃棄されるようにすることができます。 with_output_fileによって使用されるパターンは、 with_output_fileな分離を可能にします。高次のwith_output_file関数は、ファイル操作にバインドされたシステムリソースの管理を処理し、処理fは出力チャネルのみを消費します。
let with_output_file path f =
let c = open_out path in
try
let answer = f c in
(close_out c; answer)
with exn -> (close_out c; raise exn)
この高次関数を使用して文字列をファイルに書き込む関数を実装しましょう:
let save_string path s =
(with_output_file path) (fun c -> output_string c s)
fun c -> output_string csよりも高度な関数を使用すると、より複雑な値を保存することが可能になります。たとえば、標準ライブラリのMarshalモジュールやMartin JambonのYojsonライブラリを参照してください。
構成演算子
2つの有用な高次関数は、バイナリアプリケーション ( @@ )とリバースアプリケーションまたはパイプ( |> )演算子です。 4.01以降、プリミティブとして利用できるようになっていますが、ここで定義することはまだ有益です。
let (|>) x f = f x
let (@@) f x = f x
3の平方をインクリメントする問題を考えてみましょう。その計算を表現する1つの方法は次のとおりです。
(* 1 -- Using parentheses *)
succ (square 3)
(* - : int = 10 *)
(* where `square` is defined as: *)
let square x = x * x
我々は単純にsucc square 3行うことができないことに注意してください。なぜなら( 左連想のために(succ square) 3意味のない(succ square) 3です。アプリケーション( @@ )を使うと、かっこなしで表現することができます:
(* 2 -- Using the application operator *)
succ @@ square 3
(* - : int = 10 *)
実行される最後の操作(つまりsucc )が式の最初にどのように発生するかに注目してください。 逆アプリケーション演算子( |> )を使用すると、これを逆にすることができます。
(* 3 -- Using the reverse-application operator *)
3 |> square |> succ
(* - : int = 10 *)
数3は、今から「パイプ」であり、 square 、次いでsuccに適用されるのとは対照的に、 square 、その結果得succに適用されます。