1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
extern crate base;
use std::ops::Deref;
use base::types::*;
use base::ast::ASTType;
fn type_con<I, T>(s: I, args: Vec<T>) -> Type<I, T>
where I: Deref<Target = str>,
T: From<Type<I, T>>
{
assert!(s.len() != 0);
let is_var = s.chars().next().unwrap().is_lowercase();
match s.parse() {
Ok(b) => Type::Builtin(b),
Err(()) if is_var => {
Type::Generic(Generic {
kind: RcKind::new(Kind::Star),
id: s,
})
}
Err(()) => Type::Data(Type::id(s), args),
}
}
#[test]
fn show_function() {
let int: ASTType<&str> = Type::int();
let int_int = Type::function(vec![int.clone()], int.clone());
assert_eq!(format!("{}", int_int),
"Int -> Int");
assert_eq!(format!("{}", Type::function(vec![int_int.clone()], int.clone())),
"(Int -> Int) -> Int");
assert_eq!(format!("{}", Type::function(vec![int.clone()], int_int.clone())),
"Int -> Int -> Int");
}
#[test]
fn show_record() {
assert_eq!(format!("{}", Type::<&str, ASTType<&str>>::record(vec![], vec![])),
"{}");
let typ = Type::record(vec![],
vec![Field {
name: "x",
typ: Type::<&str, ASTType<&str>>::int(),
}]);
assert_eq!(format!("{}", typ), "{ x: Int }");
let data = |s, a| RcType::from(type_con(s, a));
let f = Type::function(vec![data("a", vec![])], Type::string());
let test = data("Test", vec![data("a", vec![])]);
let typ = Type::record(vec![Field {
name: "Test",
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
id: "a",
}],
f.clone(),
),
}],
vec![Field {
name: "x",
typ: Type::int(),
}]);
assert_eq!(format!("{}", typ), "{ Test a = a -> String, x: Int }");
let typ = Type::record(vec![Field {
name: "Test",
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
id: "a",
}],
f.clone(),
),
}],
vec![Field {
name: "x",
typ: Type::int(),
},
Field {
name: "test",
typ: test.clone(),
}]);
assert_eq!(format!("{}", typ),
"{ Test a = a -> String, x: Int, test: Test a }");
let typ = Type::record(vec![Field {
name: "Test",
typ: Alias::new(
"Test",
vec![Generic {
kind: Kind::star(),
id: "a",
}],
f.clone(),
),
}],
vec![]);
assert_eq!(format!("{}", typ), "{ Test a = a -> String }");
}
#[test]
fn variants() {
let typ: ASTType<&str> = Type::variants(vec![("A", Type::function(vec![Type::int()], Type::id("A"))),
("B", Type::id("A"))]);
assert_eq!(format!("{}", typ), "| A Int | B");
}
#[test]
fn show_kind() {
let two_args = Kind::function(Kind::star(), Kind::function(Kind::star(), Kind::star()));
assert_eq!(format!("{}", two_args), "* -> * -> *");
let function_arg = Kind::function(Kind::function(Kind::star(), Kind::star()), Kind::star());
assert_eq!(format!("{}", function_arg), "(* -> *) -> *");
}