OCamlの型について、ドーナツも微妙に書いてたけど、今日よくわからなかったので書いてみる。
ドーナツがわからない言ってた多相型やら型推論の話は俺もいまいちわからないのでスルー。


doubleの定義

let double f x = f (f x);;
val double : ('a -> 'a) -> 'a -> 'a =

これは、('a型を受け取って'aを返す関数) -> ('a型の変数) -> (返り値として、'a型を返す) という関数。 といってる。


double double f x について。
左結合だから、()をつけると、

((double double) f) x)

ってなるけど、わかりにくいので、doubleは2引数なんだから、

((double double f) x)

と思って考える。(そう考えていいのかどうかは知らんが。)
そうすると、

double double f = double (double f)

となるわけだ。ってことは全体は、

(double double f) x = (double (double f)) x
= double f (double f x)
= double f (f(f x))
= f(f(f(f x)))

しかし、このやり方はあまりよろしくない気がするので、

(double double) f ) x)
でやろうとすると、なんかλ式をいろいろ使ってたけど、ようは、

(double double) f) x) = (double (double f)) x
= double f (double f x)
= double f (f (f x))
= f ( f ( f( f x)))

なるほど。自分でやれば簡単だと。てか、上と導出まったく一緒やね。
実はホントは1段目の(double f)は、(double f)の前のdouble を展開する前に展開しとかなければ、call by value じゃない!!みたいなことを言ってたけど、書き方が書きにくいのでそのままにしておく。実は先にそっちを展開してるんだよってことを知っておけばOK。

あと、型でいろいろやろうとすると、double double の後ろのdoubleの型を

('a -> 'a) -> 'a -> 'a とすると、前のdoubleは、

(('a -> 'a)->'a->'a) -> ('a -> 'a) -> 'a ->'a
double -> f -> x -> 答

ってなるよ、みたいなことをやってた。
そうすると、結局double double 全体では
('a ->'a) ->'a->'a
になるね。

とりあえずあれだ、簡単なところはわかった感じですね。