Skip to content

Instantly share code, notes, and snippets.

@brendanzab
Created May 15, 2024 11:01
Show Gist options
  • Save brendanzab/12a8cd284c4ddef0e19b7fc9484a8ca5 to your computer and use it in GitHub Desktop.
Save brendanzab/12a8cd284c4ddef0e19b7fc9484a8ca5 to your computer and use it in GitHub Desktop.
ML-style module thing in Rust (please forgive me)
use std::hash::Hash;
pub trait Key {
type T: Hash + Eq;
}
pub trait Map<K : Key> {
type T<V>;
fn new<V>() -> Self::T<V>;
fn insert<V>(m: &mut Self::T<V>, k: <K as Key>::T, v: V);
fn get<'a, V>(m: &'a Self::T<V>, k: &<K as Key>::T) -> Option<&'a V>;
}
mod hash_map {
use std::collections::HashMap;
use super::*;
pub struct Make;
pub struct Wrapper<K, V>(HashMap<K, V>);
impl<K: Key> Map<K> for Make {
type T<V> = Wrapper<<K as Key>::T, V>;
fn new<V>() -> Self::T<V> {
Wrapper(HashMap::new())
}
fn insert<V>(m: &mut Self::T<V>, k: <K as Key>::T, v: V) {
m.0.insert(k, v);
}
fn get<'a, V>(m: &'a Self::T<V>, k: &<K as Key>::T) -> Option<&'a V> {
m.0.get(k)
}
}
}
fn main() {
pub struct K;
impl Key for K {
type T = &'static str;
}
let mut m = <hash_map::Make as Map<K>>::new();
<hash_map::Make as Map<K>>::insert(&mut m, "x", 3);
<hash_map::Make as Map<K>>::insert(&mut m, "y", 42);
assert_eq!(<hash_map::Make as Map<K>>::get(&mut m, &"x"), Some(&3));
assert_eq!(<hash_map::Make as Map<K>>::get(&mut m, &"y"), Some(&42));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment