-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaugment-vector.sml
251 lines (251 loc) · 6.5 KB
/
augment-vector.sml
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
(*
Functors for augmentation of simple vectors
*)
signature UNCREATABLE_VECTOR = sig
type vector
type elem
val maxLen: int
val length: vector -> int
val sub: vector * int -> elem
val appi: (int * elem -> unit) -> vector -> unit
val app: (elem -> unit) -> vector -> unit
val foldli: (int * elem * 'a -> 'a) -> 'a -> vector -> 'a
val foldri: (int * elem * 'a -> 'a) -> 'a -> vector -> 'a
val foldl: (elem * 'a -> 'a) -> 'a -> vector -> 'a
val foldr: (elem * 'a -> 'a) -> 'a -> vector -> 'a
val findi: (int * elem -> bool) -> vector -> (int * elem) option
val find: (elem -> bool) -> vector -> elem option
val exists: (elem -> bool) -> vector -> bool
val all: (elem -> bool) -> vector -> bool
val collate: (elem * elem -> order) -> vector * vector -> order
end
functor AugmentUncreatableVector (MonoVector: sig
type vector
type elem
val maxLen: int
val length: vector -> int
val sub: vector * int -> elem
end) :> UNCREATABLE_VECTOR
where type vector = MonoVector.vector
where type elem = MonoVector.elem
= struct
type vector = MonoVector.vector
type elem = MonoVector.elem
val maxLen = MonoVector.maxLen
val length = MonoVector.length
val sub = MonoVector.sub
fun appi function vector =
let
val length = MonoVector.length vector
fun loop index =
if index >= length then ()
else (
function (index, MonoVector.sub (vector, index))
; loop (index + 1)
)
in
loop 0
end
fun app function vector = appi (fn (_, element) => function element) vector
fun foldi step test function seed vector =
let
val length = MonoVector.length vector
fun loop (index, state) =
if test index then state
else loop (
step index
, function (index, MonoVector.sub (vector, index), state)
)
in
loop (0, seed)
end
fun foldli function seed vector = foldi
(fn index => index + 1)
(fn index => index >= MonoVector.length vector)
function seed vector
fun foldri function seed vector = foldi
(fn index => index - 1)
(fn index => index < 0)
function seed vector
fun foldl function seed vector =
foldli (fn (_, element, state) => function (element, state)) seed vector
fun foldr function seed vector =
foldri (fn (_, element, state) => function (element, state)) seed vector
fun findi function vector =
let
val length = MonoVector.length vector
fun loop index =
if index >= length then NONE
else let
val element = MonoVector.sub (vector, index)
in
if function (index, element) then SOME (index, element)
else loop (index + 1)
end
in
loop 0
end
fun find function vector =
case findi (fn (_, element) => function element) vector of
NONE => NONE
| SOME (_, element) => SOME element
fun exists function vector =
case find function vector of
NONE => false
| SOME _ => true
fun all function vector = not (exists (not o function) vector)
fun collate compare (vectorA, vectorB) =
let
val lengthA = MonoVector.length vectorA
val lengthB = MonoVector.length vectorB
fun loop index =
if index >= lengthA then (
if index >= lengthB then EQUAL
else LESS
) else if index >= lengthB then GREATER
else case
compare (
MonoVector.sub (vectorA, index)
, MonoVector.sub (vectorB, index)
)
of
EQUAL => loop (index + 1)
| result => result
in
loop 0
end
end
signature CREATABLE_VECTOR = sig
include UNCREATABLE_VECTOR
val fromList: elem list -> vector
val tabulate: int * (int -> elem) -> vector
val update: vector * int * elem -> vector
val concat: vector list -> vector
val mapi: (int * elem -> elem) -> vector -> vector
val map: (elem -> elem) -> vector -> vector
end
functor AugmentCreatableVector (MonoVector: sig
type vector
type elem
val maxLen: int
val unfoldi: int * 'a * (int * 'a -> elem * 'a) -> vector * 'a
val length: vector -> int
val sub: vector * int -> elem
end) :> CREATABLE_VECTOR
where type vector = MonoVector.vector
where type elem = MonoVector.elem
= struct
structure Uncreatable = AugmentUncreatableVector (MonoVector)
open Uncreatable
fun fromList list =
let
val (vector, _) = MonoVector.unfoldi (
List.length list
, list
, fn
(_, nil) => raise Fail "impossible"
| (_, head :: tail) => (head, tail)
)
in
vector
end
fun tabulate (length, createElement) =
let
val (vector, _) = MonoVector.unfoldi (
length
, ()
, fn (index, ()) => (createElement index, ())
)
in
vector
end
fun update (oldVector, newIndex, newElement) =
let
val (newVector, _) = MonoVector.unfoldi (
MonoVector.length oldVector
, ()
, fn (i, ()) =>
if i = newIndex then (newElement, ())
else (MonoVector.sub (oldVector, i), ())
)
in
newVector
end
fun concat vectors =
let
val totalLength =
List.foldl (fn (vector, length) =>
MonoVector.length vector + length
) 0 vectors
fun loop x = case x of
(_, (_, nil)) => raise Fail "impossible"
| (totalIndex, (indexOfThis, both as (this :: rest))) =>
if indexOfThis < MonoVector.length this then
(
MonoVector.sub (this, indexOfThis)
, (indexOfThis + 1, both)
)
else loop (totalIndex, (0, rest))
val (vector, _) = MonoVector.unfoldi (
totalLength
, (0, vectors)
, loop
)
in
vector
end
fun mapi function oldVector =
let
val (newVector, _) = MonoVector.unfoldi (
MonoVector.length oldVector
, ()
, fn (index, ()) => (
function (index, MonoVector.sub (oldVector, index))
, ()
)
)
in
newVector
end
fun map function vector = mapi (fn (_, element) => function element) vector
end
functor CreatableFromUncreatableVector (MonoVector: sig
type vector
type elem
val maxLen: int
val length: vector -> int
val sub: vector * int -> elem
end) :> MONO_VECTOR
where type elem = MonoVector.elem
= AugmentCreatableVector (struct
datatype vector =
Uncreatable of MonoVector.vector
| Creatable of MonoVector.elem Vector.vector
type elem = MonoVector.elem
val maxLen = Int.min (MonoVector.maxLen, Vector.maxLen)
fun unfoldi (size, seed, step) =
let
val state = ref seed
in
(
Creatable (Vector.tabulate (
size
, fn index =>
let
val (element, nextState) =
step (index, !state)
in
state := nextState
; element
end
))
, !state
)
end
fun length x = case x of
Uncreatable vector => MonoVector.length vector
| Creatable vector => Vector.length vector
fun sub (x, index) = case x of
Uncreatable vector => MonoVector.sub (vector, index)
| Creatable vector => Vector.sub (vector, index)
end)