改造中

$label が省略された場合、外側の let で自動的に $-abstract される。

# let f $x y = x,y;;
val f : $x:'a -> 'b -> 'a * 'b = <fun>
# let g = prerr_endline "hello"; f 1;; 
(* let g $x = prerr_endline "hello"; f $x 1 になる *)
val g : $x:'a -> 'a * int = <fun> (* 副作用が無い事に注目 *)
# g $x:0;;  
hello
- : int * int = (1, 0)

$-abstract compaction: 同名の$label が同じ型の引数を持つとき、外部 let での自動 $-abstract は一つにまとめられる:

# let f $x = x;;
val f : $x:'a -> 'a = <fun>
# let g = [f; f];;   
(* let g $x = [f $x; f $x] になる *)
val g : $x:'a -> 'a list = <fun> (* $x が一つしかない *)

$-abstract compaction は let の型付けの時に決めるので、その時に同じ型になってないと compaction されない。Unify の順番によって compaction されない場合がある => そりゃダメだ!どうしたもんかのー。