読者です 読者をやめる 読者になる 読者になる

unit型を使った無限数列

OCaml
# type 'a seq = Cons of 'a * (unit -> 'a seq);;
type 'a seq = Cons of 'a * (unit -> 'a seq)

# let rec from n = Cons (n, fun () -> from (n+1));;
val from : int -> int seq = <fun>
# let rec take n (Cons (x, f)) = 
    if n > 0 then x :: take (n-1) (f [])
    else [];;
# take 5 (from 2);;
- : int list = [2; 3; 4; 5; 6]

# let fib = 
    let rec f x y () = Cons (x, f (x+y) x) in
    Cons (1, f 1 1);;
val fib : int seq = Cons (1, <fun>)
# take 10 fib;;
- : int list = [1; 1; 2; 3; 5; 8; 13; 21; 34; 55]

# let prime =
    let rec prime_seq primes x () =
      let rec is_prime = function
          [] -> true
        | p :: ps -> p * p > x || (x mod p <> 0 && is_prime ps)
      in if is_prime primes
      then Cons (x, prime_seq (primes @ [x]) (x+2))
      else prime_seq primes (x+2) ()
    in Cons (2, prime_seq [2] 3);;
val prime : int seq = Cons (2, <fun>)
# take 10 prime;;
- : int list = [2; 3; 5; 7; 11; 13; 17; 19; 23; 29]

# let rec mapseq f (Cons (x, tail)) = 
    Cons (f x, fun () -> mapseq f (tail ()));;
val mapseq : ('a -> 'b) -> 'a seq -> 'b seq = <fun>
# let reciprocals = mapseq (fun x -> 1.0 /. float_of_int x) (from 1);;
val reciprocals : float seq = Cons (1., <fun>)
# take 10 reciprocals;;
- : float list =
[1.; 0.5; 0.33333333333333331; 0.25; 0.2; 0.16666666666666666;
 0.14285714285714285; 0.125; 0.1111111111111111; 0.1]

# let squares = mapseq (fun x -> x * x) (from 1);;
val squares : int seq = Cons (1, <fun>)
# take 10 squares;;
- : int list = [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]