1#[derive(Debug, Clone, PartialEq)]
9pub enum Type {
10 Int,
11 Float,
12 Str,
13 Bool,
14 Unit,
15 Result(Box<Type>, Box<Type>),
16 Option(Box<Type>),
17 List(Box<Type>),
18 Tuple(Vec<Type>),
19 Map(Box<Type>, Box<Type>),
20 Vector(Box<Type>),
21 Fn(Vec<Type>, Box<Type>, Vec<String>),
22 Var(String), Invalid, Named(String), }
26
27impl Type {
28 pub fn compatible(&self, other: &Type) -> bool {
38 match (self, other) {
39 (Type::Invalid, _) | (_, Type::Invalid) => true,
40 (Type::Int, Type::Int) => true,
41 (Type::Float, Type::Float) => true,
42 (Type::Str, Type::Str) => true,
43 (Type::Bool, Type::Bool) => true,
44 (Type::Unit, Type::Unit) => true,
45 (Type::Var(a), Type::Var(b)) => a == b,
46 (Type::Result(a1, b1), Type::Result(a2, b2)) => a1.compatible(a2) && b1.compatible(b2),
47 (Type::Option(a), Type::Option(b)) => a.compatible(b),
48 (Type::List(a), Type::List(b)) => a.compatible(b),
49 (Type::Tuple(a), Type::Tuple(b)) => {
50 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.compatible(y))
51 }
52 (Type::Map(k1, v1), Type::Map(k2, v2)) => k1.compatible(k2) && v1.compatible(v2),
53 (Type::Vector(a), Type::Vector(b)) => a.compatible(b),
54 (Type::Fn(p1, r1, e1), Type::Fn(p2, r2, e2)) => {
55 p1.len() == p2.len()
56 && p1.iter().zip(p2.iter()).all(|(a, b)| a.compatible(b))
57 && r1.compatible(r2)
58 && e1.iter().all(|actual| {
59 e2.iter()
60 .any(|expected| crate::effects::effect_satisfies(expected, actual))
61 })
62 }
63 (Type::Named(a), Type::Named(b)) => {
64 a == b || a.ends_with(&format!(".{}", b)) || b.ends_with(&format!(".{}", a))
65 }
66 _ => false,
67 }
68 }
69
70 pub fn display(&self) -> String {
71 match self {
72 Type::Int => "Int".to_string(),
73 Type::Float => "Float".to_string(),
74 Type::Str => "String".to_string(),
75 Type::Bool => "Bool".to_string(),
76 Type::Unit => "Unit".to_string(),
77 Type::Result(ok, err) => format!("Result<{}, {}>", ok.display(), err.display()),
78 Type::Option(inner) => format!("Option<{}>", inner.display()),
79 Type::List(inner) => format!("List<{}>", inner.display()),
80 Type::Tuple(items) => format!(
81 "Tuple<{}>",
82 items
83 .iter()
84 .map(Type::display)
85 .collect::<Vec<_>>()
86 .join(", ")
87 ),
88 Type::Map(key, value) => format!("Map<{}, {}>", key.display(), value.display()),
89 Type::Vector(inner) => format!("Vector<{}>", inner.display()),
90 Type::Fn(params, ret, effects) => {
91 let ps: Vec<String> = params.iter().map(|p| p.display()).collect();
92 if effects.is_empty() {
93 format!("Fn({}) -> {}", ps.join(", "), ret.display())
94 } else {
95 format!(
96 "Fn({}) -> {} ! [{}]",
97 ps.join(", "),
98 ret.display(),
99 effects.join(", ")
100 )
101 }
102 }
103 Type::Var(name) => name.clone(),
104 Type::Invalid => "Invalid".to_string(),
105 Type::Named(n) => n.clone(),
106 }
107 }
108}