git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Check all unknowns become quantified at the top level. Fix row unification bug./
commitdd540b4b241294f1c9a9fd218f2453ea09c408df authorPhil Freeman <paf31@cantab.net> dateWed 16 Oct 2013, 09:50 (13 years ago) parent1c2bd79
3 files changed+44−6
examples/ReadShow.ps+5 src/PureScript/TypeChecker/Types.hs+37−4 src/PureScript/Types.hs+2−2
examples/ReadShow.psnew file+5
@@ -0,0 +1,5 @@
1+extern read :: forall a. (String) -> a
2+
3+extern show :: forall a. (a) -> String
4+
5+test = \x -> show(read(x))
src/PureScript/TypeChecker/Types.hs+37−4
@@ -53,14 +53,47 @@ typeOf :: Ident -> Value -> Check PolyType
5353typeOf name val = do
5454 me <- fresh
5555 (cs, n) <- typeConstraints (M.singleton name me) val
56− solution <- solveTypeConstraints ((TypeConstraint me (TUnknown n)) : cs) emptyTypeSolution
57− return $ varIfUnknown $ fst (runTypeSolution solution) n
56+ let allConstraints = TypeConstraint me (TUnknown n) : cs
57+ solution <- solveTypeConstraints allConstraints emptyTypeSolution
58+ let ty = fst (runTypeSolution solution) n
59+ allUnknownsBecameQuantified allConstraints solution ty
60+ return $ varIfUnknown ty
61+
62+allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
63+allUnknownsBecameQuantified cs solution ty = do
64+ let
65+ typesMentioned = findUnknownTypes ty
66+ unknownTypes = nub $ flip concatMap cs $ \c -> case c of
67+ TypeConstraint u t -> u : findUnknownTypes t
68+ RowConstraint _ r -> findUnknownTypes r
69+ unsolvedTypes = filter (\n -> TUnknown n == fst (runTypeSolution solution) n) unknownTypes
70+ guardWith "Unsolved type variable" $ null $ unsolvedTypes \\ typesMentioned
71+ let
72+ rowsMentioned = findUnknownRows ty
73+ unknownRows = nub $ flip concatMap cs $ \c -> case c of
74+ TypeConstraint _ t -> findUnknownRows t
75+ RowConstraint u r -> u : findUnknownRows r
76+ unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
77+ guardWith ("Unsolved row variable" ++ show (unsolvedRows \\ rowsMentioned) ++ ", " ++ show cs) $ null $ unsolvedRows \\ rowsMentioned
78+
79+findUnknownTypes :: (Data d) => d -> [Int]
80+findUnknownTypes = everything (++) (mkQ [] f)
81+ where
82+ f :: Type -> [Int]
83+ f (TUnknown n) = [n]
84+ f _ = []
85+
86+findUnknownRows :: (Data d) => d -> [Int]
87+findUnknownRows = everything (++) (mkQ [] f)
88+ where
89+ f :: Row -> [Int]
90+ f (RUnknown n) = [n]
91+ f _ = []
5892
5993varIfUnknown :: Type -> PolyType
6094varIfUnknown ty =
6195 let
6296 (ty', m) = flip runState M.empty $ everywhereM (flip extM g $ mkM f) ty
63− -- TODO : check no nested unknowns
6497 in
6598 PolyType (sort $ nub $ M.elems m) ty'
6699 where
@@ -478,7 +511,7 @@ unifyRows r1 r2 =
478511 unifyRows' ((name, ty):row) r others (RUnknown u) = do
479512 u' <- fresh
480513 cs <- unifyRows' row r others (RUnknown u')
481− return [ RowConstraint u (RCons name ty (RUnknown u')) ]
514+ return (RowConstraint u (RCons name ty (RUnknown u')) : cs)
482515 unifyRows' [] REmpty [] REmpty = return []
483516 unifyRows' sd1 r1 sd2 r2 = throwError $ "Cannot unify " ++ show (fromList (sd1, r1)) ++ " with " ++ show (fromList (sd2, r2)) ++ "."
484517 toList :: Row -> ([(String, Type)], Row)
src/PureScript/Types.hs+2−2
@@ -28,7 +28,7 @@ data Type
2828 | Function [Type] Type
2929 | TypeVar String
3030 | TypeConstructor String
31− | TypeApp Type Type deriving (Show, Data, Typeable)
31+ | TypeApp Type Type deriving (Show, Eq, Data, Typeable)
3232
3333data PolyType = PolyType [String] Type deriving (Show, Data, Typeable)
3434
@@ -36,7 +36,7 @@ data Row
3636 = RUnknown Int
3737 | RowVar String
3838 | REmpty
39− | RCons String Type Row deriving (Show, Data, Typeable)
39+ | RCons String Type Row deriving (Show, Eq, Data, Typeable)
4040
4141monoType :: Type -> PolyType
4242monoType = PolyType []