@@ -15,11 +15,12 @@
1515{-# LANGUAGE DeriveDataTypeable, FlexibleContexts #-}
1616
1717module Language.PureScript.TypeChecker.Types (
18− typeOf
18+ typesOf
1919) where
2020
2121import Data.List
2222import Data.Maybe (fromMaybe)
23+import Data.Either (lefts, rights)
2324import qualified Data.Data as D
2425import Data.Generics
2526 (mkT, something, everywhere, everywhereBut, mkQ, extQ)
@@ -139,33 +140,36 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
139140 unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return ()
140141 unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
141142
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)
169173
170174escapeCheck :: [AnyUnifiable] -> Type -> Substitution -> Check ()
171175escapeCheck checks ty sub =