diff options
Diffstat (limited to 'std/prelude/iterators.pk')
-rw-r--r-- | std/prelude/iterators.pk | 91 |
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 |