OCaml: 型検査が通らない例

カリー化された関数opとそれに適用する引数をリストで受け取り1つずつ適用するようなexpand_args関数を以下のように定義する.

let rec expand_args op args = match args with
    [] -> op
  | v::rest -> expand_args (op v) rest

以下のように使いたい.

# expand_args ( + ) [1;2];;
> 3
# expand_args ( ^ ) ["foo";"bar"];;
> "foobar"

残念ながら,expand_argsはOCamlの型検査をパスしない.opの型がexpand_argsの再帰呼び出しごとに異なってしまうからだ.'a, 'b->'a, 'b->'b->'a, 'b->'b->'b->'a, ...のように.
rectypesオプションを付ければ,expand_args関数自体は型検査をパスするようになるが.

# expand_args ( + ) [1;2];;
              ^^^^^
int->'a as 'aを期待しているが,int->int->intなので,型エラーとなる

expand_argsを所期の目的どおりに使えるようにするには,OCamlの多相型を拡張する必要がありそうだ.