OCaml始めました.

文法がよく解らない.Syntax errorの嵐.Schemeではこんなことはなかったのに….
echoを書くのにえらく苦労した.
いくつかよく解らない点やがっかりした点があるのでとりあえず列挙

  • マニュアルが解りにくい.(日本語の)ドキュメントが少ない?
  • デバッグ用の,なんでも表示できる関数が無い?(リストの中身を確認するのに一々List.iterを使うの?)
  • コメントが複数行コメントしか無い.
  • その複数行コメントが(*…*)なので,(+)と同じように(*)と書きたいのにコメントの開始にされてしまう.
  • 例えばread_stringが常にstringを返す.EOFを検知するには例外処理をしないといけない…のか?
  • Schemeでいうところの)compose, unfold, unfold-right, iota等が無い?
  • List.mapが末尾再帰でない.何故?((fun f x -> List.rev (List.rev_map f x))より早いということ?)
  • (fun f x -> List.rev (List.rev_map f x))をcomposeで作ろうと思ったら無理だった(カリー化されてるから当然かな…?).試行錯誤の末,( ($) $ ($) ) rev rev_mapでできたが何故できたか解らない.しかも一度intのlistに適用したら型が(int -> int) -> int list -> int listになってしまった.funで作ればこのようなことはないし,Schemeだったら(compose rev rev-map)みたいな感じで終わり.

0引数関数や可変長引数な関数が作れないのは仕方ないのかな.


2000までの双子素数を求めてみた.

let unfold_right p g seed =
  let rec loop seed lis =
    if p seed then
      lis
    else
      loop (g seed) (seed :: lis)
  in loop seed [];;

let iota len start step =
  unfold_right ((=) (start - step)) (fun x -> x - step) ((len - 1) * step + start);;

let prime_list max =
  let rec loop head tail =
    match tail with
        [] -> head
      | x :: xs ->
          if x * x > max then
            List.rev_append head tail
          else
            loop (x :: head) (List.filter (fun y -> ((y mod x) <> 0)) xs) in
    loop [] (iota (max - 2) 2 1);;

let rec loop tuple =
  match tuple with
      (list, []) | ([], list) -> ()
    | (x :: xs, y :: ys) -> begin
        if y - x = 2 then begin
          print_int x;
          print_char ',';
          print_int y;
          print_newline ()
        end;
        loop (xs, ys)
      end in
let list1 = (prime_list 2000) in
  loop (list1, List.tl list1);;

綺麗なのか,汚いのかも解らんなぁ.Schemeがいかに簡単かということがよく解った.
はてなの色付けが微妙だ….