きくらげ観察日記

好きなことを、適当に。

OCamlのmatch文とbegin..end

OCamlにはオフサイドルールは無いので、例えばmatch文をネストした時に、

let rec zip xs ys =
  match xs with
  | x :: xs' -> match ys with
                | y :: ys' -> (x, y) :: zip xs ys
                | [] -> []
  | [] -> []

これは次のように解釈されます。

let rec zip xs ys =
  match xs with
  | x :: xs' -> (match ys with
                 | y :: ys' -> (x, y) :: zip xs ys
                 | [] -> []
                 | [] -> [])

したがって、ネストしているmatchの部分は括弧でくくらなければなりません。

let rec zip xs ys =
  match xs with
  | x :: xs' -> (match ys with
                 | y :: ys' -> (x, y) :: zip xs ys
                 | [] -> [])
  | [] -> []

これは少し不格好です。
こういう時はbegin..endを使うと、少しコードを綺麗に書くことができます。

let rec zip xs ys =
  match xs with
  | x :: xs' -> begin match ys with
                 | y :: ys' -> (x, y) :: zip xs ys
                 | [] -> []
                end
  | [] -> []

面白いことに、begin..endはただの括弧のシンタックスシュガーです。したがって、例えば

let x = (3 + 4) * (8 - 2);;

と書くかわりに、

let x =
  begin
    3 + 4
  end
  *
    begin
      8 - 2
    end

と書いたりもできます。