catコマンド

これもまた簡単に実装できた。
入出力関係は素直に書こうとするとやっぱり手続き型言語みたいになっちゃうのかな。

let version = "0.1"
let display_linenum = ref false
let filenames = ref []

let spec = [("-n", Arg.Set display_linenum, "Display line number");
	    ("-version",
	     Arg.Unit 
	       (fun () -> Printf.printf "cat in OCaml ver: %s\n" version),
	     "Display version number")]

let show_file filename = 
  let cnl = open_in filename in
  let i = ref 1 in
  try while true do
    let input = input_line cnl in
    if !display_linenum then
      Printf.printf "%6d  " !i;
    print_endline input;
    i := !i + 1
  done with End_of_file -> close_in cnl

let _ =
  Arg.parse spec
    (fun s -> filenames := s :: !filenames)
    "Usage: cat [-n] [-help] [-version] filename ...";
  List.iter show_file (List.rev !filenames)

とりあえず-nスイッチだけ対応。
今度暇だったら他のスイッチにも対応してみるか。
出力。

$ ./cat cat.ml
let version = "0.1"
let display_linenum = ref false
let filenames = ref []

let spec = [("-n", Arg.Set display_linenum, "Display line number");
	    ("-version",
	     Arg.Unit 
	       (fun () -> Printf.printf "cat in OCaml ver: %s\n" version),
	     "Display version number")]

let show_file filename = 
  let cnl = open_in filename in
  let i = ref 1 in
  try while true do
    let input = input_line cnl in
    if !display_linenum then
      Printf.printf "%6d  " !i;
    print_endline input;
    i := !i + 1
  done with End_of_file -> close_in cnl

let _ =
  Arg.parse spec
    (fun s -> filenames := s :: !filenames)
    "Usage: cat [-n] [-help] [-version] filename ...";
  List.iter show_file (List.rev !filenames)
 $ ./cat cat.ml -n
     1  let version = "0.1"
     2  let display_linenum = ref false
     3  let filenames = ref []
     4  
     5  let spec = [("-n", Arg.Set display_linenum, "Display line number");
     6  	    ("-version",
     7  	     Arg.Unit 
     8  	       (fun () -> Printf.printf "cat in OCaml ver: %s\n" version),
     9  	     "Display version number")]
    10  
    11  let show_file filename = 
    12    let cnl = open_in filename in
    13    let i = ref 1 in
    14    try while true do
    15      let input = input_line cnl in
    16      if !display_linenum then
    17        Printf.printf "%6d  " !i;
    18      print_endline input;
    19      i := !i + 1
    20    done with End_of_file -> close_in cnl
    21  
    22  let _ =
    23    Arg.parse spec
    24      (fun s -> filenames := s :: !filenames)
    25      "Usage: cat [-n] [-help] [-version] filename ...";
    26    List.iter show_file (List.rev !filenames)
$ ./cat hoge
Fatal error: exception Sys_error("hoge: No such file or directory")
$ ./cat -m
cat.exe: unknown option `-m'.
Usage: cat [-n] [-help] [-version] filename ...
  -n Display line number
  -version Display version number
  -help  Display this list of options
  --help  Display this list of options