diff --git a/findatastructures/src/seqlist/mod.rs b/findatastructures/src/seqlist/mod.rs index 50fb2fb..978841b 100644 --- a/findatastructures/src/seqlist/mod.rs +++ b/findatastructures/src/seqlist/mod.rs @@ -1,88 +1,171 @@ use seq::Seq; use seq::SeqIterator; -enum SeqRef<'a, T> { - Owned(Seq<'a, T>), - Borrowed(&'a Seq<'a, T>), +#[derive(Debug, Clone)] +pub struct SeqList<'a, T> { + seq: Seq<'a, T>, } -impl<'a, T:Clone> SeqRef<'a, T> { - fn get_ref(&'a self) -> &'a Seq<'a, T> { - match self { - SeqRef::Owned(seq) => &seq, - SeqRef::Borrowed(seq) => seq, - } - } - fn push(&'a self, value: T) -> Self { - let seq = match &self { - SeqRef::Owned(seq) => Seq::ConsRef(value, &seq), - SeqRef::Borrowed(seq) => Seq::ConsRef(value, seq), - }; - SeqRef::Owned(seq) - } - fn pop(&'a self) -> Option<(&T, Self)> { - self.get_ref().tail().map(|tail| { - ( - self.get_ref().head().unwrap(), - SeqRef::Borrowed(tail), - ) - }) - } +impl<'a, T: Clone> SeqList<'a, T> { + pub fn new() -> Self { + SeqList { seq: Seq::Empty } + } + + pub fn push(&'a self, value: T) -> Self { + SeqList { + seq: Seq::ConsRef(value, &self.seq), + } + } + + pub fn pop(&'a self) -> Option<(&T, Self)> { + self.seq.head().map(|head| { + ( + head, + SeqList { + seq: self.seq.tail().unwrap().clone(), + }, + ) + }) + } + + pub fn peek(&'a self) -> Option<&T> { + self.seq.head() + } + + pub fn is_empty(&'a self) -> bool { + self.seq.head().is_none() + } + + pub fn len(&'a self) -> usize { + self.seq.into_iter().count() + } + + pub fn reverse(&'a self) -> Self { + SeqList { + seq: self.into_iter().fold(Seq::Empty, |acc, item| { + Seq::ConsOwn(item.clone(), Box::new(acc)) + }), + } + } + + pub fn map(&self, f: F) -> SeqList<'a, U> + where + F: Fn(&T) -> U, + { + let mut seq = Seq::Empty; + for item in self.into_iter() { + seq = Seq::ConsOwn(f(item), Box::new(seq)); + } + for item in seq.clone().into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone())); + } + SeqList { seq: seq } + } + + pub fn fold(&self, init: U, f: F) -> U + where + F: Fn(U, &T) -> U, + { + let mut acc = init; + for item in self.into_iter() { + acc = f(acc, item); + } + acc + } + + pub fn any(&self, f: F) -> bool + where + F: Fn(&T) -> bool, + { + self.fold(false, |acc, item| acc || f(item)) + } + + pub fn all(&self, f: F) -> bool + where + F: Fn(&T) -> bool, + { + self.fold(true, |acc, item| acc && f(item)) + } + + pub fn find(&self, f: F) -> Option<&T> + where + F: FnMut(&&T) -> bool, + { + self.into_iter().find(f) + } + + pub fn filter(&self, f: F) -> Self + where + F: Fn(&T) -> bool, + { + let mut seq = Seq::Empty; + for item in self.into_iter() { + if f(item) { + seq = Seq::ConsOwn(item.clone(), Box::new(seq)); + } + } + for item in seq.clone().into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone())); + } + SeqList { seq: seq } + } } -pub struct SeqList<'a, T> { - seq: SeqRef<'a, T>, +impl<'a, T: Clone + PartialEq> SeqList<'a, T> { + pub fn remove(&self, value: &T) -> Self { + self.filter(|x| *x != *value) + } + + pub fn chain(&self, other: &Self) -> Self { + let mut seq = Seq::Empty; + for item in self.into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq)); + } + for item in other.into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq)); + } + for item in seq.clone().into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone())); + } + SeqList { seq: seq } + } } -impl<'a, T:Clone> SeqList<'a, T> { - pub fn new() -> Self { - SeqList { seq: SeqRef::Borrowed(&Seq::Empty) } - } - - pub fn push(&'a self, value: T) -> Self { - SeqList { seq: self.seq.push(value) } - } - - pub fn pop(&'a self) -> Option<(&T, Self)> { - self.seq.pop().map(|(head, tail)| { - ( - head, - SeqList { seq: tail }, - ) - }) - } - - pub fn peek(&'a self) -> Option<&T> { - self.seq.get_ref().head() - } - - pub fn is_empty(&'a self) -> bool { - self.seq.get_ref().head().is_none() - } - - pub fn len(&'a self) -> usize { - self.seq.get_ref().into_iter().count() - } - - pub fn into_iter(&'a self) -> SeqIterator<'a, T> { - self.seq.get_ref().into_iter() - } - - pub fn reverse(&'a self) -> Self { - let mut new = SeqList::new(); - for item in self.into_iter() { - new = new.push(item.clone()); - } - new - } - - pub fn from_iter(iter: SeqIterator<'a, T>) -> Self { - let new = SeqList::new(); - for item in iter { - new = new.push(item.clone()); - } - new = new.reverse(); - new - } +impl<'a, T> IntoIterator for &'a SeqList<'a, T> +where + T: 'a, +{ + type Item = &'a T; + type IntoIter = SeqIterator<'a, T>; + fn into_iter(self) -> Self::IntoIter { + self.seq.into_iter() + } +} + +impl<'a, T: Clone> FromIterator for SeqList<'a, T> { + fn from_iter>(iter: I) -> Self { + let mut seq = Seq::Empty; + for item in iter { + seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone())); + } + for item in seq.clone().into_iter() { + seq = Seq::ConsOwn(item.clone(), Box::new(seq.clone())); + } + SeqList { seq: seq } + } +} +impl<'a, T: PartialEq> SeqList<'a, T> { + pub fn contains(&self, v: &T) -> bool { + self.into_iter().any(|x| x == v) + } +} + +impl<'a, T: Clone + PartialEq> PartialEq for SeqList<'a, T> { + fn eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + self.into_iter().zip(other.into_iter()).all(|(a, b)| a == b) + } }