プログラミング in OCaml
unit型の無限列表現が少しわかりにくかったので、頭を整理する目的で、ちょっと考えてみた。
まず、unit 型。
(* unit型 *)
type 'a seq = Cons of 'a * (unit -> 'a seq);;
(* unit型の無限列表現 *)
let rec from n = Cons (n, fun () -> from (n+1));;
let Cons(x1, f1) = from 1
let Cons(x2, f2) = f1 ()
let Cons(x3, f3) = f2 ();;
まあ、こんな感じかなあ。
from 1 => Cons(1, (Cons 2, (Cons 3 ……)
n 番目の要素を取得する関数 nthseq は、以下のようになるかな。
let rec nthseq n (Cons(x, f)) =
if n = 1 then x
else nthseq (n-1) (f ()) ;;
(* 実行例 *)
let test_nthseq = nthseq 5 (from 1) = 5;; (* true *)
その無限列の各要素に関数を適用する。
let rec mapseq f (Cons (x, tail)) =
Cons (f x, fun () -> mapseq f (tail ()));;
各要素の逆数をとる関数 recipracal を定義。
let reciprocals = mapseq (fun x -> 1.0 /. float_of_int x) (from 2);;
無限列のはじめの n 要素をリストにする関数 take
let take n (Cons(x, f)) =
let rec take_in n (Cons(x, f)) e =
if n = 1 then e @ [x]
else take_in (n-1) (f ()) (e @ [x] )
in
take_in n (Cons(x, f)) [];;
(* 実行例 *)
let test_take = take 5 reciprocals =
[0.5; 0.333333333333333315; 0.25; 0.2; 0.166666666666666657];; (* true*)