11module TypeCandidate where
22
33import Types
4+ import TypeError
45import Obj
6+ import Util
7+
8+ --------------------------------------------------------------------------------
9+ -- Data types
510
611data TypeVarRestriction
712 = 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 {
2025 -- a list of all variables in the type head
2126 variables :: [Ty ],
2227 -- all members of the type
23- typemembers :: [XObj ],
28+ typemembers :: [( String , [ Ty ]) ],
2429 -- what sort of type variables are permitted.
2530 restriction :: TypeVarRestriction ,
2631 -- what interfaces should types satisfy
2732 interfaceConstraints :: [InterfaceConstraint ],
2833 candidateTypeEnv :: TypeEnv ,
2934 candidateEnv :: Env
3035}
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