Skip to content

Instantly share code, notes, and snippets.

Created October 18, 2015 21:08
Show Gist options
  • Save anonymous/2f565a199e8667569190 to your computer and use it in GitHub Desktop.
Save anonymous/2f565a199e8667569190 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
#![feature(optin_builtin_traits)]
use std::marker::PhantomData;
trait Lookup<K> {
type V;
fn get(&self) -> &Self::V;
}
struct Nil;
struct Cons<K, V, T> {
pd: PhantomData<K>,
value: V,
tail: T
}
impl<K, V, T> Cons<K, V, T> {
fn push<K2, V2>(self, value: V2) -> Cons<K2, V2, Self> {
Cons {
pd: PhantomData,
value: value,
tail: self
}
}
}
impl Nil {
fn push<K, V>(self, value: V) -> Cons<K, V, Self> {
Cons {
pd: PhantomData,
value: value,
tail: self
}
}
}
trait NotSame {}
impl NotSame for .. {}
impl<T> !NotSame for (T, T) {}
impl<K1, K2, V, T> Lookup<K1> for Cons<K2, V, T>
where T: Lookup<K1>, (K1, K2): NotSame
{
type V = <T as Lookup<K1>>::V;
fn get(&self) -> &Self::V { self.tail.get() }
}
impl<K, V, T> Lookup<K> for Cons<K, V, T> {
type V = V;
fn get(&self) -> &V { &self.value }
}
trait DoLookup {
fn lookup<K>(&self) -> &<Self as Lookup<K>>::V where Self: Lookup<K>;
}
impl<T> DoLookup for T {
fn lookup<K>(&self) -> &<Self as Lookup<K>>::V where Self: Lookup<K> {
<Self as Lookup<K>>::get(&self)
}
}
fn main() {
struct Key1; struct Key2; struct Key3;
let table = Nil.push::<Key1, _>(15).push::<Key2, _>(true);
let value = table.lookup::<Key1>();
println!("{:?}", value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment