Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh |
2 | * Jagannathan, and Stephen Weeks. | |
3 | * Copyright (C) 1997-2000 NEC Research Institute. | |
4 | * | |
5 | * MLton is released under a BSD-style license. | |
6 | * See the file MLton-LICENSE for details. | |
7 | *) | |
8 | ||
9 | structure List: LIST = | |
10 | struct | |
11 | open Int | |
12 | ||
13 | datatype list = datatype Primitive.List.list | |
14 | ||
15 | exception Empty | |
16 | ||
17 | val null = | |
18 | fn [] => true | |
19 | | _ => false | |
20 | ||
21 | val hd = | |
22 | fn x :: _ => x | |
23 | | _ => raise Empty | |
24 | ||
25 | val tl = | |
26 | fn _ :: l => l | |
27 | | _ => raise Empty | |
28 | ||
29 | val rec last = | |
30 | fn [] => raise Empty | |
31 | | [x] => x | |
32 | | _ :: l => last l | |
33 | ||
34 | val getItem = | |
35 | fn [] => NONE | |
36 | | x :: r => SOME (x, r) | |
37 | ||
38 | fun foldl f b l = | |
39 | let | |
40 | fun loop (l, b) = | |
41 | case l of | |
42 | [] => b | |
43 | | x :: l => loop (l, f (x, b)) | |
44 | in loop (l, b) | |
45 | end | |
46 | ||
47 | fun length l = foldl (fn (_, n) => n +? 1) 0 l | |
48 | ||
49 | fun appendRev (l1, l2) = foldl (op ::) l2 l1 | |
50 | ||
51 | val revAppend = appendRev | |
52 | ||
53 | fun rev l = appendRev (l, []) | |
54 | ||
55 | fun l1 @ l2 = | |
56 | case l2 of | |
57 | [] => l1 | |
58 | | _ => appendRev (rev l1, l2) | |
59 | ||
60 | fun foldr f b l = foldl f b (rev l) | |
61 | ||
62 | fun concat ls = foldr (op @) [] ls | |
63 | ||
64 | fun app f = foldl (f o #1) () | |
65 | ||
66 | fun map f l = rev (foldl (fn (x, l) => f x :: l) [] l) | |
67 | ||
68 | fun mapPartial pred l = | |
69 | rev (foldl (fn (x, l) => (case pred x of | |
70 | NONE => l | |
71 | | SOME y => y :: l)) | |
72 | [] l) | |
73 | ||
74 | fun filter pred = mapPartial (fn x => if pred x then SOME x else NONE) | |
75 | ||
76 | fun partition pred l = | |
77 | let | |
78 | val (pos, neg) = | |
79 | foldl (fn (x, (trues, falses)) => | |
80 | if pred x then (x :: trues, falses) | |
81 | else (trues, x :: falses)) | |
82 | ([], []) l | |
83 | in (rev pos, rev neg) | |
84 | end | |
85 | ||
86 | fun find pred = | |
87 | let | |
88 | val rec loop = | |
89 | fn [] => NONE | |
90 | | x :: l => if pred x | |
91 | then SOME x | |
92 | else loop l | |
93 | in loop | |
94 | end | |
95 | ||
96 | fun exists pred l = | |
97 | case find pred l of | |
98 | NONE => false | |
99 | | SOME _ => true | |
100 | ||
101 | fun all pred = not o (exists (not o pred)) | |
102 | ||
103 | fun tabulate (n, f) = | |
104 | if Primitive.Controls.safe andalso n < 0 | |
105 | then raise Size | |
106 | else let | |
107 | fun loop (i, ac) = | |
108 | if i < n | |
109 | then loop (i + 1, f i :: ac) | |
110 | else rev ac | |
111 | in loop (0, []) | |
112 | end | |
113 | ||
114 | fun nth (l, n) = | |
115 | let | |
116 | fun loop (l, n) = | |
117 | case l of | |
118 | [] => raise Subscript | |
119 | | x :: l => | |
120 | if n > 0 | |
121 | then loop (l, n - 1) | |
122 | else x | |
123 | in | |
124 | if Primitive.Controls.safe andalso n < 0 | |
125 | then raise Subscript | |
126 | else loop (l, n) | |
127 | end | |
128 | ||
129 | fun take (l, n) = | |
130 | let | |
131 | fun loop (l, n, ac) = | |
132 | if n > 0 | |
133 | then (case l of | |
134 | [] => raise Subscript | |
135 | | x :: l => loop (l, n - 1, x :: ac)) | |
136 | else rev ac | |
137 | in | |
138 | if Primitive.Controls.safe andalso n < 0 | |
139 | then raise Subscript | |
140 | else loop (l, n, []) | |
141 | end | |
142 | ||
143 | fun drop (l, n) = | |
144 | let | |
145 | fun loop (l, n) = | |
146 | if n > 0 | |
147 | then (case l of | |
148 | [] => raise Subscript | |
149 | | _ :: l => loop (l, n - 1)) | |
150 | else l | |
151 | in | |
152 | if Primitive.Controls.safe andalso n < 0 | |
153 | then raise Subscript | |
154 | else loop (l, n) | |
155 | end | |
156 | ||
157 | fun collate cmp = | |
158 | let | |
159 | val rec loop = | |
160 | fn ([], []) => EQUAL | |
161 | | ([], _) => LESS | |
162 | | (_, []) => GREATER | |
163 | | (x1::l1,x2::l2) => (case cmp (x1, x2) of | |
164 | EQUAL => loop (l1, l2) | |
165 | | ans => ans) | |
166 | in loop | |
167 | end | |
168 | end | |
169 | ||
170 | structure ListGlobal: LIST_GLOBAL = List | |
171 | open ListGlobal |