@@ -14,19 +14,22 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
16{-# OPTIONS_GHC -fno-warn-orphans #-}
16{-# OPTIONS_GHC -fno-warn-orphans #-}
17−{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
17+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TupleSections #-}
19module Language.PureScript.TypeChecker.Kinds (
19module Language.PureScript.TypeChecker.Kinds (
21+ kindOfWithScopedVars,
22 kindsOfAll
23 kindsOfAll
25import Data.Maybe (fromMaybe)
26import Data.Maybe (fromMaybe)
26import Data.Monoid ((<>))
27import Data.Monoid ((<>))
27import qualified Data.HashMap.Strict as H
29import qualified Data.HashMap.Strict as H
28import qualified Data.Map as M
30import qualified Data.Map as M
32+import Control.Arrow (second)
30import Control.Applicative
33import Control.Applicative
31import Control.Monad.Error
34import Control.Monad.Error
32import Control.Monad.State
35import Control.Monad.State
@@ -69,11 +72,19 @@ instance Unifiable Check Kind where
69-- Infer the kind of a single type
72-- Infer the kind of a single type
71kindOf :: ModuleName -> Type -> Check Kind
74kindOf :: ModuleName -> Type -> Check Kind
72−kindOf _ ty =
75+kindOf _ ty = fst <$> kindOfWithScopedVars ty
78+-- Infer the kind of a single type, returning the kinds of any scoped type variables
80+kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
81+kindOfWithScopedVars ty =
73 rethrow (mkErrorStack "Error checking kind" (Just (TypeError ty)) <>) $
82 rethrow (mkErrorStack "Error checking kind" (Just (TypeError ty)) <>) $
74− fmap (starIfUnknown . tidyUp) . liftUnify $ infer ty
83+ fmap tidyUp . liftUnify $ infer ty
76− tidyUp (k, sub) = sub $? k
85+ tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
86+ , map (second (starIfUnknown . (sub $?))) args
79-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
90-- Infer the kind of a type constructor with a collection of arguments and a collection of associated data constructors
@@ -125,7 +136,7 @@ kindsOfAll moduleName syns tys = fmap tidyUp . liftUnify $ do
126solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
137solveTypes :: Bool -> [Type] -> [Kind] -> Kind -> UnifyT Kind Check Kind
127solveTypes isData ts kargs tyCon = do
138solveTypes isData ts kargs tyCon = do
128− ks <- mapM infer ts
139+ ks <- mapM (fmap fst . infer) ts
129 when isData $ do
140 when isData $ do
130 tyCon =?= foldr FunKind Star kargs
141 tyCon =?= foldr FunKind Star kargs
131 forM_ ks $ \k -> k =?= Star
142 forM_ ks $ \k -> k =?= Star
@@ -145,48 +156,64 @@ starIfUnknown k = k
146-- Infer a kind for a type
157-- Infer a kind for a type
148−infer :: Type -> UnifyT Kind Check Kind
159+infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
149infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty
160infer ty = rethrow (mkErrorStack "Error inferring type of value" (Just (TypeError ty)) <>) $ infer' ty
151−infer' :: Type -> UnifyT Kind Check Kind
162+infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
152−infer' TypeWildcard = fresh
153−infer' (TypeVar v) = do
154− Just moduleName <- checkCurrentModule <$> get
155− UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
156−infer' c@(TypeConstructor v) = do
157− env <- liftCheck getEnv
158− case M.lookup v (types env) of
159− Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
160− Just (kind, _) -> return kind
161−infer' (TypeApp t1 t2) = do
165− k1 =?= FunKind k2 k0
167infer' (ForAll ident ty _) = do
163infer' (ForAll ident ty _) = do
168 k1 <- fresh
164 k1 <- fresh
169 Just moduleName <- checkCurrentModule <$> get
165 Just moduleName <- checkCurrentModule <$> get
170− k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
166+ (k2, args) <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ infer ty
171 k2 =?= Star
167 k2 =?= Star
172− return Star
168+ return (Star, (ident, k1) : args)
176−infer' (RCons _ ty row) = do
181−infer' (ConstrainedType deps ty) = do
182− forM_ deps $ \(className, tys) -> do
183− _ <- infer $ foldl TypeApp (TypeConstructor className) tys
188infer' (KindedType ty k) = do
169infer' (KindedType ty k) = do
189− k' <- infer ty
170+ (k', args) <- infer ty
191− return k'
172+ return (k', args)
173+infer' other = (, []) <$> go other
175+ go :: Type -> UnifyT Kind Check Kind
176+ go (ForAll ident ty _) = do
178+ Just moduleName <- checkCurrentModule <$> get
179+ k2 <- bindLocalTypeVariables moduleName [(ProperName ident, k1)] $ go ty
182+ go (KindedType ty k) = do
186+ go TypeWildcard = fresh
188+ Just moduleName <- checkCurrentModule <$> get
189+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
190+ go (Skolem v _ _) = do
191+ Just moduleName <- checkCurrentModule <$> get
192+ UnifyT . lift $ lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
193+ go c@(TypeConstructor v) = do
194+ env <- liftCheck getEnv
195+ case M.lookup v (types env) of
196+ Nothing -> UnifyT . lift . throwError $ mkErrorStack "Unknown type constructor" (Just (TypeError c))
197+ Just (kind, _) -> return kind
198+ go (TypeApp t1 t2) = do
202+ k1 =?= FunKind k2 k0
207+ go (RCons _ ty row) = do
212+ go (ConstrainedType deps ty) = do
213+ forM_ deps $ \(className, tys) -> do
214+ _ <- go $ foldl TypeApp (TypeConstructor className) tys
192−infer' _ = error "Invalid argument to infer"
219+ go _ = error "Invalid argument to infer"