プログラミングの基礎 ((Computer Science Library))を読み終わった。それなりに面白かった。正直、赤黒木とかちゃんと理解するのは普通に難しいので飛ばし読みしたけど。昔、一度理解はしたけど、実装しろと言われたらもう一度勉強し直さないとどうにもならないだろうなあ。
さて、OCamlをざっと理解した気になったので、Goと同じプログラムをOCamlで作ってみることにしよう。先ずは、tailが作れないことには話にならない。
とはいえ、教科書にファイルの読み書きは出てこないのだった(笑)。副作用のある処理はオマケ扱いだ。
標準出力への書込が出来ないと何が正しいのかさっぱりわからないので、Hello Worldから行こう。
> cat tail.ml let () = print_endline "Hello, OCaml!" > ocamlopt -o my_tail tail.ml > ./my_tail Hello, OCaml!
ocamloptコマンドは、ネイティブバイナリを作ってくれる。
さて、ファイルを読み込んでみよう。コマンドライン引数の処理方法をまだ知らないので、読み込むファイルは固定にする。
open_in
でファイルを開き、input_line
で読む。
EOFまで読むと例外になるので、それをキャッチして読込を止める。とても命令型な処理になる。
教科書が何にも役に立たない(笑)。
let fi = open_in "./sample.memo" let lines = let lst = ref [] in let eof = ref false in while not !eof do try lst := !lst @ [(input_line fi)] with End_of_file -> eof := true done; !lst let () = close_in fi let () = List.iter print_endline lines
whileを使ってファイルを読むところは、mutableなlst
やモードを持つeof
が出てきて全然functionalじゃない。がっかりだ。
とりあえず、これでcatコマンド相当だ。
tailにするには、listの後ろを取り出す。実は後ろを取り出すのは、再帰だと簡単だ。 こんな関数で出来る。
let n = 5 let rec tail lst = match lst with [] -> [] | first :: rest -> let last = tail rest in if List.length last > n - 1 then last else first :: last
これで後ろの5行が取り出せることになる。