udpate the type of CCKlist

This commit is contained in:
Simon Cruanes 2014-05-26 21:26:45 +02:00
parent 8ba39cb32d
commit ffcdfa8625
2 changed files with 64 additions and 47 deletions

View file

@ -25,31 +25,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Continuation List} *) (** {1 Continuation List} *)
type + 'a t = unit ->
type + 'a t =
[ `Nil [ `Nil
| `Cons of 'a * (unit -> 'a t) | `Cons of 'a * 'a t
] ]
let nil = `Nil let nil () = `Nil
let _nil () = nil let cons a b () = `Cons (a,b)
let cons a b = `Cons (a,b)
let empty = nil let empty = nil
let singleton x = `Cons (x, fun () -> `Nil) let singleton x () = `Cons (x, nil)
let is_empty = function let is_empty l = match l () with
| `Nil -> true | `Nil -> true
| `Cons _ -> false | `Cons _ -> false
let to_list l = let to_list l =
let rec direct i (l:'a t) = match l with let rec direct i (l:'a t) = match l () with
| `Nil -> [] | `Nil -> []
| _ when i=0 -> safe [] l | _ when i=0 -> safe [] l
| `Cons (x, f) -> x :: direct (i-1) (f ()) | `Cons (x, f) -> x :: direct (i-1) f
and safe acc l = match l with and safe acc l = match l () with
| `Nil -> List.rev acc | `Nil -> List.rev acc
| `Cons (x,l') -> safe (x::acc) (l' ()) | `Cons (x,l') -> safe (x::acc) l'
in in
direct 200 l direct 200 l
@ -57,87 +55,104 @@ let of_list l =
let rec aux l () = match l with let rec aux l () = match l with
| [] -> `Nil | [] -> `Nil
| x::l' -> `Cons (x, aux l') | x::l' -> `Cons (x, aux l')
in aux l () in aux l
type 'a sequence = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit
type 'a gen = unit -> 'a option type 'a gen = unit -> 'a option
let rec to_seq res k = match res with let rec to_seq res k = match res () with
| `Nil -> () | `Nil -> ()
| `Cons (s, f) -> k s; to_seq (f ()) k | `Cons (s, f) -> k s; to_seq f k
let to_gen l = let to_gen l =
let l = ref l in let l = ref l in
fun () -> fun () ->
match !l with match !l () with
| `Nil -> None | `Nil -> None
| `Cons (x,l') -> | `Cons (x,l') ->
l := l' (); l := l';
Some x Some x
let rec fold f acc res = match res with let rec fold f acc res = match res () with
| `Nil -> acc | `Nil -> acc
| `Cons (s, cont) -> fold f (f acc s) (cont ()) | `Cons (s, cont) -> fold f (f acc s) cont
let rec iter f l = match l with let rec iter f l = match l () with
| `Nil -> () | `Nil -> ()
| `Cons (x, l') -> f x; iter f (l' ()) | `Cons (x, l') -> f x; iter f l'
let length l = fold (fun acc _ -> acc+1) 0 l let length l = fold (fun acc _ -> acc+1) 0 l
let rec take n (l:'a t):'a t = match l with let rec take n (l:'a t) () = match l () with
| _ when n=0 -> `Nil | _ when n=0 -> `Nil
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (x,l') -> `Cons (x, fun () -> take (n-1) (l' ())) | `Cons (x,l') -> `Cons (x, take (n-1) l')
let rec drop n (l:'a t) = match l with let rec drop n (l:'a t) () = match l () with
| _ when n=0 -> l | l' when n=0 -> l'
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (_,l') -> drop (n-1) (l'()) | `Cons (_,l') -> drop (n-1) l' ()
let rec map f l = match l with (*$Q
(Q.pair (Q.list Q.small_int) Q.small_int) (fun (l,n) -> \
let s = of_list l in let s1, s2 = take n s, drop n s in \
append s1 s2 |> to_list = l )
*)
let rec map f l () = match l () with
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (x, l') -> `Cons (f x, fun () -> map f (l' ())) | `Cons (x, l') -> `Cons (f x, map f l')
let rec fmap f (l:'a t):'b t = match l with (*$T
(map ((+) 1) (1 -- 5) |> to_list) = (2 -- 6 |> to_list)
*)
let rec fmap f (l:'a t) () = match l() with
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (x, l') -> | `Cons (x, l') ->
begin match f x with begin match f x with
| None -> fmap f (l' ()) | None -> fmap f l' ()
| Some y -> `Cons (y, fun () -> fmap f (l' ())) | Some y -> `Cons (y, fmap f l')
end end
let rec filter p l = match l with (*$T
fmap (fun x -> if x mod 2=0 then Some (x*3) else None) (1--10) |> to_list \
= [6;12;18;24;30]
*)
let rec filter p l () = match l () with
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (x, l') -> | `Cons (x, l') ->
if p x if p x
then `Cons (x, fun () -> filter p (l' ())) then `Cons (x, filter p l')
else filter p (l' ()) else filter p l' ()
let rec append l1 l2 = match l1 with let rec append l1 l2 () = match l1 () with
| `Nil -> l2 | `Nil -> l2 ()
| `Cons (x, l1') -> `Cons (x, fun () -> append (l1' ()) l2) | `Cons (x, l1') -> `Cons (x, append l1' l2)
let rec flat_map f l = match l with let rec flat_map f l () = match l () with
| `Nil -> `Nil | `Nil -> `Nil
| `Cons (x, l') -> | `Cons (x, l') ->
_flat_map_app f (f x) (l' ()) () _flat_map_app f (f x) l' ()
and _flat_map_app f l l' () = match l with and _flat_map_app f l l' () = match l () with
| `Nil -> flat_map f l' | `Nil -> flat_map f l' ()
| `Cons (x, tl) -> | `Cons (x, tl) ->
`Cons (x, _flat_map_app f (tl ()) l') `Cons (x, _flat_map_app f tl l')
let flatten l = flat_map (fun x->x) l let flatten l = flat_map (fun x->x) l
let range i j = let range i j =
let rec aux i j () = let rec aux i j () =
if i=j then cons i _nil if i=j then `Cons(i, nil)
else if i<j then `Cons (i, aux (i+1) j) else if i<j then `Cons (i, aux (i+1) j)
else `Cons (i, aux (i-1) j) else `Cons (i, aux (i-1) j)
in aux i j () in aux i j
(*$T (*$T
range 0 5 |> to_list = [0;1;2;3;4;5] range 0 5 |> to_list = [0;1;2;3;4;5]
range 0 0 |> to_list = [0] range 0 0 |> to_list = [0]
range 5 2 |> to_list = [5;4;3;2] range 5 2 |> to_list = [5;4;3;2]
*) *)
let (--) = range

View file

@ -25,16 +25,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Continuation List} *) (** {1 Continuation List} *)
type + 'a t = type + 'a t = unit ->
[ `Nil [ `Nil
| `Cons of 'a * (unit -> 'a t) | `Cons of 'a * 'a t
] ]
val nil : 'a t val nil : 'a t
val empty : 'a t val empty : 'a t
val cons : 'a -> (unit -> 'a t) -> 'a t val cons : 'a -> 'a t -> 'a t
val singleton : 'a -> 'a t val singleton : 'a -> 'a t
@ -75,3 +75,5 @@ val flat_map : ('a -> 'b t) -> 'a t -> 'b t
val flatten : 'a t t -> 'a t val flatten : 'a t t -> 'a t
val range : int -> int -> int t val range : int -> int -> int t
val (--) : int -> int -> int t