@@ -1,11 +1,9 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2module ProjectM36.AtomType where
2module ProjectM36.AtomType where
3import ProjectM36.Base
3import ProjectM36.Base
4−import ProjectM36.DataTypes.Primitive
5import qualified ProjectM36.TypeConstructorDef as TCD
4import qualified ProjectM36.TypeConstructorDef as TCD
6import qualified ProjectM36.TypeConstructor as TC
5import qualified ProjectM36.TypeConstructor as TC
7import qualified ProjectM36.DataConstructorDef as DCD
6import qualified ProjectM36.DataConstructorDef as DCD
8−import qualified Data.Text as T
9import ProjectM36.Error
7import ProjectM36.Error
10import ProjectM36.Attribute
8import ProjectM36.Attribute
11import qualified Data.Vector as V
9import qualified Data.Vector as V
@@ -79,11 +77,18 @@ atomTypeForDataConstructor tConss dConsName atomArgTypes = do
79resolveDataConstructorTypeVars :: DataConstructorDef -> [AtomType] -> TypeConstructorMapping -> Either RelationalError TypeVarMap
77resolveDataConstructorTypeVars :: DataConstructorDef -> [AtomType] -> TypeConstructorMapping -> Either RelationalError TypeVarMap
80resolveDataConstructorTypeVars dCons aTypeArgs tConss = do
78resolveDataConstructorTypeVars dCons aTypeArgs tConss = do
81 maps <- mapM (\(dCons',aTypeArg) -> resolveDataConstructorArgTypeVars dCons' aTypeArg tConss) (zip (DCD.fields dCons) aTypeArgs)
79 maps <- mapM (\(dCons',aTypeArg) -> resolveDataConstructorArgTypeVars dCons' aTypeArg tConss) (zip (DCD.fields dCons) aTypeArgs)
82− --if any two maps have the same key and different values- bail!
80+ --if any two maps have the same key and different values, this indicates a type arg mismatch
83− let typeVarMapFolder
81+ let typeVarMapFolder valMap acc = case acc of
83+ Right accMap -> if accMap `M.isSubmapOf` valMap then
84+ Right (M.union accMap valMap)
86+ Left (DataConstructorTypeVarsMismatch (DCD.name dCons) accMap valMap)
84− foldr typeVarMapFolder (Right M.empty) maps
87+ case foldr typeVarMapFolder (Right M.empty) maps of
89+ Right typeVarMaps -> pure typeVarMaps
85 --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 AnyAtomType which is resolved when the relation is constructed- the relation must contain all resolved atom types.
90 --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 AnyAtomType which is resolved when the relation is constructed- the relation must contain all resolved atom types.
86− pure (M.unions maps)
91+
88-- | Attempt to match the data constructor argument to a type constructor type variable.
93-- | Attempt to match the data constructor argument to a type constructor type variable.
89resolveDataConstructorArgTypeVars :: DataConstructorDefArg -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
94resolveDataConstructorArgTypeVars :: DataConstructorDefArg -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
@@ -92,13 +97,13 @@ resolveDataConstructorArgTypeVars (DataConstructorDefTypeConstructorArg tCons) a
92resolveDataConstructorArgTypeVars (DataConstructorDefTypeVarNameArg pVarName) aType _ = Right (M.singleton pVarName aType)
97resolveDataConstructorArgTypeVars (DataConstructorDefTypeVarNameArg pVarName) aType _ = Right (M.singleton pVarName aType)
94resolveTypeConstructorTypeVars :: TypeConstructor -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
99resolveTypeConstructorTypeVars :: TypeConstructor -> AtomType -> TypeConstructorMapping -> Either RelationalError TypeVarMap
95−resolveTypeConstructorTypeVars (PrimitiveTypeConstructor _ pType) aType tConss =
100+resolveTypeConstructorTypeVars (PrimitiveTypeConstructor _ pType) aType _ =
96 if aType /= pType then
101 if aType /= pType then
97 Left (AtomTypeMismatchError pType aType)
102 Left (AtomTypeMismatchError pType aType)
99 Right M.empty
104 Right M.empty
101−resolveTypeConstructorTypeVars (ADTypeConstructor tConsName tConsArgs) (ConstructedAtomType tConsName' pVarMap') tConss =
106+resolveTypeConstructorTypeVars (ADTypeConstructor tConsName _) (ConstructedAtomType tConsName' pVarMap') tConss =
102 if tConsName /= tConsName' then
107 if tConsName /= tConsName' then
103 Left (TypeConstructorNameMismatch tConsName tConsName')
108 Left (TypeConstructorNameMismatch tConsName tConsName')
@@ -156,7 +161,7 @@ findTypeConstructor name tConsList = foldr tConsFolder Nothing tConsList
158resolveAtomType :: AtomType -> AtomType -> Either RelationalError AtomType
163resolveAtomType :: AtomType -> AtomType -> Either RelationalError AtomType
159−resolveAtomType orig@(ConstructedAtomType dConsName resolvedTypeVarMap) (ConstructedAtomType _ unresolvedTypeVarMap) = do
164+resolveAtomType orig@(ConstructedAtomType _ resolvedTypeVarMap) (ConstructedAtomType _ unresolvedTypeVarMap) = do
160 _ <- resolveAtomTypesInTypeVarMap resolvedTypeVarMap unresolvedTypeVarMap
165 _ <- resolveAtomTypesInTypeVarMap resolvedTypeVarMap unresolvedTypeVarMap
161 pure orig
166 pure orig
162resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresolvedType then
167resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresolvedType then
@@ -167,14 +172,14 @@ resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresol
167-- this could be optimized to reduce new tuple creation- if anyatomtype does not appear, just return the original typevarmap
172-- this could be optimized to reduce new tuple creation- if anyatomtype does not appear, just return the original typevarmap
168resolveAtomTypesInTypeVarMap :: TypeVarMap -> TypeVarMap -> Either RelationalError TypeVarMap
173resolveAtomTypesInTypeVarMap :: TypeVarMap -> TypeVarMap -> Either RelationalError TypeVarMap
169resolveAtomTypesInTypeVarMap resolvedTypeMap unresolvedTypeMap = do
174resolveAtomTypesInTypeVarMap resolvedTypeMap unresolvedTypeMap = do
170− let lookup key tMap = case M.lookup key tMap of
175+ let lookup' key tMap = case M.lookup key tMap of
171 Nothing -> Left (TypeConstructorTypeVarMissing key)
176 Nothing -> Left (TypeConstructorTypeVarMissing key)
172 Just val -> Right val
177 Just val -> Right val
173 let resolveTypePair unresKey AnyAtomType = do
178 let resolveTypePair unresKey AnyAtomType = do
174− resType <- lookup unresKey resolvedTypeMap
179+ resType <- lookup' unresKey resolvedTypeMap
175 pure (unresKey, resType)
180 pure (unresKey, resType)
176 resolveTypePair unresKey subType@(ConstructedAtomType _ _) = do --recurse
181 resolveTypePair unresKey subType@(ConstructedAtomType _ _) = do --recurse
177− resType <- lookup unresKey resolvedTypeMap
182+ resType <- lookup' unresKey resolvedTypeMap
178 resAType <- resolveAtomType resType subType
183 resAType <- resolveAtomType resType subType
179 pure (unresKey, resAType)
184 pure (unresKey, resAType)
180 resolveTypePair unresKey unresV = pure (unresKey, unresV)
185 resolveTypePair unresKey unresV = pure (unresKey, unresV)