改造中
$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 されない場合がある => そりゃダメだ!どうしたもんかのー。