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
|
## std.iterators: The Iter interface and associated functions.
## This module is imported by default.
# reference: https://doc.rust-lang.org/std/iter/
# reference: https://docs.rs/itertools/latest/itertools/
use std.queue.ring
## The Iter interface. Any type implementing `next()` is iterable.
pub type Iter[T] = interface
next(mut Self): T? # should T be lent?
## The IntoIter interface.
## Any type implementing `iter()` may be converted to an iterable type.
pub type IntoIter[T] = interface
iter(Self): Iter[T]
## The Peek interface.
## Any type implementing `Iter`, `peek`, and `peek_nth` is peekable.
pub type Peek[T] = interface
next(mut Self): T?
peek(mut Self): T?
peek_nth(mut Self, int): T?
## A concrete Peekable structure formed from a generic Iter type.
## Implements the Peek interface. Can be formed with `.peekable()`
type PeekImpl = struct
iter: ref Iter[T] # this is probably bad... heap allocated...
buf: Queue[T]
## Convert any Iter into a peekable equivalent.
# https://github.com/LukeMathWalker/multipeek/blob/main/src/lib.rs
pub func peekable[T](iter: owned Iter[T]): PeekImpl[T] =
{ iter, buf: ... } # todo: implement Queue, somewhere
pub func next[T](self: mut PeekImpl[T]): T? =
match self.buf.pop()
of None:
self.iter.next()
of Some(val):
val
pub func peek[T](self: mut PeekImpl[T]): T? =
match self.buf.peek()
of None:
self.buf.push(self.iter.next())
self.buf.peek()
of Some(val):
val
pub func peek_nth[T](self: mut PeekImpl[T], i: uint): T? =
if self.buf.len > i:
self.buf.get(i)!
else:
for _ in self.buf.len .. i: # fixme
match self.buf.next()
of None:
return None
of Some(val):
self.buf.push(val)
self.buf.peek()
# todo: useful functions for an iterator
# https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods
func advance_by[T](self: Iter[T], n: uint) =
for i in 0 .. n:
if self.next().is_none():
return
pub func get[T](self: Iter[T], at: uint): Option[T]
self.advance_by(at-1).ok? # fixme
self.next()
## Returns true if every element in an Iter fulfills the conditional.
pub func all[T](self: Iter[T], cond: T -> bool): bool =
for elem in self:
if not cond(elem):
return false
true
## Returns true if any element in an Iter fulfills the conditional.
pub func any[T](self: Iter[T], cond: T -> bool): bool =
for elem in self:
if cond(elem):
return true
false
## Returns true if an Iter contains the given element.
pub func contains[T](self: Iter[T], val: T): bool =
self.any(elem => elem == val)
## Returns the first element matching a condition, if it exists.
pub func find[T](self: Iter[T], cond: T -> bool): T? =
for elem in self:
if cond(elem):
return Some(elem)
None
## Returns the position of the first element matching a condition, if it exists.
pub func position[T](self: Iter[T], cond: T -> bool): T? =
var i = 0
for elem in self:
if cond(elem):
return Some(i)
i += 1
None
pub func fold[T, U](self: Iter[T], init: U, op: (U, T) -> U) =
var res = init
for elem in self:
res = res.op(elem)
res
pub func reduce[T, U](self: Iter[T], op: (U, T) -> U): U? =
match self.next()
of None:
None
of Some(val):
var res = val
for elem in self:
res = op(res, elem)
Some(res)
pub func count[T](self: Iter[T], element: T): uint =
self.fold(0, (elem, acc) => if elem == element: acc + 1 else: acc)
pub func count[T](self: Iter[T]): uint =
self.fold(0, (elem, acc) => acc + 1)
pub func last[T](self: Iter[T]): T =
var res = None
for elem in self:
res = elem
res
pub func ==[T](first: Iter[T], second: Iter[T]): bool =
for (a, b) in :
if a != b:
return false
true
type LazyIter = struct
...
pub func apply[T](self: mut LazyIter[T], fn: T -> T)
pub func map[T, S](self: Iter[T], fn: T -> S): LazyIter[S]
pub func foreach[T, S](self: Iter[T], fn: T -> S): LazyIter[T]
pub func enumerate[T](self: LazyIter[T]): LazyIter[T] # todo: impl with map or similar
pub func dedup[T](self: Iter[T], sorted = false): LazyIter[T]
pub func filter[T](self: Iter[T], cond: T -> bool): LazyIter[T]
## Takes (at most) the first `n` elements of an iterator.
pub func take[T](self: Iter[T], n: uint): LazyIter[T]
## Skips (at most) the first `n` elements of an iterator.
pub func skip[T](self: Iter[T], n: uint): LazyIter[T]
pub func repeat[T](self: Iter[T], n: uint): LazyIter[T] # cycle??
pub func intersperse[T](self: Iter[T], item: T): LazyIter[T]
pub func step[T](self: Iter[T], step: uint): LazyIter[T]
pub func flatten[T](self: Iter[Iter[T]]): LazyIter[T]
pub func chain[T](first: Iter[T], second: Iter[T]): LazyIter[T]
pub func zip[T, U](first: Iter[T], second: Iter[U]): Iter[(T, U)]
pub func unzip[T, U](self: Iter[(T, U)]): (Iter[T], Iter[U])
# equivalent of collect. useful for type conversion
pub func from[T](self: LazyIter[T]): list[T]
pub func from(self: LazyIter[chr]): str
pub type BoundIter[T] = interface
next(mut Self): T?
pop(mut Self): T?
pub func rev[T](self: BoundIter[T]): BoundIter[T]
pub type SizedIter[T] = interface
next(mut Self): T?
pop(mut Self): T?
len(Self): uint
get(mut Self): T?
pub func max(self: Iter[Comparable[T]]): T
pub func min(self: Iter[Comparable[T]]): T
pub func sorted(self: Iter[Comparable[T]]): bool
|