順番に見るとわかる
OCamlのin
は、局所的にスコープを作成するものです。簡単な例を挙げると以下のようなものです。
* let x = 1 in x + 2;;
さて何が返ってくるでしょう?答えは3です。では以下のような場合はどうなるでしょうか?
* let x = 1 in let x = x + 2 in x + 3;;
答えは6です。見た目が非常にややこしい。いったいどの
x
がどの値なのか混乱してしまいがちです。しかし、順番に見ていくとすっきりするはずです。
まず最初の例の説明をすると、最初に
x
が1に束縛されます。そして次にin
があるので、続きを見てみます。すると、x + 2
となっているので、先程束縛されたx
と2を加算します。結果3を返すことになります。同じように2つ目の例を見てみます。
まず
x
が1に束縛されます。そしてin
があるので続きを見ます。すると、新たにx
を束縛しようとしています(まだ束縛されていない)。束縛する値はx + 2
となっています。今のところx
に束縛されている値は1なので、それを使います。これで新たなx
が3に束縛されました。さらにin
が付いていますので、続きを見てみます。すると、x + 3
となっています。現在x
に束縛されている値は3なので、加算すると6になります。このように順番に考えるとわかりやすくなるように思います。
では以下のようなリストの長さを返す関数の場合を考えてみます。
let length list =
let rec aux n = function
| [] -> n
| _ :: t -> aux (n + 1) t
in aux 0 list;;
function
は以下の形の省略形になっています。
let length list =
let rec aux n list =
match list with
| [] -> n
| _ :: t -> aux (n + 1) t
in aux 0 list;;
順番に考えてみます。まず
list
という引数を持つlength
をいう名前の関数が、n
とlist
を引数に持つ再帰する関数aux
に束縛されます。ここでaux
も束縛されます。そしてin
がついているので続きを見てみます。すると、aux 0 list
となっています。たびたび出てくるlist
ですが、新たに束縛はしてませんので、その名前は、関数length
の引数しかありません。したがってそのlist
と同じものです。ということで、結果は再帰関数aux
の結果となります。