@@ -12,7 +12,7 @@ import qualified Data.List as L
1212import Data.Maybe (isJust)
1313import Control.Monad.Writer
1414import qualified Data.Map as M
15−import Debug.Trace
15+--import Debug.Trace
1616
1717findDataConstructor :: DataConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, DataConstructorDef)
1818findDataConstructor dName tConsList = foldr tConsFolder Nothing tConsList
@@ -70,7 +70,6 @@ atomTypeForDataConstructor tConss dConsName atomArgTypes = do
7070 Just (tCons, dCons) -> do
7171 --validate that the type constructor arguments are fulfilled in the data constructor
7272 typeVars <- resolveDataConstructorTypeVars dCons atomArgTypes tConss
73− traceShowM typeVars
7473 pure (ConstructedAtomType (TCD.name tCons) typeVars)
7574
7675-- | Walks the data and type constructors to extract the type variable map.
@@ -161,9 +160,9 @@ findTypeConstructor name tConsList = foldr tConsFolder Nothing tConsList
161160 accum
162161
163162resolveAtomType :: AtomType -> AtomType -> Either RelationalError AtomType
164−resolveAtomType orig@(ConstructedAtomType _ resolvedTypeVarMap) (ConstructedAtomType _ unresolvedTypeVarMap) = do
165− _ <- resolveAtomTypesInTypeVarMap resolvedTypeVarMap unresolvedTypeVarMap
166− pure orig
163+resolveAtomType (ConstructedAtomType tConsName resolvedTypeVarMap) (ConstructedAtomType _ unresolvedTypeVarMap) = do
164+ tVarMap <- resolveAtomTypesInTypeVarMap resolvedTypeVarMap unresolvedTypeVarMap
165+ pure (ConstructedAtomType tConsName tVarMap)
167166resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresolvedType then
168167 Right typeFromRelation
169168 else
@@ -172,19 +171,29 @@ resolveAtomType typeFromRelation unresolvedType = if typeFromRelation == unresol
172171-- this could be optimized to reduce new tuple creation- if anyatomtype does not appear, just return the original typevarmap
173172resolveAtomTypesInTypeVarMap :: TypeVarMap -> TypeVarMap -> Either RelationalError TypeVarMap
174173resolveAtomTypesInTypeVarMap resolvedTypeMap unresolvedTypeMap = do
175− let lookup' key tMap = case M.lookup key tMap of
174+ {-
175+ let resKeySet = traceShowId $ M.keysSet resolvedTypeMap
176+ unresKeySet = traceShowId $ M.keysSet unresolvedTypeMap
177+ when (resKeySet /= unresKeySet) (Left $ TypeConstructorTypeVarsMismatch resKeySet unresKeySet)
178+
179+
180+ let lookupOrDef key tMap = case M.lookup key tMap of
176181 Nothing -> Left (TypeConstructorTypeVarMissing key)
177182 Just val -> Right val
178− let resolveTypePair unresKey AnyAtomType = do
179− resType <- lookup' unresKey resolvedTypeMap
180− pure (unresKey, resType)
181− resolveTypePair unresKey subType@(ConstructedAtomType _ _) = do --recurse
182− resType <- lookup' unresKey resolvedTypeMap
183− resAType <- resolveAtomType resType subType
184− pure (unresKey, resAType)
185− resolveTypePair unresKey unresV = pure (unresKey, unresV)
186− mapM_ (uncurry resolveTypePair) (M.toList unresolvedTypeMap)
187− pure resolvedTypeMap
183+ -}
184+ let resolveTypePair resKey resType = do
185+ -- if the key is missing in the unresolved type map, then fill it in with the value from the resolved map
186+ case M.lookup resKey unresolvedTypeMap of
187+ Just unresType -> case unresType of
188+ --do we need to recurse for RelationAtomType?
189+ subType@(ConstructedAtomType _ _) -> do
190+ resSubType <- resolveAtomType resType subType
191+ pure (resKey, resSubType)
192+ otherType -> pure (resKey, otherType)
193+ Nothing -> do
194+ pure (resKey, resType) --swipe the missing type var from the expected map
195+ tVarList <- mapM (uncurry resolveTypePair) (M.toList resolvedTypeMap)
196+ pure (M.fromList tVarList)
188197
189198-- | See notes at `resolveTypesInTuple`. The typeFromRelation must not include any wildcards.
190199resolveTypeInAtom :: AtomType -> Atom -> Either RelationalError Atom
@@ -197,6 +206,23 @@ resolveTypeInAtom _ atom = Right atom
197206-- 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.
198207resolveTypesInTuple :: Attributes -> RelationTuple -> Either RelationalError RelationTuple
199208resolveTypesInTuple resolvedAttrs (RelationTuple _ tupAtoms) = do
200− newAtoms <- mapM (\(atom, resolvedType) -> resolveTypeInAtom resolvedType atom) (zip (V.toList tupAtoms) (map atomType (V.toList resolvedAttrs)))
209+ newAtoms <- mapM (\(atom, resolvedType) -> resolveTypeInAtom resolvedType atom) (zip (V.toList tupAtoms) $ (map atomType (V.toList resolvedAttrs)))
201210 Right (RelationTuple resolvedAttrs (V.fromList newAtoms))
202−
211+
212+-- | Validate that the type is provided with complete type variables for type constructors.
213+validateAtomType :: AtomType -> TypeConstructorMapping -> Maybe RelationalError
214+validateAtomType typ@(ConstructedAtomType tConsName tVarMap) tConss = do
215+ (tConsDef, _) <- findTypeConstructor tConsName tConss
216+ case tConsDef of
217+ ADTypeConstructorDef _ tVarNames -> let expectedTyVarNames = S.fromList tVarNames
218+ actualTyVarNames = M.keysSet tVarMap
219+ diff = S.difference expectedTyVarNames actualTyVarNames in
220+ if not (S.null diff) then
221+ Just $ TypeConstructorTypeVarsMismatch expectedTyVarNames actualTyVarNames
222+ else
223+ Nothing
224+ _ -> Just (TypeConstructorAtomTypeMismatch tConsName typ)
225+validateAtomType _ _ = Nothing
226+
227+validateTuple :: RelationTuple -> TypeConstructorMapping -> Maybe RelationalError
228+validateTuple (RelationTuple _ atoms) tConss = mapM_ (\a -> validateAtomType (atomTypeForAtom a) tConss) atoms >>= pure Nothing