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 {
32 match (self, other) {
33 (Type::Int, Type::Int) => true,
34 (Type::Float, Type::Float) => true,
35 (Type::Str, Type::Str) => true,
36 (Type::Bool, Type::Bool) => true,
37 (Type::Unit, Type::Unit) => true,
38 (Type::Var(a), Type::Var(b)) => a == b,
39 (Type::Invalid, _) | (_, Type::Invalid) => false,
40 (Type::Result(a1, b1), Type::Result(a2, b2)) => a1.compatible(a2) && b1.compatible(b2),
41 (Type::Option(a), Type::Option(b)) => a.compatible(b),
42 (Type::List(a), Type::List(b)) => a.compatible(b),
43 (Type::Tuple(a), Type::Tuple(b)) => {
44 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.compatible(y))
45 }
46 (Type::Map(k1, v1), Type::Map(k2, v2)) => k1.compatible(k2) && v1.compatible(v2),
47 (Type::Vector(a), Type::Vector(b)) => a.compatible(b),
48 (Type::Fn(p1, r1, e1), Type::Fn(p2, r2, e2)) => {
49 p1.len() == p2.len()
50 && p1.iter().zip(p2.iter()).all(|(a, b)| a.compatible(b))
51 && r1.compatible(r2)
52 && e1.iter().all(|actual| {
53 e2.iter()
54 .any(|expected| crate::effects::effect_satisfies(expected, actual))
55 })
56 }
57 (Type::Named(a), Type::Named(b)) => {
58 a == b || a.ends_with(&format!(".{}", b)) || b.ends_with(&format!(".{}", a))
59 }
60 _ => false,
61 }
62 }
63
64 pub fn display(&self) -> String {
65 match self {
66 Type::Int => "Int".to_string(),
67 Type::Float => "Float".to_string(),
68 Type::Str => "String".to_string(),
69 Type::Bool => "Bool".to_string(),
70 Type::Unit => "Unit".to_string(),
71 Type::Result(ok, err) => format!("Result<{}, {}>", ok.display(), err.display()),
72 Type::Option(inner) => format!("Option<{}>", inner.display()),
73 Type::List(inner) => format!("List<{}>", inner.display()),
74 Type::Tuple(items) => format!(
75 "({})",
76 items
77 .iter()
78 .map(Type::display)
79 .collect::<Vec<_>>()
80 .join(", ")
81 ),
82 Type::Map(key, value) => format!("Map<{}, {}>", key.display(), value.display()),
83 Type::Vector(inner) => format!("Vector<{}>", inner.display()),
84 Type::Fn(params, ret, effects) => {
85 let ps: Vec<String> = params.iter().map(|p| p.display()).collect();
86 if effects.is_empty() {
87 format!("Fn({}) -> {}", ps.join(", "), ret.display())
88 } else {
89 format!(
90 "Fn({}) -> {} ! [{}]",
91 ps.join(", "),
92 ret.display(),
93 effects.join(", ")
94 )
95 }
96 }
97 Type::Var(name) => name.clone(),
98 Type::Invalid => "Invalid".to_string(),
99 Type::Named(n) => n.clone(),
100 }
101 }
102}