I have implemented a basic, but seemingly working, persistent (as in immutable), heterogenous list type in Rust.
Here's the code:
#[derive(Debug)]
pub enum ConsCell<'a> {
Char(char),
Number(u64),
String(&'a str),
}
pub struct PersistentList<'a, T: 'a> {
first: Option<&'a T>,
rest: Option<&'a PersistentList<'a, T>>,
count: u64,
}
impl<'a, T> PersistentList<'a, T> {
pub fn new() -> PersistentList<'a, T> {
PersistentList {
first: None,
rest: None,
count: 0,
}
}
pub fn first(&self) -> &T {
self.first.unwrap()
}
pub fn next(&self) -> Option<&PersistentList<T>> {
if self.count == 1 {
return None;
}
self.rest
}
pub fn cons(&'a self, x: &'a T) -> PersistentList<'a, T> {
PersistentList {
first: Some(x),
rest: Some(&self),
count: self.count + 1
}
}
pub fn count(&self) -> u64 {
self.count
}
}
This can be used like so:
fn main() {
let list = PersistentList::new();
let cell = &ConsCell::Number(42);
let list = list.cons(cell);
let cell = &ConsCell::String(&"foo");
let list = list.cons(cell);
match list.first() {
ConsCell::Char(c) => println!("{}", c),
ConsCell::Number(n) => println!("{}", n),
ConsCell::String(s) => println!("{}", s),
}
}
The ergonomics of this are not fantastic, however it does seem to work. Is there a more idiomatic way of doing something similar with Rust?
PersistentList
own any value? \$\endgroup\$PersistentList
s around, without being limited to the lifetime of their surroundings, right? Or rather: did you take inspiration from another programming language/implementation? \$\endgroup\$