Sophie

Sophie

distrib > Mandriva > 2010.2 > i586 > by-pkgid > 0d9d5bda371b7626336c9a789891d9be > files > 7

ocaml-pure-fun-doc-1.0.8-4mdv2010.1.noarch.rpm

(*
   Original source code in SML from:

     Purely Functional Data Structures
     Chris Okasaki
     Cambridge University Press, 1998
     Copyright (c) 1998 Cambridge University Press

   Translation from SML to OCAML (this file):

     Copyright (C) 1999 - 2002  Markus Mottl
     email:  markus.mottl@gmail.com
     www:    http://www.ocaml.info

   Unless this violates copyrights of the original sources, the following
   licence applies to this file:

   This source code is free software; you can redistribute it and/or
   modify it without any restrictions. It is distributed in the hope
   that it will be useful, but WITHOUT ANY WARRANTY.
*)

(***********************************************************************)
(*                              Chapter 4                              *)
(***********************************************************************)

let (!$) = Lazy.force

module type STREAM = sig
  type 'a stream = Nil | Cons of 'a * 'a stream Lazy.t

  val (++) : 'a stream -> 'a stream -> 'a stream  (* stream append *)
  val take : int -> 'a stream -> 'a stream
  val drop : int -> 'a stream -> 'a stream
  val reverse : 'a stream -> 'a stream
end

module Stream : STREAM = struct
  type 'a stream = Nil | Cons of 'a * 'a stream Lazy.t

  (* function lazy *)
  let rec (++) s1 s2 = match s1 with
    | Nil -> s2
    | Cons (hd, tl) -> Cons (hd, lazy (!$tl ++ s2))

  (* function lazy *)
  let rec take n = function
    | _ when n = 0 -> Nil
    | Nil -> Nil
    | Cons (hd, tl) -> Cons (hd, lazy (take (n - 1) !$tl))

  (* function lazy *)
  let rec drop n = function
    | s when n = 0 -> s
    | Nil -> Nil
    | Cons (_, tl) -> drop (n - 1) !$tl

  (* function lazy *)
  let reverse s =
    let rec reverse' acc = function
      | Nil -> acc
      | Cons (hd, tl) -> reverse' (Cons (hd, lazy acc)) !$tl in
    reverse' Nil s
end

(*
(* MM: for demonstration purposes *)
open Stream

let rec l_map f = function
  | Nil -> Nil
  | Cons (hd, tl) -> Cons (f hd, lazy (l_map f !$tl))

let rec l_iter f n = function
  | Nil -> ()
  | Cons (hd, tl) -> if n > 0 then begin f hd; l_iter f (n-1) !$tl end

let rec nat = Cons (0, lazy (l_map succ nat))

let _ =
  let test = reverse (take 10 (drop 50 (take 1000000000 nat))) in
  l_iter (fun n -> print_int n; print_newline ()) 1000 test
*)