Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heterogeneous Sets #3

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions lhlist/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,6 @@ pub use relation::{Bool, False, LabelEq, Member, ToBool, True};
mod lookup;
pub use lookup::LookupElemByLabel;

mod ordered_set;

pub mod iter;
103 changes: 103 additions & 0 deletions lhlist/src/ordered_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use crate::Label;
use crate::{Cons, False, LabeledValue, Member, Nil};

impl OrderedHSet for Nil {}

impl<H, T> OrderedHSet for Cons<LabeledValue<H>, T>
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
where
H: Label,
T: OrderedHSet + Member<H, Output = False>,
{}

pub trait OrderedHSet: Sized {
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
fn prepend<H>(self, h: LabeledValue<H>) -> Cons<LabeledValue<H>, Self>
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
where
H: Label,
Self: Member<H, Output = False>,
{
Cons {
head: h,
tail: self,
}
}
}

pub trait Union<Rhs: OrderedHSet> {
type Output: OrderedHSet;

fn union(self, rhs: Rhs) -> Self::Output
where
Self: OrderedHSet;
}

impl<Rhs> Union<Rhs> for Nil
where
Rhs: OrderedHSet
{
type Output = Rhs;

fn union(self, rhs: Rhs) -> Self::Output {
rhs
}
}

impl<H, T, Rhs> Union<Rhs> for Cons<LabeledValue<H>, T>
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
where
H: Label,
T: OrderedHSet + Union<Rhs>,
Rhs: OrderedHSet,
Cons<LabeledValue<H>, <T as Union<Rhs>>::Output>: OrderedHSet,
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
{
type Output = Cons<LabeledValue<H>, <T as Union<Rhs>>::Output>;
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved

fn union(self, rhs: Rhs) -> Self::Output {
Cons {
head: self.head,
tail: self.tail.union(rhs),
}
}
}

#[cfg(test)]
mod tests {
use crate::ordered_set::{OrderedHSet, Union};
use crate::*;

#[test]
fn create_ordered_set() {
#[label(type=String, crate=crate)]
struct ProductName;

#[label(type=u8, crate=crate)]
struct ProductId;

#[label(type=u8, crate=crate)]
struct ShelfId;

#[label(type=String, crate=crate)]
struct ShelfName;

#[label(type=String, crate=crate)]
struct StoreName;

#[label(type=f64, crate=crate)]
struct Price;

let nil = Nil {};
let name = LabeledValue::<ProductName>::new("Shampoo".to_string());
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
let product_id = LabeledValue::<ProductId>::new(10);
let shelf_id = LabeledValue::<ShelfId>::new(10);
let shelf_name = LabeledValue::<ShelfName>::new("Home".to_string());
let store_name = LabeledValue::<StoreName>::new("X".to_string());
let price = LabeledValue::<Price>::new(12.0);
let ordered_set = nil
LukeMathWalker marked this conversation as resolved.
Show resolved Hide resolved
.clone()
.prepend(name)
.prepend(product_id)
.prepend(shelf_id);
let singleton = nil.clone().prepend(shelf_name);
let another_set = nil.clone().prepend(store_name).prepend(price);

ordered_set.union(singleton).union(another_set);
}
}