use crate::r#type::{Type, Type::*, util::*}; impl Type { /// Performs substitution on the type. /// /// Replaces all free occurrences of generics /// named `name` with the given type `value` /// in the type. /// ```rust /// use melisp::r#type::{Type::*, util::*}; /// /// assert_eq!( /// List(vec![Integer, arr(Integer, VarType("A".to_string())), VarType("B".to_string())]) /// .subst("A", &Integer), /// List(vec![Integer, arr(Integer, Integer), VarType("B".to_string())]) /// ); /// /// assert_eq!( /// List(vec![Integer, arr(Integer, VarType("A".to_string())), VarType("B".to_string())]) /// .subst("B", &arr(Integer, Integer)), /// List(vec![Integer, arr(Integer, VarType("A".to_string())), arr(Integer, Integer)]) /// ); /// ``` pub fn subst(self, name: &str, value: &Type) -> Type { match self { Arrow(a, b) => arr((*a).subst(name, value), (*b).subst(name, value)), List(v) => List( v.into_iter() .map(|t| t.subst(name, value)) .collect() ), VarType(s) if s == name => value.clone(), VarType(s) => VarType(s), Integer => Integer, } } }