@@ -11,7 +11,7 @@ import qualified Data.Vector as V
11import qualified Data.Set as S
11import qualified Data.Set as S
12import qualified Data.List as L
12import qualified Data.List as L
13import Data.Maybe (isJust)
13import Data.Maybe (isJust)
14−import Data.Either (rights)
14+import Data.Either (rights, lefts)
15import Control.Monad.Writer
15import Control.Monad.Writer
16import qualified Data.Map as M
16import qualified Data.Map as M
17import qualified Data.Text as T
17import qualified Data.Text as T
@@ -49,10 +49,6 @@ atomTypeForDataConstructorDefArg (DataConstructorDefTypeConstructorArg tCons) aT
50atomTypeForDataConstructorDefArg (DataConstructorDefTypeVarNameArg _) aType _ = Right aType --any type is OK
50atomTypeForDataConstructorDefArg (DataConstructorDefTypeVarNameArg _) aType _ = Right aType --any type is OK
52−isValidAtomTypeForTypeConstructorArg :: AtomType -> TypeConstructorArg -> TypeConstructorMapping -> Maybe RelationalError
53−isValidAtomTypeForTypeConstructorArg aType (TypeConstructorArg tCons) tConsList = isValidAtomTypeForTypeConstructor aType tCons tConsList
54−isValidAtomTypeForTypeConstructorArg _ (TypeConstructorTypeVarArg _) _ = Nothing
56--reconcile the atom-in types with the type constructors
52--reconcile the atom-in types with the type constructors
57isValidAtomTypeForTypeConstructor :: AtomType -> TypeConstructor -> TypeConstructorMapping -> Maybe RelationalError
53isValidAtomTypeForTypeConstructor :: AtomType -> TypeConstructor -> TypeConstructorMapping -> Maybe RelationalError
58isValidAtomTypeForTypeConstructor aType (PrimitiveTypeConstructor _ expectedAType) _ = if expectedAType /= aType then Just (AtomTypeMismatchError expectedAType aType) else Nothing
54isValidAtomTypeForTypeConstructor aType (PrimitiveTypeConstructor _ expectedAType) _ = if expectedAType /= aType then Just (AtomTypeMismatchError expectedAType aType) else Nothing
@@ -112,10 +108,11 @@ resolveTypeConstructorTypeVars (ADTypeConstructor tConsName _) (ConstructedAtomT
112 Nothing -> Left (NoSuchTypeConstructorName tConsName)
108 Nothing -> Left (NoSuchTypeConstructorName tConsName)
113 Just (tConsDef, _) -> let expectedPVarNames = S.fromList (TCD.typeVars tConsDef) in
109 Just (tConsDef, _) -> let expectedPVarNames = S.fromList (TCD.typeVars tConsDef) in
114 if M.keysSet pVarMap' `S.isSubsetOf` expectedPVarNames then
110 if M.keysSet pVarMap' `S.isSubsetOf` expectedPVarNames then
115− Right pVarMap' -- I wish we could actually resolve this- we are creating temporary AtomTypes which are actually invalid until they are resolved with a second pass of type resolution- not great
111+ Right pVarMap'
117 Left (TypeConstructorTypeVarsMismatch expectedPVarNames (M.keysSet pVarMap'))
113 Left (TypeConstructorTypeVarsMismatch expectedPVarNames (M.keysSet pVarMap'))
118−resolveTypeConstructorTypeVars _ _ _ = error "Unhandled type vars"
114+resolveTypeConstructorTypeVars (TypeVariable tvName) typ _ = Right (M.singleton tvName typ)
115+resolveTypeConstructorTypeVars x y _ = error $ "Unhandled type vars:" ++ show x ++ show y
120-- check that type vars on the right also appear on the left
117-- check that type vars on the right also appear on the left
121-- check that the data constructor names are unique
118-- check that the data constructor names are unique
@@ -134,17 +131,14 @@ validateTypeConstructorDef tConsDef dConsList = execWriter $ do
134-- Either Int Text -> ConstructedAtomType "Either" {Int , Text}
131-- Either Int Text -> ConstructedAtomType "Either" {Int , Text}
135atomTypeForTypeConstructor :: TypeConstructor -> TypeConstructorMapping -> Either RelationalError AtomType
132atomTypeForTypeConstructor :: TypeConstructor -> TypeConstructorMapping -> Either RelationalError AtomType
136atomTypeForTypeConstructor (PrimitiveTypeConstructor _ aType) _ = Right aType
133atomTypeForTypeConstructor (PrimitiveTypeConstructor _ aType) _ = Right aType
134+atomTypeForTypeConstructor (TypeVariable tvname) _ = Right (TypeVariableType tvname)
137atomTypeForTypeConstructor tCons tConss = case findTypeConstructor (TC.name tCons) tConss of
135atomTypeForTypeConstructor tCons tConss = case findTypeConstructor (TC.name tCons) tConss of
138 Nothing -> Left (NoSuchTypeConstructorError (TC.name tCons))
136 Nothing -> Left (NoSuchTypeConstructorError (TC.name tCons))
139 Just (tConsDef, _) -> do
137 Just (tConsDef, _) -> do
140− tConsArgTypes <- mapM ((flip atomTypeForTypeConstructorArg) tConss) (TC.arguments tCons)
138+ tConsArgTypes <- mapM ((flip atomTypeForTypeConstructor) tConss) (TC.arguments tCons)
141 let pVarNames = TCD.typeVars tConsDef
139 let pVarNames = TCD.typeVars tConsDef
142 tConsArgs = M.fromList (zip pVarNames tConsArgTypes)
140 tConsArgs = M.fromList (zip pVarNames tConsArgTypes)
143 Right (ConstructedAtomType (TC.name tCons) tConsArgs)
141 Right (ConstructedAtomType (TC.name tCons) tConsArgs)
145−atomTypeForTypeConstructorArg :: TypeConstructorArg -> TypeConstructorMapping -> Either RelationalError AtomType
146−atomTypeForTypeConstructorArg (TypeConstructorTypeVarArg _) _ = Left IncompletelyDefinedAtomTypeWithConstructorError
147−atomTypeForTypeConstructorArg (TypeConstructorArg tCons) tConsList = atomTypeForTypeConstructor tCons tConsList
149findTypeConstructor :: TypeConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, [DataConstructorDef])
143findTypeConstructor :: TypeConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, [DataConstructorDef])
150findTypeConstructor name tConsList = foldr tConsFolder Nothing tConsList
144findTypeConstructor name tConsList = foldr tConsFolder Nothing tConsList
@@ -225,8 +219,8 @@ validateTuple (RelationTuple _ atoms) tConss = mapM_ (\a -> validateAtomType (at
226-- | Determine if two types are equal or compatible (including special handling for TypeVar x).
220-- | Determine if two types are equal or compatible (including special handling for TypeVar x).
227atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
221atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
228−atomTypeVerify (TypeVar _) x = Right x
222+atomTypeVerify (TypeVariableType _) x = Right x
229−atomTypeVerify x (TypeVar _) = Right x
223+atomTypeVerify x (TypeVariableType _) = Right x
230atomTypeVerify x@(ConstructedAtomType tConsNameA tVarMapA) (ConstructedAtomType tConsNameB tVarMapB) =
224atomTypeVerify x@(ConstructedAtomType tConsNameA tVarMapA) (ConstructedAtomType tConsNameB tVarMapB) =
231 if tConsNameA /= tConsNameB then
225 if tConsNameA /= tConsNameB then
232 Left (TypeConstructorNameMismatch tConsNameA tConsNameB)
226 Left (TypeConstructorNameMismatch tConsNameA tConsNameB)
@@ -257,19 +251,30 @@ prettyAtomType (ConstructedAtomType tConsName typeVarMap) = tConsName `T.append`
258 showTypeVars (tyVarName, aType) = " (" `T.append` tyVarName `T.append` "::" `T.append` prettyAtomType aType `T.append` ")"
252 showTypeVars (tyVarName, aType) = " (" `T.append` tyVarName `T.append` "::" `T.append` prettyAtomType aType `T.append` ")"
259-- 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?)
253-- 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?)
260−prettyAtomType (TypeVar x) = "?TypeVar " <> x <> "?"
254+prettyAtomType (TypeVariableType x) = "?TypeVariableType " <> x <> "?"
261prettyAtomType aType = T.take (T.length fullName - T.length "AtomType") fullName
255prettyAtomType aType = T.take (T.length fullName - T.length "AtomType") fullName
262 where fullName = (T.pack . show) aType
256 where fullName = (T.pack . show) aType
264prettyAttribute :: Attribute -> T.Text
258prettyAttribute :: Attribute -> T.Text
265prettyAttribute attr = A.attributeName attr `T.append` "::" `T.append` prettyAtomType (A.atomType attr)
259prettyAttribute attr = A.attributeName attr `T.append` "::" `T.append` prettyAtomType (A.atomType attr)
267−resolveTypeVariables :: [AtomType] -> [AtomType] -> TypeVarMap
261+resolveTypeVariables :: [AtomType] -> [AtomType] -> Either RelationalError TypeVarMap
262+resolveTypeVariables expectedArgTypes actualArgTypes = do
268−resolveTypeVariables expectedArgTypes actualArgTypes = let tvmaps = map (uncurry resolveTypeVariable) (zip expectedArgTypes actualArgTypes) in
263+ let tvmaps = map (uncurry resolveTypeVariable) (zip expectedArgTypes actualArgTypes)
264+ --if there are any new keys which don't have equal values then we have a conflict!
265+ foldM (\acc tvmap -> do
266+ let inter = M.intersectionWithKey (\tvName vala valb ->
267+ if vala /= valb then
268+ Left (AtomFunctionTypeVariableMismatch tvName vala valb)
270+ Right vala) acc tvmap
271+ errs = lefts (M.elems inter)
269− M.unions tvmaps
273+ [] -> pure (M.unions tvmaps)
274+ errs' -> Left (someErrors errs')) M.empty tvmaps
271resolveTypeVariable :: AtomType -> AtomType -> TypeVarMap
276resolveTypeVariable :: AtomType -> AtomType -> TypeVarMap
272−resolveTypeVariable (TypeVar tv) typ = M.singleton tv typ
277+resolveTypeVariable (TypeVariableType tv) typ = M.singleton tv typ
273resolveTypeVariable (ConstructedAtomType _ _) (ConstructedAtomType _ actualTvMap) = actualTvMap
278resolveTypeVariable (ConstructedAtomType _ _) (ConstructedAtomType _ actualTvMap) = actualTvMap
274resolveTypeVariable _ _ = M.empty
279resolveTypeVariable _ _ = M.empty
@@ -280,7 +285,7 @@ resolveFunctionReturnValue funcName tvMap (ConstructedAtomType tCons retMap) = d
280 pure (ConstructedAtomType tCons (M.intersection tvMap retMap))
285 pure (ConstructedAtomType tCons (M.intersection tvMap retMap))
282 Left (AtomFunctionTypeVariableResolutionError funcName (fst (head (M.toList diff))))
287 Left (AtomFunctionTypeVariableResolutionError funcName (fst (head (M.toList diff))))
283−resolveFunctionReturnValue funcName tvMap (TypeVar tvName) = case M.lookup tvName tvMap of
288+resolveFunctionReturnValue funcName tvMap (TypeVariableType tvName) = case M.lookup tvName tvMap of
284 Nothing -> Left (AtomFunctionTypeVariableResolutionError funcName tvName)
289 Nothing -> Left (AtomFunctionTypeVariableResolutionError funcName tvName)
285 Just typ -> pure typ
290 Just typ -> pure typ
286−resolveFunctionReturnValue _ _ typ = pure typ
291+resolveFunctionReturnValue _ _ typ = pure typ