@@ -11,7 +11,7 @@ import qualified Data.Vector as V
1111import qualified Data.Set as S
1212import qualified Data.List as L
1313import Data.Maybe (isJust)
14−import Data.Either (rights)
14+import Data.Either (rights, lefts)
1515import Control.Monad.Writer
1616import qualified Data.Map as M
1717import qualified Data.Text as T
@@ -49,10 +49,6 @@ atomTypeForDataConstructorDefArg (DataConstructorDefTypeConstructorArg tCons) aT
4949
5050atomTypeForDataConstructorDefArg (DataConstructorDefTypeVarNameArg _) aType _ = Right aType --any type is OK
5151
52−isValidAtomTypeForTypeConstructorArg :: AtomType -> TypeConstructorArg -> TypeConstructorMapping -> Maybe RelationalError
53−isValidAtomTypeForTypeConstructorArg aType (TypeConstructorArg tCons) tConsList = isValidAtomTypeForTypeConstructor aType tCons tConsList
54−isValidAtomTypeForTypeConstructorArg _ (TypeConstructorTypeVarArg _) _ = Nothing
55−
5652--reconcile the atom-in types with the type constructors
5753isValidAtomTypeForTypeConstructor :: AtomType -> TypeConstructor -> TypeConstructorMapping -> Maybe RelationalError
5854isValidAtomTypeForTypeConstructor aType (PrimitiveTypeConstructor _ expectedAType) _ = if expectedAType /= aType then Just (AtomTypeMismatchError expectedAType aType) else Nothing
@@ -112,10 +108,11 @@ resolveTypeConstructorTypeVars (ADTypeConstructor tConsName _) (ConstructedAtomT
112108 Nothing -> Left (NoSuchTypeConstructorName tConsName)
113109 Just (tConsDef, _) -> let expectedPVarNames = S.fromList (TCD.typeVars tConsDef) in
114110 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'
116112 else
117113 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
119116
120117-- check that type vars on the right also appear on the left
121118-- check that the data constructor names are unique
@@ -134,17 +131,14 @@ validateTypeConstructorDef tConsDef dConsList = execWriter $ do
134131-- Either Int Text -> ConstructedAtomType "Either" {Int , Text}
135132atomTypeForTypeConstructor :: TypeConstructor -> TypeConstructorMapping -> Either RelationalError AtomType
136133atomTypeForTypeConstructor (PrimitiveTypeConstructor _ aType) _ = Right aType
134+atomTypeForTypeConstructor (TypeVariable tvname) _ = Right (TypeVariableType tvname)
137135atomTypeForTypeConstructor tCons tConss = case findTypeConstructor (TC.name tCons) tConss of
138136 Nothing -> Left (NoSuchTypeConstructorError (TC.name tCons))
139137 Just (tConsDef, _) -> do
140− tConsArgTypes <- mapM ((flip atomTypeForTypeConstructorArg) tConss) (TC.arguments tCons)
138+ tConsArgTypes <- mapM ((flip atomTypeForTypeConstructor) tConss) (TC.arguments tCons)
141139 let pVarNames = TCD.typeVars tConsDef
142140 tConsArgs = M.fromList (zip pVarNames tConsArgTypes)
143141 Right (ConstructedAtomType (TC.name tCons) tConsArgs)
144−
145−atomTypeForTypeConstructorArg :: TypeConstructorArg -> TypeConstructorMapping -> Either RelationalError AtomType
146−atomTypeForTypeConstructorArg (TypeConstructorTypeVarArg _) _ = Left IncompletelyDefinedAtomTypeWithConstructorError
147−atomTypeForTypeConstructorArg (TypeConstructorArg tCons) tConsList = atomTypeForTypeConstructor tCons tConsList
148142
149143findTypeConstructor :: TypeConstructorName -> TypeConstructorMapping -> Maybe (TypeConstructorDef, [DataConstructorDef])
150144findTypeConstructor name tConsList = foldr tConsFolder Nothing tConsList
@@ -225,8 +219,8 @@ validateTuple (RelationTuple _ atoms) tConss = mapM_ (\a -> validateAtomType (at
225219
226220-- | Determine if two types are equal or compatible (including special handling for TypeVar x).
227221atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
228−atomTypeVerify (TypeVar _) x = Right x
229−atomTypeVerify x (TypeVar _) = Right x
222+atomTypeVerify (TypeVariableType _) x = Right x
223+atomTypeVerify x (TypeVariableType _) = Right x
230224atomTypeVerify x@(ConstructedAtomType tConsNameA tVarMapA) (ConstructedAtomType tConsNameB tVarMapB) =
231225 if tConsNameA /= tConsNameB then
232226 Left (TypeConstructorNameMismatch tConsNameA tConsNameB)
@@ -257,19 +251,30 @@ prettyAtomType (ConstructedAtomType tConsName typeVarMap) = tConsName `T.append`
257251 where
258252 showTypeVars (tyVarName, aType) = " (" `T.append` tyVarName `T.append` "::" `T.append` prettyAtomType aType `T.append` ")"
259253-- 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 <> "?"
261255prettyAtomType aType = T.take (T.length fullName - T.length "AtomType") fullName
262256 where fullName = (T.pack . show) aType
263257
264258prettyAttribute :: Attribute -> T.Text
265259prettyAttribute attr = A.attributeName attr `T.append` "::" `T.append` prettyAtomType (A.atomType attr)
266260
267−resolveTypeVariables :: [AtomType] -> [AtomType] -> TypeVarMap
268−resolveTypeVariables expectedArgTypes actualArgTypes = let tvmaps = map (uncurry resolveTypeVariable) (zip expectedArgTypes actualArgTypes) in
269− M.unions tvmaps
261+resolveTypeVariables :: [AtomType] -> [AtomType] -> Either RelationalError TypeVarMap
262+resolveTypeVariables expectedArgTypes actualArgTypes = do
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)
269+ else
270+ Right vala) acc tvmap
271+ errs = lefts (M.elems inter)
272+ case errs of
273+ [] -> pure (M.unions tvmaps)
274+ errs' -> Left (someErrors errs')) M.empty tvmaps
270275
271276resolveTypeVariable :: AtomType -> AtomType -> TypeVarMap
272−resolveTypeVariable (TypeVar tv) typ = M.singleton tv typ
277+resolveTypeVariable (TypeVariableType tv) typ = M.singleton tv typ
273278resolveTypeVariable (ConstructedAtomType _ _) (ConstructedAtomType _ actualTvMap) = actualTvMap
274279resolveTypeVariable _ _ = M.empty
275280
@@ -280,7 +285,7 @@ resolveFunctionReturnValue funcName tvMap (ConstructedAtomType tCons retMap) = d
280285 pure (ConstructedAtomType tCons (M.intersection tvMap retMap))
281286 else
282287 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
284289 Nothing -> Left (AtomFunctionTypeVariableResolutionError funcName tvName)
285290 Just typ -> pure typ
286−resolveFunctionReturnValue _ _ typ = pure typ
291+resolveFunctionReturnValue _ _ typ = pure typ