@@ -12,6 +12,8 @@
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
15+{-# LANGUAGE DeriveDataTypeable #-}
15module PureScript.TypeChecker.Types (
17module PureScript.TypeChecker.Types (
16 TypeConstraint(..),
18 TypeConstraint(..),
17 TypeSolution(..),
19 TypeSolution(..),
@@ -20,7 +22,7 @@ module PureScript.TypeChecker.Types (
21import Data.List
23import Data.List
22import Data.Function
24import Data.Function
23−import Data.Data (Data(..))
25+import qualified Data.Data as D
24import Data.Generics (everywhere, everywhereM, everything, mkT, mkM, mkQ, extM, extQ)
26import Data.Generics (everywhere, everywhereM, everything, mkT, mkM, mkQ, extM, extQ)
26import PureScript.Values
28import PureScript.Values
@@ -44,7 +46,7 @@ import qualified Data.Map as M
45data TypeConstraint
47data TypeConstraint
46 = TypeConstraint Int Type
48 = TypeConstraint Int Type
47− | RowConstraint Int Row deriving Show
49+ | RowConstraint Int Row deriving (Show, D.Data, D.Typeable)
49newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Row) }
51newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Row) }
@@ -59,9 +61,10 @@ typeOf name val = do
59 (cs, n) <- typeConstraints (M.singleton name me) val
61 (cs, n) <- typeConstraints (M.singleton name me) val
60 return (TypeConstraint me (TUnknown n) : cs, n)
62 return (TypeConstraint me (TUnknown n) : cs, n)
61 _ -> typeConstraints M.empty val
63 _ -> typeConstraints M.empty val
64+ desugared <- replaceAllTypeSynonyms cs
62− solution <- solveTypeConstraints cs emptyTypeSolution
65+ solution <- solveTypeConstraints desugared emptyTypeSolution
63 let ty = fst (runTypeSolution solution) n
66 let ty = fst (runTypeSolution solution) n
64− allUnknownsBecameQuantified cs solution ty
67+ allUnknownsBecameQuantified desugared solution ty
65 return $ varIfUnknown ty
68 return $ varIfUnknown ty
67allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
70allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
@@ -81,21 +84,21 @@ allUnknownsBecameQuantified cs solution ty = do
81 unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
84 unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
82 guardWith "Unsolved row variable" $ null $ unsolvedRows \\ rowsMentioned
85 guardWith "Unsolved row variable" $ null $ unsolvedRows \\ rowsMentioned
84−findUnknownTypes :: (Data d) => d -> [Int]
87+findUnknownTypes :: (D.Data d) => d -> [Int]
85findUnknownTypes = everything (++) (mkQ [] f)
88findUnknownTypes = everything (++) (mkQ [] f)
87 f :: Type -> [Int]
90 f :: Type -> [Int]
88 f (TUnknown n) = [n]
91 f (TUnknown n) = [n]
91−findTypeVars :: (Data d) => d -> [String]
94+findTypeVars :: (D.Data d) => d -> [String]
92findTypeVars = everything (++) (mkQ [] f)
95findTypeVars = everything (++) (mkQ [] f)
94 f :: Type -> [String]
97 f :: Type -> [String]
95 f (TypeVar v) = [v]
98 f (TypeVar v) = [v]
98−findUnknownRows :: (Data d) => d -> [Int]
101+findUnknownRows :: (D.Data d) => d -> [Int]
99findUnknownRows = everything (++) (mkQ [] f)
102findUnknownRows = everything (++) (mkQ [] f)
101 f :: Row -> [Int]
104 f :: Row -> [Int]
@@ -154,13 +157,23 @@ replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip ext
154 Just u -> return $ RUnknown u
157 Just u -> return $ RUnknown u
155 g r = return r
158 g r = return r
160+replaceAllTypeSynonyms :: (D.Data d) => d -> Check d
161+replaceAllTypeSynonyms ty = do
163+ go (M.toList $ typeSynonyms env) ty
166+ go ((name, (args, repl)):rest) d = do
167+ d' <- either throwError return (substituteTypeSynonym name args repl d)
157−replaceType :: (Data d) => Int -> Type -> d -> d
170+replaceType :: (D.Data d) => Int -> Type -> d -> d
158replaceType n t = everywhere (mkT go)
171replaceType n t = everywhere (mkT go)
160 go (TUnknown m) | m == n = t
173 go (TUnknown m) | m == n = t
163−replaceRow :: (Data d) => Int -> Row -> d -> d
176+replaceRow :: (D.Data d) => Int -> Row -> d -> d
164replaceRow n r = everywhere (mkT go)
177replaceRow n r = everywhere (mkT go)
166 go (RUnknown m) | m == n = r
179 go (RUnknown m) | m == n = r
@@ -174,7 +187,7 @@ rowOccursCheck :: Int -> Row -> Check ()
174rowOccursCheck u (RUnknown _) = return ()
187rowOccursCheck u (RUnknown _) = return ()
175rowOccursCheck u r = when (occursCheck u r) $ throwError $ "Occurs check failed: " ++ show u ++ " = " ++ prettyPrintRow r
188rowOccursCheck u r = when (occursCheck u r) $ throwError $ "Occurs check failed: " ++ show u ++ " = " ++ prettyPrintRow r
177−occursCheck :: (Data d) => Int -> d -> Bool
190+occursCheck :: (D.Data d) => Int -> d -> Bool
178occursCheck u = everything (||) $ flip extQ g $ mkQ False f
191occursCheck u = everything (||) $ flip extQ g $ mkQ False f
180 f (TUnknown u') | u' == u = True
193 f (TUnknown u') | u' == u = True
@@ -276,19 +289,8 @@ typeConstraints m (IfThenElse cond th el) = do
276typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
289typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
277 kind <- kindOf poly
290 kind <- kindOf poly
278 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
291 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
279− desugared <- replaceAllTypeSynonyms ty
280 (cs, n1) <- typeConstraints m val
292 (cs, n1) <- typeConstraints m val
281− return (TypeConstraint n1 desugared : cs, n1)
293+ return (TypeConstraint n1 ty : cs, n1)
283−replaceAllTypeSynonyms :: Type -> Check Type
284−replaceAllTypeSynonyms ty = do
286− go (M.toList $ typeSynonyms env) ty
288− go [] ty = return ty
289− go ((name, (args, repl)):rest) ty = do
290− ty' <- either throwError return (substituteTypeSynonym name args repl ty)
293unaryOperatorConstraints :: UnaryOperator -> Int -> Int -> [TypeConstraint]
295unaryOperatorConstraints :: UnaryOperator -> Int -> Int -> [TypeConstraint]
294unaryOperatorConstraints Negate val result = [TypeConstraint val Number, TypeConstraint result Number]
296unaryOperatorConstraints Negate val result = [TypeConstraint val Number, TypeConstraint result Number]