OCaml 高階関数、多相性、匿名関数、カリー化とリスト

いつまで続くかわからないけど、 M.Hiroi's Home Page / お気楽 OCaml プログラミング入門 - 高階関数 リスト を読んで、 OCaml 書いた。

末尾再帰を意識して、一つづつ。

#! /usr/bin/env ocaml

(* 高階関数 *)
let sum_of f n m =
    let rec iter f n m a =
        if n > m then a
        else iter f (n + 1) m (a + (f n)) in
    iter f n m 0
;;

(* 多相性 *)
let polymorphism a = a;;

(* 匿名関数 *)
let anon_fun = fun x -> x * x;;

(* カリー化 *)
let curry x y z = (fun x -> fun y -> fun z -> x + y + z) x y z;;

(* カリー化 sum_of に対し、色付け *)
let sum_of_int = sum_of (fun x -> x);;
let sum_of_square = sum_of (fun x -> x * x);;
let sum_of_cube = sum_of (fun x -> x * x * x);;

(* リスト *)
let make_list n =
    let rec iter n ls =
        if n = 0 then ls
        else (iter (n - 1) (1 :: ls)) in
    iter n []
;;

let rev_list xs =
    let rec iter xs xs2 =
        if (xs = []) then xs2
        else iter (List.tl xs) ((List.hd xs) :: xs2) in
    iter xs []
;;

let concat_list xs ys =
    let xs2 = (rev_list xs) in
    let rec iter x xs ys =
        if (xs = []) then (x :: ys)
        else iter (List.hd xs) (List.tl xs) (x :: ys) in
    iter (List.hd xs2) (List.tl xs2) ys
;;

let member_list x ys =
    let rec iter x y ys =
        if (ys = []) then []
        else
            if (x = y) then (y :: ys)
            else iter x (List.hd ys) (List.tl ys) in
    iter x (List.hd ys) (List.tl ys)
;;

(* main *)
let main =
    if (Array.length Sys.argv) = 2
    then
        match Sys.argv.(1) with
        | "sum_of" -> string_of_int (sum_of (fun x -> x * x * x) 1 1000000)
        | "polymorphism" -> polymorphism "hoge"
        | "anon_fun" -> string_of_int (anon_fun 3)
        | "curry" -> string_of_int (curry 1 2 3)
        | "sum_of_int" -> string_of_int (sum_of_int 1 10)
        | "sum_of_square" -> string_of_int (sum_of_square 1 10)
        | "sum_of_cube" -> string_of_int (sum_of_cube 1 10)
        | "make_list" -> string_of_bool ((make_list 3) = [1; 1; 1])
        | "rev_list" -> string_of_bool ((rev_list [1; 2; 3]) = [3; 2; 1])
        | "concat_list" -> string_of_bool ((concat_list [1; 2; 3] [4; 5; 6]) = [1; 2; 3; 4; 5; 6])
        | "member_list" -> string_of_bool ((member_list 2 [1; 2; 3]) = [2; 3])
        | _ -> "some"
    else "Please specify func."
    ;;
let () = print_string (main ^ "\n");;