package tiny_json

  1. Overview
  2. Docs

Source file llist.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
open Util

type 'a llist = Nil | Cons of 'a * 'a llist Lazy.t

type 'a t = 'a llist Lazy.t

let to_list ll =
  let rec to_list st = function
    | Nil -> List.rev st
    | Cons (x, xs) ->
        to_list (x :: st) (Lazy.force xs)
  in
  to_list [] ll

let hd = function | Nil -> failwith "hd" | Cons (x, _xs) -> x
let tl = function | Nil -> failwith "tl" | Cons (_x, xs) -> !$xs

let rec take n l =
  match n, l with
  | 0, _ -> []
  | _n, Nil -> []
  | n, Cons (x, xs) -> x :: take (n-1) !$xs

let rec map f = function
  | Nil -> Nil
  | Cons (x, xs) -> Cons (f x, lazy (map f !$xs))

let rec repeat x = Cons (x, lazy (repeat x));;

let rec app xs ys =
  match xs with
  | Nil -> ys
  | Cons (x, xs) -> Cons (x, lazy (app (!$ xs) ys))

let rec combine xs ys =
  match (xs,ys) with 
  | Cons(x,xs),Cons(y,ys) -> Cons((x,y), lazy (combine !$xs !$ys))
  | _ -> Nil

let rec filter f xs =
  match xs with
  | Nil -> Nil
  | Cons(x, xs) when f x -> Cons (x, lazy (filter f !$xs))
  | Cons(_x, xs) -> filter f !$xs

let rec concat xss =
  match xss with 
  | Nil -> Nil
  | Cons(Nil, xss') -> concat !$xss'
  | Cons(Cons(x,lazy xs'), xss') -> Cons(x, lazy (concat (Cons(xs', xss'))))

let rec unfoldr f b =
  match f b with
  | Some (a, new_b) -> Cons(a, lazy (unfoldr f new_b))
  | None -> Nil

let continually make =
  let f () = try Some(make (), ()) with _ -> None in
  unfoldr f ()

(* int llist *)
let rec from n = Cons (n, lazy (from (n+1)))


(* llist <--> stream *)
let rec of_stream str =
  try
    Cons (Stream.next str, lazy (of_stream str))
  with
  | Stream.Failure -> Nil

let sllist ?(items:int=20) delim show l =
  let fin = take items l in
  if List.length fin <= items then
    slist delim show fin
  else
    slist delim show fin ^ "..."

(* string -> llist *)
let of_string =
  of_stream $ Stream.of_string

let of_function f =
  let buf = Bytes.create 1024 in
  
  let rec fill () = 
    let read = f buf 1024 in
    if read = 0 then Nil
    else Cons (Bytes.unsafe_get buf 0, lazy (use read 1))
  
  and use read pos = 
    if read <= pos then fill ()
    else Cons (Bytes.unsafe_get buf pos, lazy (use read (pos+1)))

  in
  
  fill ()