forked from idris-community/idris2-containers
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnsized.idr
More file actions
232 lines (209 loc) · 5.21 KB
/
Copy pathUnsized.idr
File metadata and controls
232 lines (209 loc) · 5.21 KB
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
||| General purpose linear two-end finite sequences.
|||
||| This is implemented by finger tree.
module Data.Seq1.Unsized
import Control.WellFounded
import Data.Linear.Ref1
import public Data.Zippable
import Data.Seq.Internal
%default total
||| A linear two-end finite sequence.
export
data Seq1 : (s : Type) -> (e : Type) -> Type where
MkSeq1 : Ref s (FingerTree (Elem e))
-> Seq1 s e
||| O(1). The empty sequence.
export
empty : F1 s (Seq1 s e)
empty t =
let tr # t := ref1 Empty t
in MkSeq1 tr # t
||| O(1). A singleton sequence.
export
singleton : e
-> F1 s (Seq1 s e)
singleton a t =
let tr # t := ref1 (Single (MkElem a)) t
in MkSeq1 tr # t
||| O(n). A sequence of length n with a the value of every element.
export
replicate : (n : Nat)
-> (a : e)
-> F1 s (Seq1 s e)
replicate n a t =
let tr # t := ref1 (replicate' n a) t
in MkSeq1 tr # t
||| O(1). The number of elements in the sequence.
export
length : Seq1 s a
-> F1 s Nat
length (MkSeq1 tr) t =
let tr' # t := read1 tr t
in length' tr' # t
||| O(n). Reverse the sequence.
export
reverse : Seq1 s a
-> F1' s
reverse (MkSeq1 tr) t =
casmod1 tr (\tr' => reverseTree id tr') t
export infixr 5 `cons`
||| O(1). Add an element to the left end of a sequence.
export
cons : e
-> Seq1 s e
-> F1' s
(a `cons` (MkSeq1 tr)) t =
casmod1 tr (\tr' => MkElem a `consTree` tr') t
export infixl 5 `snoc`
||| O(1). Add an element to the right end of a sequence.
export
snoc : Seq1 s e
-> e
-> F1' s
((MkSeq1 tr) `snoc` a) t =
casmod1 tr (\tr' => tr' `snocTree` MkElem a) t
||| O(1). View from the left of the sequence.
export
viewl : Seq1 s e
-> F1 s (Maybe (e, Seq1 s e))
viewl (MkSeq1 tr) t =
casupdate1 tr
(\tr' =>
case viewLTree tr' of
Just (MkElem a, tr'') =>
(tr'', Just (a, MkSeq1 tr))
Nothing =>
(tr', Nothing)
) t
||| O(1). The first element of the sequence.
export
head : Seq1 s e
-> F1 s (Maybe e)
head (MkSeq1 tr) t =
let tr' # t := read1 tr t
in case viewLTree tr' of
Just (MkElem a, _) =>
Just a # t
Nothing =>
Nothing # t
||| O(1). The elements after the head of the sequence.
||| Returns an empty sequence when the sequence is empty.
export
tail : Seq1 s e
-> F1' s
tail (MkSeq1 tr) t =
casmod1 tr
(\tr' =>
case viewLTree tr' of
Just (MkElem _, tr'') =>
tr''
Nothing =>
tr'
) t
||| O(1). View from the right of the sequence.
export
viewr : Seq1 s e
-> F1 s (Maybe (Seq1 s e, e))
viewr (MkSeq1 tr) t =
casupdate1 tr
(\tr' =>
case viewRTree tr' of
Just (tr'', MkElem a) =>
(tr'', Just (MkSeq1 tr, a))
Nothing =>
(tr', Nothing)
) t
||| O(1). The elements before the last element of the sequence.
||| Returns an empty sequence when the sequence is empty.
export
init : Seq1 s e
-> F1' s
init (MkSeq1 tr) t =
casmod1 tr
(\tr' =>
case viewRTree tr' of
Just (tr'', MkElem _) =>
tr''
Nothing =>
tr'
) t
||| O(1). The last element of the sequence.
export
last : Seq1 s e
-> F1 s (Maybe e)
last (MkSeq1 tr) t =
let tr' # t := read1 tr t
in case viewRTree tr' of
Just (_, MkElem a) =>
Just a # t
Nothing =>
Nothing # t
||| O(n). Turn a list into a sequence.
export
fromList : List e
-> F1 s (Seq1 s e)
fromList xs t =
let tr # t := ref1 (foldr (\x, acc => MkElem x `consTree` acc) Empty xs) t
in (MkSeq1 tr) # t
||| Turn a sequence into a list. O(n)
export
toList : Seq1 s e
-> F1 s (List e)
toList seq t =
go seq Lin t
where
go : Seq1 s e
-> (sl : SnocList e)
-> F1 s (List e)
go seq sl t =
let tr # t := Data.Seq1.Unsized.viewl seq t
in case tr of
Nothing =>
(sl <>> []) # t
Just (x, tr') =>
(assert_total (go tr' (sl :< x))) t
||| O(log(min(i, n-i))). The element at the specified position.
export
index : Nat
-> Seq1 s e
-> F1 s (Maybe e)
index i (MkSeq1 tr) t =
let tr' # t := read1 tr t
in case i < length' tr' of
True =>
let (_, MkElem a) := lookupTree i tr'
in Just a # t
False =>
Nothing # t
||| O(log(min(i, n-i))). Update the element at the specified position.
||| If the position is out of range, the original sequence is returned.
export
adjust : (e -> e)
-> Nat
-> Seq1 s e
-> F1' s
adjust f i (MkSeq1 tr) t =
casmod1 tr
(\tr' =>
case i < length' tr' of
True =>
adjustTree (const (map f)) i tr'
False => tr'
) t
||| O(log(min(i, n-i))). Replace the element at the specified position.
||| If the position is out of range, the original sequence is returned.
export
update : Nat
-> e
-> Seq1 s e
-> F1' s
update i a seq t =
adjust (const a) i seq t
||| Dump the internal structure of the finger tree.
export
show' : Show e
=> Seq1 s e
-> F1 s String
show' (MkSeq1 tr) t =
let tr' # t := read1 tr t
in showPrec Open tr' # t