use std::collections::HashMap;
pub type TypeVarId = u32;
#[derive(Debug, Clone, PartialEq)]
pub enum Scalar {
Int,
Float,
Var(TypeVarId),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Type {
pub ins: Vec<Scalar>,
pub outs: Vec<Scalar>,
}
impl Type {
pub fn uniform(n_in: usize, n_out: usize, s: Scalar) -> Type {
Type {
ins: vec![s.clone(); n_in],
outs: vec![s; n_out],
}
}
pub fn arity_in(&self) -> usize {
self.ins.len()
}
pub fn arity_out(&self) -> usize {
self.outs.len()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Scheme {
pub lam_count: usize,
pub vars: Vec<TypeVarId>,
pub ty: Type,
}
#[derive(Debug, Clone, Default)]
pub struct Subst {
pub map: HashMap<TypeVarId, Scalar>,
}
impl Subst {
pub fn resolve_scalar(&self, s: &Scalar) -> Scalar {
match s {
Scalar::Var(v) => match self.map.get(v) {
Some(inner) => self.resolve_scalar(inner),
None => s.clone(),
},
_ => s.clone(),
}
}
pub fn apply(&self, t: &Type) -> Type {
Type {
ins: t.ins.iter().map(|s| self.resolve_scalar(s)).collect(),
outs: t.outs.iter().map(|s| self.resolve_scalar(s)).collect(),
}
}
}