|
15 | 15 | {-# LANGUAGE DeriveDataTypeable, FlexibleContexts #-} |
16 | 16 |
|
17 | 17 | module Language.PureScript.TypeChecker.Types ( |
18 | | - typeOf |
| 18 | + typesOf |
19 | 19 | ) where |
20 | 20 |
|
21 | 21 | import Data.List |
22 | 22 | import Data.Maybe (fromMaybe) |
| 23 | +import Data.Either (lefts, rights) |
23 | 24 | import qualified Data.Data as D |
24 | 25 | import Data.Generics |
25 | 26 | (mkT, something, everywhere, everywhereBut, mkQ, extQ) |
@@ -139,33 +140,36 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 + |
139 | 140 | unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return () |
140 | 141 | unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "." |
141 | 142 |
|
142 | | -isFunction :: Value -> Bool |
143 | | -isFunction (Abs _ _) = True |
144 | | -isFunction (TypedValue untyped _) = isFunction untyped |
145 | | -isFunction _ = False |
146 | | - |
147 | | -typeOf :: Maybe Ident -> Value -> Check Type |
148 | | -typeOf name val = do |
149 | | - (ty, sub, checks) <- runSubst $ case name of |
150 | | - Just ident | isFunction val -> |
151 | | - case val of |
152 | | - TypedValue value ty -> do |
153 | | - kind <- liftCheck $ kindOf ty |
154 | | - guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star |
155 | | - ty' <- replaceAllTypeSynonyms ty |
156 | | - modulePath <- checkModulePath <$> get |
157 | | - bindNames (M.singleton (modulePath, ident) (ty, LocalVariable)) $ check value ty' |
158 | | - return ty' |
159 | | - _ -> do |
160 | | - me <- fresh |
161 | | - modulePath <- checkModulePath <$> get |
162 | | - ty <- bindNames (M.singleton (modulePath, ident) (me, LocalVariable)) $ infer val |
163 | | - ty ~~ me |
164 | | - return ty |
165 | | - _ -> infer val |
166 | | - escapeCheck checks ty sub |
167 | | - skolemEscapeCheck ty |
168 | | - return $ varIfUnknown $ desaturateAllTypeSynonyms $ setifyAll ty |
| 143 | +typesOf :: [(Ident, Value)] -> Check [Type] |
| 144 | +typesOf vals = do |
| 145 | + (tys, sub, checks) <- runSubst $ do |
| 146 | + modulePath <- checkModulePath <$> get |
| 147 | + let es = map isTyped vals |
| 148 | + typed = lefts es |
| 149 | + untyped = rights es |
| 150 | + typedDict = map (\(ident, ty, _) -> (ident, ty)) typed |
| 151 | + untypedNames <- replicateM (length untyped) fresh |
| 152 | + let untypedDict = zip (map fst untyped) untypedNames |
| 153 | + dict = M.fromList (map (\(ident, ty) -> ((modulePath, ident), (ty, LocalVariable))) $ typedDict ++ untypedDict) |
| 154 | + tys <- forM es $ \e -> case e of |
| 155 | + Left (_, ty, val) -> do |
| 156 | + kind <- liftCheck $ kindOf ty |
| 157 | + guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star |
| 158 | + ty' <- replaceAllTypeSynonyms ty |
| 159 | + bindNames dict $ check val ty' |
| 160 | + return ty' |
| 161 | + Right (ident, val) -> do |
| 162 | + ty <- bindNames dict $ infer val |
| 163 | + ty ~~ fromMaybe (error "name not found in dictionary") (lookup ident untypedDict) |
| 164 | + return ty |
| 165 | + return tys |
| 166 | + forM tys $ flip (escapeCheck checks) sub |
| 167 | + forM tys $ skolemEscapeCheck |
| 168 | + return $ map (varIfUnknown . desaturateAllTypeSynonyms . setifyAll) tys |
| 169 | + |
| 170 | +isTyped :: (Ident, Value) -> Either (Ident, Type, Value) (Ident, Value) |
| 171 | +isTyped (name, TypedValue value ty) = Left (name, ty, value) |
| 172 | +isTyped (name, value) = Right (name, value) |
169 | 173 |
|
170 | 174 | escapeCheck :: [AnyUnifiable] -> Type -> Substitution -> Check () |
171 | 175 | escapeCheck checks ty sub = |
|
0 commit comments