1
1
from collections import namedtuple , defaultdict
2
2
3
3
class Type (object ): pass
4
- class AtomicType (Type , namedtuple ('AtomicType' , ['name' ])): pass
5
- class TypeVariable (Type , namedtuple ('TypeVariable' , ['name' ])): pass
4
+
5
+ class AtomicType (Type ):
6
+ def __init__ (self , name ):
7
+ self .name = name
8
+
9
+ def substitute (self , substitution ):
10
+ return self
11
+
12
+ def __str__ (self ):
13
+ return self .name
14
+
15
+ class TypeVariable (Type ):
16
+ def __init__ (self , name ):
17
+ self .name = name
18
+
19
+ def substitute (self , substitution ):
20
+ if self .name in substitution :
21
+ return substitution [self .name ]
22
+ else :
23
+ return self
24
+
25
+ def __str__ (self ):
26
+ return '?%s' % self .name
6
27
7
28
class FunctionType (Type ):
8
29
def __init__ (self , arg_types , return_type , vararg_type = None , kwonly_arg_types = None , kwarg_type = None ):
@@ -12,6 +33,13 @@ def __init__(self, arg_types, return_type, vararg_type=None, kwonly_arg_types=No
12
33
self .kwarg_type = kwarg_type
13
34
self .kwonly_arg_types = kwonly_arg_types
14
35
36
+ def substitute (self , substitution ):
37
+ return FunctionType (arg_types = [ty .substitute (substitution ) for ty in self .arg_types ],
38
+ return_type = self .return_type .substitute (substitution ),
39
+ vararg_type = None if self .vararg_type is None else self .vararg_type .substitute (substitution ),
40
+ kwonly_arg_types = None if self .kwonly_arg_types is None else [ty .substitute (substitution ) for ty in self .kwonly_arg_types ],
41
+ kwarg_type = None if self .kwarg_type is None else self .kwarg_type .substitute (substitution ))
42
+
15
43
def __str__ (self ):
16
44
comma_separated_bits = [unicode (v ) for v in self .arg_types ]
17
45
@@ -31,15 +59,17 @@ def __init__(self, fn, args):
31
59
self .fn = fn
32
60
self .args = args
33
61
62
+ def substitute (self , substitution ):
63
+ return TypeApplication (self .fn .substitute (substitution ), [ty .substitute (substitution ) for ty in self .args ])
64
+
34
65
class UnionType (Type ):
35
66
def __init__ (self , types ):
36
67
self .types = types
37
68
38
-
39
69
used_vars = defaultdict (lambda : 0 )
40
70
def fresh (prefix = None ):
41
71
global used_vars
42
- prefix = prefix or '? X'
72
+ prefix = prefix or 'X'
43
73
used_vars [prefix ] = used_vars [prefix ] + 1
44
- return prefix + str (used_vars [prefix ])
74
+ return TypeVariable ( prefix + str (used_vars [prefix ]) )
45
75
0 commit comments