@@ -14,7 +14,6 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
16{-# OPTIONS_GHC -fno-warn-orphans #-}
16{-# OPTIONS_GHC -fno-warn-orphans #-}
17−{-# LANGUAGE DeriveDataTypeable #-}
18{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE FlexibleContexts #-}
19{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE MultiParamTypeClasses #-}
@@ -60,7 +59,6 @@ import Language.PureScript.Pretty
61import Control.Monad.State
60import Control.Monad.State
62import Control.Monad.Error
61import Control.Monad.Error
63−import Control.Monad.Reader
64import Control.Monad.Unify
62import Control.Monad.Unify
66import Control.Applicative
64import Control.Applicative
@@ -82,7 +80,7 @@ instance Unifiable Check Type where
82-- Unify two types, updating the current substitution
80-- Unify two types, updating the current substitution
84unifyTypes :: Type -> Type -> UnifyT Type Check ()
82unifyTypes :: Type -> Type -> UnifyT Type Check ()
85−unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2 ++ ":\n" ++ e) $ do
83+unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 ++ " with type " ++ prettyPrintType t2 ++ ":\n" ++ e) $
86 unifyTypes' t1 t2
84 unifyTypes' t1 t2
88 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
86 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()
@@ -104,8 +102,8 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
104 sko <- newSkolemConstant
102 sko <- newSkolemConstant
105 let sk = skolemize ident sko sc ty1
103 let sk = skolemize ident sko sc ty1
106 sk `unifyTypes` ty2
104 sk `unifyTypes` ty2
107− unifyTypes' (ForAll _ _ _) _ = throwError "Skolem variable scope is unspecified"
105+ unifyTypes' ForAll{} _ = throwError "Skolem variable scope is unspecified"
108− unifyTypes' ty f@(ForAll _ _ _) = f `unifyTypes` ty
106+ unifyTypes' ty f@ForAll{} = f `unifyTypes` ty
109 unifyTypes' (Object row1) (Object row2) = row1 =?= row2
107 unifyTypes' (Object row1) (Object row2) = row1 =?= row2
110 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
108 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
111 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
109 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
@@ -116,8 +114,8 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
116 t3 `unifyTypes` t5
114 t3 `unifyTypes` t5
117 t4 `unifyTypes` t6
115 t4 `unifyTypes` t6
118 unifyTypes' (Skolem s1 _) (Skolem s2 _) | s1 == s2 = return ()
116 unifyTypes' (Skolem s1 _) (Skolem s2 _) | s1 == s2 = return ()
119− unifyTypes' r1@(RCons _ _ _) r2 = unifyRows r1 r2
117+ unifyTypes' r1@RCons{} r2 = unifyRows r1 r2
120− unifyTypes' r1 r2@(RCons _ _ _) = unifyRows r1 r2
118+ unifyTypes' r1 r2@RCons{} = unifyRows r1 r2
121 unifyTypes' r1@REmpty r2 = unifyRows r1 r2
119 unifyTypes' r1@REmpty r2 = unifyRows r1 r2
122 unifyTypes' r1 r2@REmpty = unifyRows r1 r2
120 unifyTypes' r1 r2@REmpty = unifyRows r1 r2
123 unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
121 unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
@@ -187,30 +185,30 @@ typesOf mainModuleName moduleName vals = do
187 -- If the declaration is a function, it has access to other values in the binding group.
185 -- If the declaration is a function, it has access to other values in the binding group.
188 -- If not, the generated code might fail at runtime since those values might be undefined.
186 -- If not, the generated code might fail at runtime since those values might be undefined.
189 let dict' = if isFunction val then dict else M.empty
187 let dict' = if isFunction val then dict else M.empty
190− triple@(_, (val, ty)) <- case e of
188+ triple@(_, (val', ty)) <- case e of
191 -- Typed declarations
189 -- Typed declarations
192− (ident, (val, Just (ty, checkType))) -> do
190+ (ident, (val', Just (ty, checkType))) -> do
193 -- Kind check
191 -- Kind check
194 kind <- liftCheck $ kindOf moduleName ty
192 kind <- liftCheck $ kindOf moduleName ty
195 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
193 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
196 -- Check the type with the new names in scope
194 -- Check the type with the new names in scope
197 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
195 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
198− val' <- bindNames dict' $ if checkType
196+ val'' <- bindNames dict' $ if checkType
199− then TypedValue True <$> check val ty' <*> pure ty'
197+ then TypedValue True <$> check val' ty' <*> pure ty'
200− else return (TypedValue False val ty')
198+ else return (TypedValue False val' ty')
201− return (ident, (val', ty'))
199+ return (ident, (val'', ty'))
202 -- Untyped declarations
200 -- Untyped declarations
203− (ident, (val, Nothing)) -> do
201+ (ident, (val', Nothing)) -> do
204 -- Infer the type with the new names in scope
202 -- Infer the type with the new names in scope
205− TypedValue _ val' ty <- bindNames dict' $ infer val
203+ TypedValue _ val'' ty <- bindNames dict' $ infer val'
206 ty =?= fromMaybe (error "name not found in dictionary") (lookup ident untypedDict)
204 ty =?= fromMaybe (error "name not found in dictionary") (lookup ident untypedDict)
207− return (ident, (TypedValue True val' ty, ty))
205+ return (ident, (TypedValue True val'' ty, ty))
208 -- If --main is enabled, need to check that `main` has type Eff eff a for some eff, a
206 -- If --main is enabled, need to check that `main` has type Eff eff a for some eff, a
209 when (Just moduleName == mainModuleName && fst e == Ident "main") $ do
207 when (Just moduleName == mainModuleName && fst e == Ident "main") $ do
210 [eff, a] <- replicateM 2 fresh
208 [eff, a] <- replicateM 2 fresh
211 ty =?= TypeApp (TypeApp (TypeConstructor (Qualified (Just (ModuleName [ProperName "Control", ProperName "Monad", ProperName "Eff"])) (ProperName "Eff"))) eff) a
209 ty =?= TypeApp (TypeApp (TypeConstructor (Qualified (Just (ModuleName [ProperName "Control", ProperName "Monad", ProperName "Eff"])) (ProperName "Eff"))) eff) a
212 -- Make sure unification variables do not escape
210 -- Make sure unification variables do not escape
213− escapeCheck val ty
211+ escapeCheck val' ty
214 return triple
212 return triple
215 forM tys $ \(ident, (val, ty)) -> do
213 forM tys $ \(ident, (val, ty)) -> do
216 -- Replace type class dictionary placeholders with actual dictionaries
214 -- Replace type class dictionary placeholders with actual dictionaries
@@ -221,7 +219,7 @@ typesOf mainModuleName moduleName vals = do
221 -- top-level unification variables with named type variables.
219 -- top-level unification variables with named type variables.
222 let val'' = overTypes (desaturateAllTypeSynonyms . setifyAll) val'
220 let val'' = overTypes (desaturateAllTypeSynonyms . setifyAll) val'
223 ty' = varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty
221 ty' = varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty
224− return $ (ident, (val'', ty'))
222+ return (ident, (val'', ty'))
226 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
224 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
227 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
225 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
@@ -284,7 +282,7 @@ entails moduleName context goal@(className, tys) = do
284 solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, [Type])] -> [Maybe [Value]]
282 solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, [Type])] -> [Maybe [Value]]
285 solveSubgoals _ _ Nothing = return Nothing
283 solveSubgoals _ _ Nothing = return Nothing
286 solveSubgoals env subst (Just subgoals) = do
284 solveSubgoals env subst (Just subgoals) = do
287− dict <- mapM (go env) (map (id *** map (replaceAllTypeVars subst)) subgoals)
285+ dict <- mapM (go env . second (map (replaceAllTypeVars subst))) subgoals
288 return $ Just dict
286 return $ Just dict
289 -- Make a dictionary from subgoal dictionaries by applying the correct function
287 -- Make a dictionary from subgoal dictionaries by applying the correct function
290 mkDictionary :: Qualified Ident -> Maybe [Value] -> Value
288 mkDictionary :: Qualified Ident -> Maybe [Value] -> Value
@@ -320,7 +318,7 @@ typeHeadsAreEqual m e (TypeConstructor c1) (TypeConstructor c2) | typeConstructo
320typeHeadsAreEqual m e (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = (:) (v, arg) <$> typeHeadsAreEqual m e h1 h2
318typeHeadsAreEqual m e (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = (:) (v, arg) <$> typeHeadsAreEqual m e h1 h2
321typeHeadsAreEqual m e t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual m e t2 t1
319typeHeadsAreEqual m e t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual m e t2 t1
322typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e m name args of
320typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e m name args of
323− Left err -> Nothing
321+ Left _ -> Nothing
324 Right t1 -> typeHeadsAreEqual m e t1 t2
322 Right t1 -> typeHeadsAreEqual m e t1 t2
325typeHeadsAreEqual _ _ _ _ = Nothing
323typeHeadsAreEqual _ _ _ _ = Nothing
@@ -350,7 +348,7 @@ findAllTypes = everything (++) (mkQ [] go)
351skolemEscapeCheck :: Value -> Check ()
349skolemEscapeCheck :: Value -> Check ()
352skolemEscapeCheck (TypedValue False _ _) = return ()
350skolemEscapeCheck (TypedValue False _ _) = return ()
353−skolemEscapeCheck root@(TypedValue _ _ _) =
351+skolemEscapeCheck root@TypedValue{} =
354 -- Every skolem variable is created when a ForAll type is skolemized.
352 -- Every skolem variable is created when a ForAll type is skolemized.
355 -- This determines the scope of that skolem variable, which is copied from the SkolemScope
353 -- This determines the scope of that skolem variable, which is copied from the SkolemScope
356 -- field of the ForAll constructor.
354 -- field of the ForAll constructor.
@@ -374,10 +372,10 @@ skolemEscapeCheck root@(TypedValue _ _ _) =
374 collect _ = []
372 collect _ = []
375 go _ scos = ([], scos)
373 go _ scos = ([], scos)
376 findBindingScope :: SkolemScope -> Maybe Value
374 findBindingScope :: SkolemScope -> Maybe Value
377− findBindingScope sco = something (mkQ Nothing go) root
375+ findBindingScope sco = something (mkQ Nothing go') root
379− go val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = Just val
377+ go' val@(TypedValue _ _ (ForAll _ _ (Just sco'))) | sco == sco' = Just val
380− go _ = Nothing
378+ go' _ = Nothing
381skolemEscapeCheck val = throwError $ "Untyped value passed to skolemEscapeCheck: " ++ prettyPrintValue val
379skolemEscapeCheck val = throwError $ "Untyped value passed to skolemEscapeCheck: " ++ prettyPrintValue val
@@ -399,7 +397,7 @@ varIfUnknown :: Type -> Type
399varIfUnknown ty =
397varIfUnknown ty =
400 let unks = nub $ unknowns ty
398 let unks = nub $ unknowns ty
401 toName = (:) 't' . show
399 toName = (:) 't' . show
402− ty' = everywhere (mkT typeToVar) $ ty
400+ ty' = everywhere (mkT typeToVar) ty
403 typeToVar :: Type -> Type
401 typeToVar :: Type -> Type
404 typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)
402 typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)
405 typeToVar t = t
403 typeToVar t = t
@@ -430,7 +428,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
430replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
428replaceVarWithUnknown :: String -> Type -> UnifyT Type Check Type
431replaceVarWithUnknown ident ty = do
429replaceVarWithUnknown ident ty = do
432 tu <- fresh
430 tu <- fresh
433− return $ replaceTypeVars ident tu $ ty
431+ return $ replaceTypeVars ident tu ty
436-- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate
434-- Replace fully applied type synonyms with the @SaturatedTypeSynonym@ data constructor, which helps generate
@@ -603,11 +601,11 @@ inferBinder val (ConstructorBinder ctor binders) = do
603 (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contains constraints") ty
601 (_, fn) <- instantiatePolyTypeWithUnknowns (error "Data constructor types cannot contains constraints") ty
604 go binders fn
602 go binders fn
606− go [] ty = do
604+ go [] ty' = do
607− subsumes Nothing val ty
605+ subsumes Nothing val ty'
608 return M.empty
606 return M.empty
609− go (binder : binders) (TypeApp (TypeApp t obj) ret) | t == tyFunction =
607+ go (binder : binders') (TypeApp (TypeApp t obj) ret) | t == tyFunction =
610− M.union <$> inferBinder obj binder <*> go binders ret
608+ M.union <$> inferBinder obj binder <*> go binders' ret
611 go _ _ = throwError $ "Wrong number of arguments to constructor " ++ show ctor
609 go _ _ = throwError $ "Wrong number of arguments to constructor " ++ show ctor
612 _ -> throwError $ "Constructor " ++ show ctor ++ " is not defined"
610 _ -> throwError $ "Constructor " ++ show ctor ++ " is not defined"
613inferBinder val (ObjectBinder props) = do
611inferBinder val (ObjectBinder props) = do
@@ -713,7 +711,7 @@ check val ty = rethrow errorMessage $ check' val ty
713-- Check the type of a value
711-- Check the type of a value
715check' :: Value -> Type -> UnifyT Type Check Value
713check' :: Value -> Type -> UnifyT Type Check Value
716−check' val t@(ForAll ident ty _) = do
714+check' val (ForAll ident ty _) = do
717 scope <- newSkolemScope
715 scope <- newSkolemScope
718 sko <- newSkolemConstant
716 sko <- newSkolemConstant
719 let sk = skolemize ident sko scope ty
717 let sk = skolemize ident sko scope ty
@@ -722,15 +720,15 @@ check' val t@(ForAll ident ty _) = do
722check' val t@(ConstrainedType constraints ty) = do
720check' val t@(ConstrainedType constraints ty) = do
723 env <- getEnv
721 env <- getEnv
724 Just moduleName <- checkCurrentModule <$> get
722 Just moduleName <- checkCurrentModule <$> get
725− dictNames <- flip mapM constraints $ \(Qualified _ (ProperName className), _) -> do
723+ dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do
726 n <- liftCheck freshDictionaryName
724 n <- liftCheck freshDictionaryName
727 return $ Ident $ "__dict_" ++ className ++ "_" ++ show n
725 return $ Ident $ "__dict_" ++ className ++ "_" ++ show n
728 val' <- withTypeClassDictionaries (zipWith (\name (className, instanceTy) ->
726 val' <- withTypeClassDictionaries (zipWith (\name (className, instanceTy) ->
729 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
727 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
730 (qualifyAllUnqualifiedNames moduleName env constraints)) $
728 (qualifyAllUnqualifiedNames moduleName env constraints)) $
731 check val ty
729 check val ty
732− return $ TypedValue True (foldr Abs val' (map Left dictNames)) t
730+ return $ TypedValue True (foldr (Abs . Left) val' dictNames) t
733−check' val t@(SaturatedTypeSynonym name args) = do
731+check' val (SaturatedTypeSynonym name args) = do
734 ty <- introduceSkolemScope <=< expandTypeSynonym name $ args
732 ty <- introduceSkolemScope <=< expandTypeSynonym name $ args
735 val' <- check val ty
733 val' <- check val ty
736 return $ TypedValue True val' ty
734 return $ TypedValue True val' ty
@@ -747,8 +745,8 @@ check' v@(StringLiteral _) t | t == tyString =
747check' v@(BooleanLiteral _) t | t == tyBoolean =
745check' v@(BooleanLiteral _) t | t == tyBoolean =
748 return $ TypedValue True v t
746 return $ TypedValue True v t
749check' (ArrayLiteral vals) t@(TypeApp a ty) | a == tyArray = do
747check' (ArrayLiteral vals) t@(TypeApp a ty) | a == tyArray = do
750− arr <- ArrayLiteral <$> forM vals (\val -> check val ty)
748+ array <- ArrayLiteral <$> forM vals (`check` ty)
751− return $ TypedValue True arr t
749+ return $ TypedValue True array t
752check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do
750check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do
753 Just moduleName <- checkCurrentModule <$> get
751 Just moduleName <- checkCurrentModule <$> get
754 ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy
752 ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy
@@ -944,17 +942,17 @@ subsumes' val (Object r1) (Object r2) = do
944 go ts1' ts2' r1' r2'
942 go ts1' ts2' r1' r2'
945 return val
943 return val
947− go [] ts2 r1 r2 = r1 =?= rowFromList (ts2, r2)
945+ go [] ts2 r1' r2' = r1' =?= rowFromList (ts2, r2')
948− go ts1 [] r1 r2 = r2 =?= rowFromList (ts1, r1)
946+ go ts1 [] r1' r2' = r2' =?= rowFromList (ts1, r1')
949− go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1 r2
947+ go ((p1, ty1) : ts1) ((p2, ty2) : ts2) r1' r2'
950 | p1 == p2 = do subsumes Nothing ty1 ty2
948 | p1 == p2 = do subsumes Nothing ty1 ty2
951− go ts1 ts2 r1 r2
949+ go ts1 ts2 r1' r2'
952 | p1 < p2 = do rest <- fresh
950 | p1 < p2 = do rest <- fresh
953− r2 =?= RCons p1 ty1 rest
951+ r2' =?= RCons p1 ty1 rest
954− go ts1 ((p2, ty2) : ts2) r1 rest
952+ go ts1 ((p2, ty2) : ts2) r1' rest
955 | p1 > p2 = do rest <- fresh
953 | p1 > p2 = do rest <- fresh
956− r1 =?= RCons p2 ty2 rest
954+ r1' =?= RCons p2 ty2 rest
957− go ((p1, ty1) : ts1) ts2 rest r2
955+ go ((p1, ty1) : ts1) ts2 rest r2'
958subsumes' val ty1 ty2@(Object _) = subsumes val ty2 ty1
956subsumes' val ty1 ty2@(Object _) = subsumes val ty2 ty1
959subsumes' val ty1 ty2 = do
957subsumes' val ty1 ty2 = do
960 ty1 =?= ty2
958 ty1 =?= ty2