use std::rc::Rc;
use std::fmt;
use std::iter::FromIterator;
use std::borrow::Borrow;
struct Node<T> {
value: T,
next: Option<Rc<Node<T>>>,
}
impl <T: PartialEq> PartialEq for Node<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value && self.next == other.next
}
}
pub struct List<T> {
head: Option<Rc<Node<T>>>,
}
impl <T: Eq + PartialEq> Eq for List<T> {}
impl <T> Clone for List<T> {
fn clone(&self) -> Self {
List {
head: self.head.clone()
}
}
}
impl <T: fmt::Debug> fmt::Debug for List<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[ ")?;
self.for_each(
|v| write!(f, "{:?} ", v).unwrap()
);
write!(f, "]")
}
}
impl <T: PartialEq> PartialEq for List<T> {
fn eq(&self, other: &Self) -> bool {
self.head == other.head
}
}
impl <T> Default for List<T> {
fn default() -> Self {
Self::nil()
}
}
impl <T> List<T> {
pub fn single(v: T) -> Self {
Self::cons(v, Self::nil())
}
pub const fn nil() -> Self {
Self {
head: None,
}
}
pub fn head(&self) -> Option<&T> {
match &self.head {
Some(v) => Some(&v.value),
None => None
}
}
pub fn tail(&self) -> Option<List<T>> {
match &self.head {
Some(v) => Some(List { head: v.next.clone() }),
None => None
}
}
pub fn tail_ref(&self) -> Option<List<&T>> {
self.ref_list().tail()
}
pub fn is_empty(&self) -> bool {
self.head.is_none()
}
pub fn len(&self) -> usize {
let mut len = 0;
self.for_each(|_| len += 1);
len
}
pub fn take(&self, n: usize) -> List<&T> {
self.iter().take(n).collect()
}
pub fn take_while(&self, mut f: impl FnMut(&T) -> bool) -> List<&T> {
self.iter().take_while(|x| f(*x)).collect()
}
pub fn cons(head: T, tail: Self) -> Self {
let head = Node {
value: head,
next: tail.head,
};
List {
head: Some(Rc::new(head)),
}
}
pub fn prepend(&self, value: T) -> Self {
Self::cons(value, (*self).clone())
}
pub fn for_each<'s>(&'s self, mut f: impl FnMut(&'s T)) {
for v in self.iter() {
f(v)
}
}
pub fn iter(&self) -> ListIter<T> {
ListIter {
node: &self.head,
}
}
pub fn ref_list(&self) -> List<&T> {
let mut list = List::nil();
self.for_each(|x| list = list.prepend(x));
list.reversed()
}
pub fn fold<'s, R>(&'s self, initial: R, f: impl FnMut(R, &'s T) -> R) -> R {
self.iter().fold(initial, f)
}
pub fn reduce<'s>(&'s self, f: impl FnMut(Option<&'s T>, &'s T) -> Option<&'s T>) -> Option<&'s T>{
let initial = self.head.as_ref();
let initial = initial.map(|v| &v.value);
self.fold(initial, f)
}
pub fn rev(&self) -> List<&T> {
self.fold(
List::nil(),
|acc, x|
List::cons(x, acc)
)
}
pub fn append<'a>(&'a self, other: &'a Self) -> List<&'a T> {
let mut list = List::nil();
self.for_each(|x| list = list.prepend(x));
other.for_each(|x| list = list.prepend(x));
list.reversed()
}
pub fn map<R>(&self, f: impl Fn(&T) -> R) -> List<R> {
match &self.head {
None => List::nil(),
Some(head) => {
let tail = self.tail().unwrap();
let head = f(&head.value);
let tail = tail.map(f);
List::cons(head, tail)
}
}
}
pub fn zip<'a, U>(&'a self, other: &'a List<U>) -> List<(&'a T, &'a U)> {
let (a, b) = (self.iter(), other.iter());
a.zip(b).collect()
}
}
impl <T: Clone> List<T> {
pub fn reversed(&self) -> Self {
self.rev().cloned()
}
}
impl <'v, T: Clone> List<&'v T> {
pub fn cloned(self) -> List<T> {
let mut list = List::nil();
self.for_each(|v| list = list.prepend((**v).clone()));
list.fold(
List::nil(),
|acc, x|
List::cons(x.clone(), acc)
)
}
}
impl <T> List<List<T>> {
pub fn join(&self) -> List<&T> {
self.fold(
List::nil(),
|acc, x|
acc.append(&x.ref_list()).cloned()
)
}
}
pub type ListMap<K, V> = List<(K, V)>;
impl <K, V> ListMap<K, V>
where K: Eq
{
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Eq,
{
for (k, v) in self.iter() {
if k.borrow() == key {
return Some(v)
}
}
None
}
pub fn insert(&self, key: K, value: V) -> Self {
self.prepend((key, value))
}
}
pub struct ListIter<'list, T> {
node: &'list Option<Rc<Node<T>>>,
}
impl <'list, T> Iterator for ListIter<'list, T> {
type Item = &'list T;
fn next(&mut self) -> Option<Self::Item> {
match self.node {
None => None,
Some(head) => {
self.node = &head.next;
Some(&head.value)
}
}
}
}
impl <T: Clone> FromIterator<T> for List<T> {
fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
let mut iter = iter.into_iter();
let mut list = List::nil();
while let Some(v) = iter.next() {
list = list.prepend(v);
}
list.reversed()
}
}