Solving Constraints [blog/lti-english/solve_code][edit]

pub fn Constraints::solve(self : Constraints, ty : Type) -> Map[Var, Type]? {
  let f = (vs : (Var, Subtype)) => {
    let { l, r } = vs.1
    let v = match ty.variance(vs.0) {
      Constant | Covariant => Some(l)
      Contravariant => Some(r)
      Invariant => if l == r { Some(l) } else { None }
    }
    v.map(v => (vs.0, v))
  }
  let constraints = self.items()
  let solved = constraints.iter().filter_map(f).to_array()
  guard solved.length() == constraints.length() else { None }
  Some(Map::from_array(solved))
}