Skip to content

Instantly share code, notes, and snippets.

@hgiesel
Created June 18, 2026 11:11
Show Gist options
  • Select an option

  • Save hgiesel/4beb0fd70fa079144077bc17abafb8ba to your computer and use it in GitHub Desktop.

Select an option

Save hgiesel/4beb0fd70fa079144077bc17abafb8ba to your computer and use it in GitHub Desktop.
Problem illustrating two-way linked type hierarchies
use std::collections::HashMap;
use std::hash::Hash;
use std::fmt::Debug;
trait Language {
type PartOfSpeech: PartOfSpeech;
type Slot: Slot;
}
trait PartOfSpeech {
type Language: Language;
type Slot: Slot;
fn inflect(&self, term: &Term<Self::Language>) -> HashMap<Self::Slot, String>
where Self::Slot: Hash;
}
trait Slot {
type Language: Language;
}
#[derive(Debug)]
struct English;
impl Language for English {
type PartOfSpeech = Noun;
type Slot = Singular;
}
#[derive(Debug)]
struct Noun;
impl PartOfSpeech for Noun {
type Language = English;
type Slot = Singular;
fn inflect(&self, term: &Term<Self::Language>) -> HashMap<Self::Slot, String> {
let mut map = HashMap::new();
map.insert(Singular, term.term.clone());
map
}
}
#[derive(PartialEq, Eq, Hash, Debug)]
struct Singular;
impl Slot for Singular {
type Language = English;
}
#[derive(Debug)]
struct Term<Lang: Language> {
term: String,
language: Lang,
}
#[derive(Debug)]
struct Lexeme<Part: PartOfSpeech> {
// term: Term<Part::Language>, #!!!!!
term: Term<Part::Language>,
part: Part,
}
trait HasLanguage {
type Language;
}
impl HasLanguage for Noun {
type Language = English;
}
fn process_infl<Lang: Language>(infl: &HashMap<Lang::Slot, String>, term: &Term<Lang>) {
println!("Hi");
}
fn process_part<Part: PartOfSpeech + Debug>(lexeme: &Lexeme<Part>)
where
Part::Language: Debug,
Part::Slot: Hash,
{
println!("hello! {lexeme:?}");
let infl = lexeme.part.inflect(&lexeme.term);
// CRASH! No way to make this compile
process_infl(&infl, &lexeme.term);
}
fn main() {
let l = Lexeme {
term: Term {
term: "abc".to_string(),
language: English,
},
part: Noun,
};
process_part(&l);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment