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