on 52182bc help sign in
384 lines 24 kB history raw
1module ProjectM36.AtomType where
2import ProjectM36.Base
3import qualified ProjectM36.TypeConstructorDef as TCD
4import qualified ProjectM36.TypeConstructor as TC
5import qualified ProjectM36.DataConstructorDef as DCD
6import ProjectM36.MiscUtils
7import ProjectM36.Error
8import ProjectM36.DataTypes.Primitive
9import ProjectM36.AttributeExpr as AE
10import qualified ProjectM36.Attribute as A
11import qualified Data.Vector as V
12import qualified Data.Set as S
13import qualified Data.List as L
14import Data.Maybe (isJust)
15import Data.Either (rights, lefts)
16import Control.Monad.Writer
17import qualified Data.Map as M
18import qualified Data.Text as T
20findDataConstructor :: DataConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, DataConstructorDef)
21findDataConstructor dName = foldr tConsFolder Nothing
22 where
23 tConsFolder (tCons, dConsList) accum = if isJust accum then
24 accum
25 else
26 case findDCons dConsList of
27 Just dCons -> Just (tCons, dCons)
28 Nothing -> Nothing
29 findDCons dConsList = case filter (\dCons -> DCD.name dCons == dName) dConsList of
30 [] -> Nothing
31 [dCons] -> Just dCons
32 _ -> error "More than one data constructor with the same name found"
34{-
35-- | Scan the atom types and return the resultant ConstructedAtomType or error.
36-- Used in typeFromAtomExpr to validate argument types.
37atomTypeForDataConstructorName :: DataConstructorName -> [AtomType] -> TypeConstructorMapping -> Either RelationalError AtomType
38-- search for the data constructor and resolve the types' names
39atomTypeForDataConstructorName dConsName atomTypesIn tConsList =
40 case findDataConstructor dConsName tConsList of
41 Nothing -> Left (NoSuchDataConstructorError dConsName)
42 Just (tCons, dCons) -> do
43 dConsVars <- resolveDataConstructorTypeVars dCons atomTypesIn tConsList
44 let tConsVars = M.fromList (map TypeVariableType (TCD.typeVars tCons))
45 allVars = M.union dConsVars tConsVars
46 ConstructedAtomType (TCD.name tCons) <$> allVars
47-}
49atomTypeForDataConstructorDefArg :: DataConstructorDefArg -> AtomType -> TypeConstructorMapping -> Either RelationalError AtomType
50atomTypeForDataConstructorDefArg (DataConstructorDefTypeConstructorArg tCons) aType tConss = do
51 isValidAtomTypeForTypeConstructor aType tCons tConss
52 pure aType
54atomTypeForDataConstructorDefArg (DataConstructorDefTypeVarNameArg _) aType _ = Right aType --any type is OK
56-- | Used to determine if the atom arguments can be used with the data constructor.
57-- | This is the entry point for type-checking from RelationalExpression.hs
58atomTypeForDataConstructor :: TypeConstructorMapping -> DataConstructorName -> [AtomType] -> Either RelationalError AtomType
59atomTypeForDataConstructor tConss dConsName atomArgTypes =
60 --lookup the data constructor
61 case findDataConstructor dConsName tConss of
62 Nothing -> Left (NoSuchDataConstructorError dConsName)
63 Just (tCons, dCons) -> do
64 --validate that the type constructor arguments are fulfilled in the data constructor
65 dConsVars <- resolveDataConstructorTypeVars dCons atomArgTypes tConss
66 let tConsVars = M.fromList (map (\v -> (v, TypeVariableType v)) (TCD.typeVars tCons))
67 allVars = M.union dConsVars tConsVars
68 unresolvedType = ConstructedAtomType (TCD.name tCons) allVars
69 --validateAtomType unresolvedType tConss -- do not validate here because the type may not be fully resolved at this point
70 pure unresolvedType
72-- | Walks the data and type constructors to extract the type variable map.
73resolveDataConstructorTypeVars :: DataConstructorDef -> [AtomType] -> TypeConstructorMapping -> Either RelationalError TypeVarMap
74resolveDataConstructorTypeVars dCons@(DataConstructorDef _ defArgs) aTypeArgs tConss = do
75 let defCount = length defArgs
76 argCount = length aTypeArgs
77 if defCount /= argCount then
78 Left (ConstructedAtomArgumentCountMismatchError defCount argCount)
79 else do
80 maps <- mapM (\(dCons',aTypeArg) -> resolveDataConstructorArgTypeVars dCons' aTypeArg tConss) (zip (DCD.fields dCons) aTypeArgs)
81 --if any two maps have the same key and different values, this indicates a type arg mismatch
82 let typeVarMapFolder valMap acc = case acc of
83 Left err -> Left err
84 Right accMap ->
85 case resolveAtomTypesInTypeVarMap valMap accMap of
86 Left (TypeConstructorTypeVarMissing _) -> Left (DataConstructorTypeVarsMismatch (DCD.name dCons) accMap valMap)
87 Left err -> Left err
88 Right ok -> pure ok
89 case foldr typeVarMapFolder (Right M.empty) maps of
90 Left err -> Left err
91 Right typeVarMaps -> pure typeVarMaps
92 --if the data constructor cannot complete a type constructor variables (ex. "Nothing" could be Maybe Int or Maybe Text, etc.), then fill that space with TypeVar which is resolved when the relation is constructed- the relation must contain all resolved atom types.
95-- | Attempt to match the data constructor argument to a type constructor type variable.
96resolveDataConstructorArgTypeVars :: DataConstructorDefArg -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
97resolveDataConstructorArgTypeVars (DataConstructorDefTypeConstructorArg tCons) aType tConss = resolveTypeConstructorTypeVars tCons aType tConss
99resolveDataConstructorArgTypeVars (DataConstructorDefTypeVarNameArg pVarName) aType _ = Right (M.singleton pVarName aType)
101resolveTypeConstructorTypeVars :: TypeConstructor -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
102resolveTypeConstructorTypeVars (PrimitiveTypeConstructor _ pType) aType _ =
103 if aType /= pType then
104 Left (AtomTypeMismatchError pType aType)
105 else
106 Right M.empty
108resolveTypeConstructorTypeVars (ADTypeConstructor tConsName _) (ConstructedAtomType tConsName' pVarMap') tConss =
109 if tConsName /= tConsName' then
110 Left (TypeConstructorNameMismatch tConsName tConsName')
111 else
112 case findTypeConstructor tConsName tConss of
113 Nothing -> Left (NoSuchTypeConstructorName tConsName)
114 Just (tConsDef, _) -> let expectedPVarNames = S.fromList (TCD.typeVars tConsDef) in
115 if M.keysSet pVarMap' `S.isSubsetOf` expectedPVarNames then
116 Right pVarMap'
117 else
118 Left (TypeConstructorTypeVarsMismatch expectedPVarNames (M.keysSet pVarMap'))
119resolveTypeConstructorTypeVars (TypeVariable tvName) typ _ = case typ of
120 TypeVariableType nam -> Left (TypeConstructorTypeVarMissing nam)
121 _ -> Right (M.singleton tvName typ)
122resolveTypeConstructorTypeVars (ADTypeConstructor tConsName []) typ tConss = case findTypeConstructor tConsName tConss of
123 Just (PrimitiveTypeConstructorDef _ _, _) -> Right M.empty
124 _ -> Left (TypeConstructorAtomTypeMismatch tConsName typ)
126resolveTypeConstructorTypeVars (ADTypeConstructor tConsName _) typ _ = Left (TypeConstructorAtomTypeMismatch tConsName typ)
128resolveTypeConstructorTypeVars (RelationAtomTypeConstructor attrExprs) typ tConsMap =
129 case typ of
130 RelationAtomType attrs ->
131 --resolve any typevars in the attrExprs
132 M.unions <$> mapM (\(expectedAtomType, attrExpr) -> resolveAttributeExprTypeVars attrExpr expectedAtomType tConsMap) (zip (A.atomTypesList attrs) attrExprs)
133 otherType -> Left (AtomTypeMismatchError typ otherType)
135--used when recursing down sub-relation type definition
136resolveAttributeExprTypeVars :: AttributeExprBase a -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
137resolveAttributeExprTypeVars (NakedAttributeExpr attr) aType _ = pure $ resolveTypeVariable (A.atomType attr) aType
138resolveAttributeExprTypeVars (AttributeAndTypeNameExpr _ tCons _) aType tConsMap = resolveTypeConstructorTypeVars tCons aType tConsMap
140-- check that type vars on the right also appear on the left
141-- check that the data constructor names are unique
142validateTypeConstructorDef :: TypeConstructorDef -> [DataConstructorDef] -> [RelationalError]
143validateTypeConstructorDef tConsDef dConsList = execWriter $ do
144 let duplicateDConsNames = dupes (L.sort (map DCD.name dConsList))
145 mapM_ tell [map DataConstructorNameInUseError duplicateDConsNames]
146 let leftSideVars = S.fromList (TCD.typeVars tConsDef)
147 rightSideVars = S.unions (map DCD.typeVars dConsList)
148 varsDiff = S.difference leftSideVars rightSideVars
149 mapM_ tell [map DataConstructorUsesUndeclaredTypeVariable (S.toList varsDiff)]
151atomTypeForTypeConstructor :: TypeConstructor -> TypeConstructorMapping -> TypeVarMap -> Either RelationalError AtomType
152atomTypeForTypeConstructor = atomTypeForTypeConstructorValidate False
154-- | Create an atom type iff all type variables are provided.
155-- Either Int Text -> ConstructedAtomType "Either" {Int , Text}
156atomTypeForTypeConstructorValidate :: Bool -> TypeConstructor -> TypeConstructorMapping -> TypeVarMap -> Either RelationalError AtomType
157atomTypeForTypeConstructorValidate _ (PrimitiveTypeConstructor _ aType) _ _ = Right aType
158atomTypeForTypeConstructorValidate validate (TypeVariable tvname) _ tvMap = case M.lookup tvname tvMap of
159 Nothing -> if validate then
160 Left (TypeConstructorTypeVarMissing tvname)
161 else
162 pure (TypeVariableType tvname)
163 Just typ -> Right typ
164atomTypeForTypeConstructorValidate _ (RelationAtomTypeConstructor attrExprs) tConsMap tvMap = do
165 resolvedAtomTypes <- mapM (\expr -> atomTypeForAttributeExpr expr tConsMap tvMap) attrExprs
166 let attrs = zipWith Attribute (map AE.attributeName attrExprs) resolvedAtomTypes
167 pure (RelationAtomType (A.attributesFromList attrs))
168atomTypeForTypeConstructorValidate val tCons tConss tvMap = case findTypeConstructor (TC.name tCons) tConss of
169 Nothing -> Left (NoSuchTypeConstructorError (TC.name tCons))
170 Just (PrimitiveTypeConstructorDef _ aType, _) -> Right aType
171 Just (tConsDef, _) -> do
172 tConsArgTypes <- mapM (\tConsArg -> atomTypeForTypeConstructorValidate val tConsArg tConss tvMap) (TC.arguments tCons)
173 let pVarNames = TCD.typeVars tConsDef
174 tConsArgs = M.fromList (zip pVarNames tConsArgTypes)
175 Right (ConstructedAtomType (TC.name tCons) tConsArgs)
178atomTypeForAttributeExpr :: AttributeExprBase a -> TypeConstructorMapping -> TypeVarMap -> Either RelationalError AtomType
179atomTypeForAttributeExpr (NakedAttributeExpr attr) _ _ = pure (A.atomType attr)
180atomTypeForAttributeExpr (AttributeAndTypeNameExpr _ tCons _) tConsMap tvMap = atomTypeForTypeConstructorValidate True tCons tConsMap tvMap
182--reconcile the atom-in types with the type constructors
183isValidAtomTypeForTypeConstructor :: AtomType -> TypeConstructor -> TypeConstructorMapping -> Either RelationalError ()
184isValidAtomTypeForTypeConstructor aType (PrimitiveTypeConstructor _ expectedAType) _ = if expectedAType /= aType then Left (AtomTypeMismatchError expectedAType aType) else pure ()
186--lookup constructor name and check if the incoming atom types are valid
187isValidAtomTypeForTypeConstructor (ConstructedAtomType tConsName _) (ADTypeConstructor expectedTConsName _) _ = if tConsName /= expectedTConsName then Left (TypeConstructorNameMismatch expectedTConsName tConsName) else pure ()
189isValidAtomTypeForTypeConstructor (RelationAtomType attrs) (RelationAtomTypeConstructor attrExprs) tConsMap = do
190 evaldAtomTypes <- mapM (\expr -> atomTypeForAttributeExpr expr tConsMap M.empty) attrExprs
191 mapM_ (uncurry resolveAtomType) (zip (map A.atomType (V.toList attrs)) evaldAtomTypes)
192isValidAtomTypeForTypeConstructor aType tCons _ = Left (AtomTypeTypeConstructorReconciliationError aType (TC.name tCons))
194findTypeConstructor :: TypeConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, [DataConstructorDef])
195findTypeConstructor name = foldr tConsFolder Nothing
196 where
197 tConsFolder (tCons, dConsList) accum = if TCD.name tCons == name then
198 Just (tCons, dConsList)
199 else
200 accum
202resolveAtomType :: AtomType -> AtomType -> Either RelationalError AtomType
203resolveAtomType (ConstructedAtomType tConsName resolvedTypeVarMap) (ConstructedAtomType _ unresolvedTypeVarMap) =
204 ConstructedAtomType tConsName <$> resolveAtomTypesInTypeVarMap resolvedTypeVarMap unresolvedTypeVarMap
205resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresolvedType then
206 Right typeFromRelation
207 else
208 Left (AtomTypeMismatchError typeFromRelation unresolvedType)
210{-
211--walk an `AtomType` and apply the type variables in the map
212resolveAtomTypeVars :: TypeVarMap -> AtomType -> AtomType
213resolveAtomTypeVars tvMap typ@(TypeVariableType nam) = fromMaybe typ (M.lookup nam tvMap)
214resolveAtomTypeVars tvMap (RelationAtomType relAttrs) =
215-}
216-- this could be optimized to reduce new tuple creation
217resolveAtomTypesInTypeVarMap :: TypeVarMap -> TypeVarMap -> Either RelationalError TypeVarMap
218resolveAtomTypesInTypeVarMap resolvedTypeMap unresolvedTypeMap = do
219 {-
220 let resKeySet = traceShowId $ M.keysSet resolvedTypeMap
221 unresKeySet = traceShowId $ M.keysSet unresolvedTypeMap
222 when (resKeySet /= unresKeySet) (Left $ TypeConstructorTypeVarsMismatch resKeySet unresKeySet)
225 let lookupOrDef key tMap = case M.lookup key tMap of
226 Nothing -> Left (TypeConstructorTypeVarMissing key)
227 Just val -> Right val
228 -}
229 let resolveTypePair resKey resType =
230 -- if the key is missing in the unresolved type map, then fill it in with the value from the resolved map
231 case M.lookup resKey unresolvedTypeMap of
232 Just unresType -> case unresType of
233 --do we need to recurse for RelationAtomType?
234 subType@(ConstructedAtomType _ _) -> do
235 resSubType <- resolveAtomType resType subType
236 pure (resKey, resSubType)
237 _ -> pure (resKey, resType)
238 Nothing ->
239 pure (resKey, resType) --swipe the missing type var from the expected map
240 tVarList <- mapM (uncurry resolveTypePair) (M.toList resolvedTypeMap)
241 pure (M.fromList tVarList)
243-- | See notes at `resolveTypesInTuple`. The typeFromRelation must not include any wildcards.
244resolveTypeInAtom :: AtomType -> Atom -> TypeConstructorMapping -> Either RelationalError Atom
245resolveTypeInAtom typeFromRelation@(ConstructedAtomType _ tvMap) atomIn@(ConstructedAtom dConsName _ args) tConss = do
246 newType <- resolveAtomType typeFromRelation (atomTypeForAtom atomIn)
247 case findDataConstructor dConsName tConss of
248 Nothing -> -- the atom may have been constructed using a constructor function without a public data constructor, no further resolution is possible
249 pure atomIn
250 Just (_, dConsDef) -> do
251 atomArgTypes <- resolvedAtomTypesForDataConstructorDefArgs tConss tvMap dConsDef
252 newArgs <- mapM (\(atom, atomTyp) -> resolveTypeInAtom atomTyp atom tConss) (zip args atomArgTypes)
253 pure (ConstructedAtom dConsName newType newArgs)
254resolveTypeInAtom (RelationAtomType attrs) (RelationAtom (Relation _ tupSet)) tConss = do
255 let newTups = mapM (resolveTypesInTuple attrs tConss) (asList tupSet)
256 RelationAtom . Relation attrs . RelationTupleSet <$> newTups
257resolveTypeInAtom _ atom _ = Right atom
259-- | When creating a tuple, the data constructor may not complete the type constructor arguments, so the wildcard "TypeVar x" fills in the type constructor's argument. The tuple type must be resolved before it can be part of a relation, however.
260-- Example: "Nothing" does not specify the the argument in "Maybe a", so allow delayed resolution in the tuple before it is added to the relation. Note that this resolution could cause a type error. Hardly a Hindley-Milner system.
261resolveTypesInTuple :: Attributes -> TypeConstructorMapping -> RelationTuple -> Either RelationalError RelationTuple
262resolveTypesInTuple resolvedAttrs tConss (RelationTuple _ tupAtoms) = do
263 newAtoms <- mapM (\(atom, resolvedType) -> resolveTypeInAtom resolvedType atom tConss) (zip (V.toList tupAtoms) $ map A.atomType (V.toList resolvedAttrs))
264 Right (RelationTuple resolvedAttrs (V.fromList newAtoms))
266-- | Validate that the type is provided with complete type variables for type constructors.
267validateAtomType :: AtomType -> TypeConstructorMapping -> Either RelationalError ()
268validateAtomType typ@(ConstructedAtomType tConsName tVarMap) tConss =
269 case findTypeConstructor tConsName tConss of
270 Nothing -> Left (TypeConstructorAtomTypeMismatch tConsName typ)
271 Just (tConsDef, _) -> case tConsDef of
272 ADTypeConstructorDef _ tVarNames -> let expectedTyVarNames = S.fromList tVarNames
273 actualTyVarNames = M.keysSet tVarMap
274 diff = S.difference expectedTyVarNames actualTyVarNames in
275 if not (S.null diff) then
276 Left $ TypeConstructorTypeVarsMismatch expectedTyVarNames actualTyVarNames
277 else
278 validateTypeVarMap tVarMap tConss
279 _ -> Right ()
280validateAtomType (RelationAtomType attrs) tConss =
281 mapM_ (\attr ->
282 validateAtomType (A.atomType attr) tConss) (V.toList attrs)
283validateAtomType (TypeVariableType x) _ = Left (TypeConstructorTypeVarMissing x)
284validateAtomType _ _ = pure ()
286--ensure that all type vars are fully resolved
287validateTypeVarMap :: TypeVarMap -> TypeConstructorMapping -> Either RelationalError ()
288validateTypeVarMap tvMap tConss = mapM_ (`validateAtomType` tConss) $ M.elems tvMap
290validateTuple :: RelationTuple -> TypeConstructorMapping -> Either RelationalError ()
291validateTuple (RelationTuple _ atoms) tConss = mapM_ (`validateAtom` tConss) atoms
293--ensure that all types are fully resolved
294validateAtom :: Atom -> TypeConstructorMapping -> Either RelationalError ()
295validateAtom (RelationAtom (Relation _ tupSet)) tConss = mapM_ (`validateTuple` tConss) (asList tupSet)
296validateAtom (ConstructedAtom _ dConsType atomArgs) tConss = do
297 validateAtomType dConsType tConss
298 mapM_ (`validateAtom` tConss) atomArgs
299validateAtom _ _ = pure ()
302-- | Determine if two types are equal or compatible (including special handling for TypeVar x).
303atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
304atomTypeVerify (TypeVariableType _) x = Right x
305atomTypeVerify x (TypeVariableType _) = Right x
306atomTypeVerify x@(ConstructedAtomType tConsNameA tVarMapA) (ConstructedAtomType tConsNameB tVarMapB)
307 | tConsNameA /= tConsNameB = Left (TypeConstructorNameMismatch tConsNameA tConsNameB)
308 | not (typeVarMapsVerify tVarMapA tVarMapB) = Left (TypeConstructorTypeVarsTypesMismatch tConsNameA tVarMapA tVarMapB)
309 | otherwise = Right x
311atomTypeVerify x@(RelationAtomType attrs1) y@(RelationAtomType attrs2) = do
312 mapM_ (\(attr1,attr2) -> let name1 = A.attributeName attr1
313 name2 = A.attributeName attr2 in
314 if notElem "_" [name1, name2] && name1 /= name2 then
315 Left $ AtomTypeMismatchError x y
316 else
317 atomTypeVerify (A.atomType attr1) (A.atomType attr2)) $ V.toList (V.zip attrs1 attrs2)
318 return x
319atomTypeVerify x y = if x == y then
320 Right x
321 else
322 Left $ AtomTypeMismatchError x y
324-- | Determine if two typeVars are logically compatible.
325typeVarMapsVerify :: TypeVarMap -> TypeVarMap -> Bool
326typeVarMapsVerify a b = M.keysSet a == M.keysSet b && (length . rights) (map (\((_,v1),(_,v2)) -> atomTypeVerify v1 v2) (zip (M.toAscList a) (M.toAscList b))) == M.size a
328prettyAtomType :: AtomType -> T.Text
329prettyAtomType (RelationAtomType attrs) = "relation {" `T.append` T.intercalate "," (map prettyAttribute (V.toList attrs)) `T.append` "}"
330prettyAtomType (ConstructedAtomType tConsName typeVarMap) = tConsName `T.append` T.concat (map showTypeVars (M.toList typeVarMap))
331 where
332 showTypeVars (_, TypeVariableType x) = " " <> x
333 showTypeVars (tyVarName, aType) = " (" `T.append` tyVarName `T.append` "::" `T.append` prettyAtomType aType `T.append` ")"
334-- it would be nice to have the original ordering, but we don't have access to the type constructor here- maybe the typevarmap should be also positional (ordered map?)
335prettyAtomType (TypeVariableType x) = x
336prettyAtomType aType = T.take (T.length fullName - T.length "AtomType") fullName
337 where fullName = (T.pack . show) aType
339prettyAttribute :: Attribute -> T.Text
340prettyAttribute (Attribute _ (TypeVariableType x)) = x
341prettyAttribute attr = A.attributeName attr `T.append` "::" `T.append` prettyAtomType (A.atomType attr)
343resolveTypeVariables :: [AtomType] -> [AtomType] -> Either RelationalError TypeVarMap
344resolveTypeVariables expectedArgTypes actualArgTypes = do
345 let tvmaps = zipWith resolveTypeVariable expectedArgTypes actualArgTypes
346 --if there are any new keys which don't have equal values then we have a conflict!
347 foldM (\acc tvmap -> do
348 let inter = M.intersectionWithKey (\tvName vala valb ->
349 if vala /= valb then
350 Left (AtomFunctionTypeVariableMismatch tvName vala valb)
351 else
352 Right vala) acc tvmap
353 errs = lefts (M.elems inter)
354 case errs of
355 [] -> pure (M.unions tvmaps)
356 errs' -> Left (someErrors errs')) M.empty tvmaps
358resolveTypeVariable :: AtomType -> AtomType -> TypeVarMap
359resolveTypeVariable (TypeVariableType tv) typ = M.singleton tv typ
360resolveTypeVariable (ConstructedAtomType _ _) (ConstructedAtomType _ actualTvMap) = actualTvMap
361resolveTypeVariable _ _ = M.empty
363resolveFunctionReturnValue :: AtomFunctionName -> TypeVarMap -> AtomType -> Either RelationalError AtomType
364resolveFunctionReturnValue funcName tvMap (ConstructedAtomType tCons retMap) = do
365 let diff = M.difference retMap tvMap
366 if M.null diff then
367 pure (ConstructedAtomType tCons (M.intersection tvMap retMap))
368 else
369 Left (AtomFunctionTypeVariableResolutionError funcName (fst (head (M.toList diff))))
370resolveFunctionReturnValue funcName tvMap (TypeVariableType tvName) = case M.lookup tvName tvMap of
371 Nothing -> Left (AtomFunctionTypeVariableResolutionError funcName tvName)
372 Just typ -> pure typ
373resolveFunctionReturnValue _ _ typ = pure typ
375-- convert a typevarmap and data constructor definition into a list of atomtypes which represent the arguments-- no type variables are allowed to remain
376resolvedAtomTypesForDataConstructorDefArgs :: TypeConstructorMapping -> TypeVarMap -> DataConstructorDef -> Either RelationalError [AtomType]
377resolvedAtomTypesForDataConstructorDefArgs tConsMap tvMap (DataConstructorDef _ args) = mapM (resolvedAtomTypeForDataConstructorDefArg tConsMap tvMap) args
379resolvedAtomTypeForDataConstructorDefArg :: TypeConstructorMapping -> TypeVarMap -> DataConstructorDefArg -> Either RelationalError AtomType
380resolvedAtomTypeForDataConstructorDefArg tConsMap tvMap (DataConstructorDefTypeConstructorArg typCons) = atomTypeForTypeConstructor typCons tConsMap tvMap
381resolvedAtomTypeForDataConstructorDefArg _ tvMap (DataConstructorDefTypeVarNameArg tvName) = case M.lookup tvName tvMap of
382 Nothing -> Left (DataConstructorUsesUndeclaredTypeVariable tvName)
383 Just typ -> Right typ