aboutsummaryrefslogtreecommitdiff
path: root/std/prelude/iterators.pk
diff options
context:
space:
mode:
Diffstat (limited to 'std/prelude/iterators.pk')
-rw-r--r--std/prelude/iterators.pk91
1 files changed, 42 insertions, 49 deletions
diff --git a/std/prelude/iterators.pk b/std/prelude/iterators.pk
index 82137ee..1403b55 100644
--- a/std/prelude/iterators.pk
+++ b/std/prelude/iterators.pk
@@ -1,28 +1,28 @@
-## std.iterators: The Iter interface and associated functions.
+## std.iterators: The Iter class 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
+## The Iter class. Any type implementing `next()` is iterable.
+pub type Iter[T] = class
next(mut Self): T? # should T be lent?
-## The IntoIter interface.
+## The IntoIter class.
## Any type implementing `iter()` may be converted to an iterable type.
-pub type IntoIter[T] = interface
+pub type IntoIter[T] = class
iter(Self): Iter[T]
-## The Peek interface.
+## The Peek class.
## Any type implementing `Iter`, `peek`, and `peek_nth` is peekable.
-pub type Peek[T] = interface
+pub type Peek[T] = class
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()`
+## Implements the Peek class. Can be formed with `.peekable()`
type PeekImpl = struct
iter: ref Iter[T] # this is probably bad... heap allocated...
buf: Queue[T]
@@ -34,26 +34,26 @@ pub func peekable[T](iter: owned Iter[T]): PeekImpl[T] =
pub func next[T](self: mut PeekImpl[T]): T? =
match self.buf.pop()
- of None:
+ of None then
self.iter.next()
- of Some(val):
+ of Some(val) then
val
pub func peek[T](self: mut PeekImpl[T]): T? =
match self.buf.peek()
- of None:
+ of None then
self.buf.push(self.iter.next())
self.buf.peek()
- of Some(val):
+ of Some(val) then
val
pub func peek_nth[T](self: mut PeekImpl[T], i: uint): T? =
- if self.buf.len > i:
+ if self.buf.len > i then
self.buf.get(i)!
- else:
- for _ in self.buf.len .. i: # fixme
+ else
+ for _ in self.buf.len .. i do # fixme
match self.buf.next()
- of None:
+ of None then
return None
- of Some(val):
+ of Some(val) then
self.buf.push(val)
self.buf.peek()
@@ -61,26 +61,23 @@ pub func peek_nth[T](self: mut PeekImpl[T], i: uint): T? =
# 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
+ for i in 0 .. n do
+ if self.next().is_none() then return
-pub func get[T](self: Iter[T], at: uint): Option[T]
+pub func get[T](self: Iter[T], at: uint): 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
+ for elem in self do
+ if not cond(elem) then 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
+ for elem in self do
+ if cond(elem) then return true
false
## Returns true if an Iter contains the given element.
@@ -89,52 +86,48 @@ pub func contains[T](self: Iter[T], val: T): bool =
## 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)
+ for elem in self do
+ if cond(elem) then 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)
+ for elem in self do
+ if cond(elem) then return Some(i)
i += 1
None
+@[inline]
pub func fold[T, U](self: Iter[T], init: U, op: (U, T) -> U) =
var res = init
- for elem in self:
+ for elem in self do
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):
+ of None then None
+ of Some(val) then
var res = val
- for elem in self:
- res = op(res, elem)
+ for elem in self do 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)
+ self.fold(0, (elem, acc) => if elem == element then 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
+ for elem in self do res = elem
res
pub func ==[T](first: Iter[T], second: Iter[T]): bool =
- for (a, b) in :
- if a != b:
- return false
+ if first.len != second.len then return false
+ for (a, b) in zip(first, second) do
+ if a != b then return false
true
type LazyIter = struct
@@ -165,16 +158,16 @@ 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 func to[T](self: LazyIter[T]): list[T]
+pub func to(self: LazyIter[chr]): str
-pub type BoundIter[T] = interface
+pub type BoundIter[T] = class
next(mut Self): T?
pop(mut Self): T?
pub func rev[T](self: BoundIter[T]): BoundIter[T]
-pub type SizedIter[T] = interface
+pub type SizedIter[T] = class
next(mut Self): T?
pop(mut Self): T?
len(Self): uint