1
1
module TypeCandidate where
2
2
3
3
import Types
4
+ import TypeError
4
5
import Obj
6
+ import Util
7
+
8
+ --------------------------------------------------------------------------------
9
+ -- Data types
5
10
6
11
data TypeVarRestriction
7
12
= AllowAnyTypeVariableNames -- Used when checking a type found in the code, e.g. (Foo a), any name is OK for 'a'
@@ -20,11 +25,59 @@ data TypeCandidate = TypeCandidate {
20
25
-- a list of all variables in the type head
21
26
variables :: [Ty ],
22
27
-- all members of the type
23
- typemembers :: [XObj ],
28
+ typemembers :: [( String , [ Ty ]) ],
24
29
-- what sort of type variables are permitted.
25
30
restriction :: TypeVarRestriction ,
26
31
-- what interfaces should types satisfy
27
32
interfaceConstraints :: [InterfaceConstraint ],
28
33
candidateTypeEnv :: TypeEnv ,
29
34
candidateEnv :: Env
30
35
}
36
+
37
+ --------------------------------------------------------------------------------
38
+ -- Constructors
39
+
40
+ -- | Constructs a type candidate from the members of a product type definition.
41
+ fromDeftype :: String -> [Ty ] -> TypeEnv -> Env -> [XObj ] -> Either TypeError TypeCandidate
42
+ fromDeftype name vars tenv env members =
43
+ let tMembers = mapM go (pairwise members)
44
+ candidate = TypeCandidate {
45
+ typename = name,
46
+ variables = vars,
47
+ typemembers = [] ,
48
+ interfaceConstraints = [] ,
49
+ restriction = AllowOnlyNamesInScope ,
50
+ candidateTypeEnv = tenv,
51
+ candidateEnv = env
52
+ }
53
+ in if even (length members)
54
+ then fmap (\ ms -> candidate {typemembers = ms}) tMembers
55
+ else Left (UnevenMembers members)
56
+ where go :: (XObj , XObj ) -> Either TypeError (String , [Ty ])
57
+ go ((XObj (Sym (SymPath [] fieldname) _) _ _), tyx) =
58
+ case xobjToTy tyx of
59
+ Just t -> Right (fieldname, [t])
60
+ Nothing -> Left (NotAType tyx)
61
+ go (x, _) = Left (InvalidProductField x)
62
+
63
+ -- | Constructs a type candidate from the members of a sum type definition.
64
+ fromSumtype :: String -> [Ty ] -> TypeEnv -> Env -> [XObj ] -> Either TypeError TypeCandidate
65
+ fromSumtype name vars tenv env members =
66
+ let tMembers = mapM go members
67
+ candidate = TypeCandidate {
68
+ typename = name,
69
+ variables = vars,
70
+ typemembers = [] ,
71
+ interfaceConstraints = [] ,
72
+ restriction = AllowOnlyNamesInScope ,
73
+ candidateTypeEnv = tenv,
74
+ candidateEnv = env
75
+ }
76
+ in fmap (\ ms -> candidate {typemembers = ms}) tMembers
77
+ where go :: XObj -> Either TypeError (String , [Ty ])
78
+ go x@ (XObj (Lst [XObj (Sym (SymPath [] pname) Symbol ) _ _, XObj (Arr tyXObjs) _ _]) _ _) =
79
+ case mapM xobjToTy tyXObjs of
80
+ Just ts -> Right (pname, ts)
81
+ Nothing -> Left (InvalidSumtypeCase x)
82
+ go (XObj (Sym (SymPath [] pname) Symbol ) _ _) = Right (pname, [] )
83
+ go x = Left (InvalidSumtypeCase x)
0 commit comments