@@ -12,6 +12,8 @@
1212--
1313-----------------------------------------------------------------------------
1414
15+{-# LANGUAGE DeriveDataTypeable #-}
16+
1517module PureScript.TypeChecker.Types (
1618 TypeConstraint(..),
1719 TypeSolution(..),
@@ -20,7 +22,7 @@ module PureScript.TypeChecker.Types (
2022
2123import Data.List
2224import Data.Function
23−import Data.Data (Data(..))
25+import qualified Data.Data as D
2426import Data.Generics (everywhere, everywhereM, everything, mkT, mkM, mkQ, extM, extQ)
2527
2628import PureScript.Values
@@ -44,7 +46,7 @@ import qualified Data.Map as M
4446
4547data TypeConstraint
4648 = TypeConstraint Int Type
47− | RowConstraint Int Row deriving Show
49+ | RowConstraint Int Row deriving (Show, D.Data, D.Typeable)
4850
4951newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Row) }
5052
@@ -59,9 +61,10 @@ typeOf name val = do
5961 (cs, n) <- typeConstraints (M.singleton name me) val
6062 return (TypeConstraint me (TUnknown n) : cs, n)
6163 _ -> typeConstraints M.empty val
62− solution <- solveTypeConstraints cs emptyTypeSolution
64+ desugared <- replaceAllTypeSynonyms cs
65+ solution <- solveTypeConstraints desugared emptyTypeSolution
6366 let ty = fst (runTypeSolution solution) n
64− allUnknownsBecameQuantified cs solution ty
67+ allUnknownsBecameQuantified desugared solution ty
6568 return $ varIfUnknown ty
6669
6770allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
@@ -81,21 +84,21 @@ allUnknownsBecameQuantified cs solution ty = do
8184 unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
8285 guardWith "Unsolved row variable" $ null $ unsolvedRows \\ rowsMentioned
8386
84−findUnknownTypes :: (Data d) => d -> [Int]
87+findUnknownTypes :: (D.Data d) => d -> [Int]
8588findUnknownTypes = everything (++) (mkQ [] f)
8689 where
8790 f :: Type -> [Int]
8891 f (TUnknown n) = [n]
8992 f _ = []
9093
91−findTypeVars :: (Data d) => d -> [String]
94+findTypeVars :: (D.Data d) => d -> [String]
9295findTypeVars = everything (++) (mkQ [] f)
9396 where
9497 f :: Type -> [String]
9598 f (TypeVar v) = [v]
9699 f _ = []
97100
98−findUnknownRows :: (Data d) => d -> [Int]
101+findUnknownRows :: (D.Data d) => d -> [Int]
99102findUnknownRows = everything (++) (mkQ [] f)
100103 where
101104 f :: Row -> [Int]
@@ -154,13 +157,23 @@ replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip ext
154157 Just u -> return $ RUnknown u
155158 g r = return r
156159
157−replaceType :: (Data d) => Int -> Type -> d -> d
160+replaceAllTypeSynonyms :: (D.Data d) => d -> Check d
161+replaceAllTypeSynonyms ty = do
162+ env <- getEnv
163+ go (M.toList $ typeSynonyms env) ty
164+ where
165+ go [] d = return d
166+ go ((name, (args, repl)):rest) d = do
167+ d' <- either throwError return (substituteTypeSynonym name args repl d)
168+ go rest d'
169+
170+replaceType :: (D.Data d) => Int -> Type -> d -> d
158171replaceType n t = everywhere (mkT go)
159172 where
160173 go (TUnknown m) | m == n = t
161174 go t = t
162175
163−replaceRow :: (Data d) => Int -> Row -> d -> d
176+replaceRow :: (D.Data d) => Int -> Row -> d -> d
164177replaceRow n r = everywhere (mkT go)
165178 where
166179 go (RUnknown m) | m == n = r
@@ -174,7 +187,7 @@ rowOccursCheck :: Int -> Row -> Check ()
174187rowOccursCheck u (RUnknown _) = return ()
175188rowOccursCheck u r = when (occursCheck u r) $ throwError $ "Occurs check failed: " ++ show u ++ " = " ++ prettyPrintRow r
176189
177−occursCheck :: (Data d) => Int -> d -> Bool
190+occursCheck :: (D.Data d) => Int -> d -> Bool
178191occursCheck u = everything (||) $ flip extQ g $ mkQ False f
179192 where
180193 f (TUnknown u') | u' == u = True
@@ -276,19 +289,8 @@ typeConstraints m (IfThenElse cond th el) = do
276289typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
277290 kind <- kindOf poly
278291 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
279− desugared <- replaceAllTypeSynonyms ty
280292 (cs, n1) <- typeConstraints m val
281− return (TypeConstraint n1 desugared : cs, n1)
282−
283−replaceAllTypeSynonyms :: Type -> Check Type
284−replaceAllTypeSynonyms ty = do
285− env <- getEnv
286− go (M.toList $ typeSynonyms env) ty
287− where
288− go [] ty = return ty
289− go ((name, (args, repl)):rest) ty = do
290− ty' <- either throwError return (substituteTypeSynonym name args repl ty)
291− go rest ty'
293+ return (TypeConstraint n1 ty : cs, n1)
292294
293295unaryOperatorConstraints :: UnaryOperator -> Int -> Int -> [TypeConstraint]
294296unaryOperatorConstraints Negate val result = [TypeConstraint val Number, TypeConstraint result Number]