@@ -1,147 +1,180 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE OverloadedStrings #-}
2module Type.Environment
3module Type.Environment
4 , initialize
6 , initialize
5− , getType, freshDataScheme, ctorNames
7+ , get, getType, freshDataScheme, ctorNames
6 , addValues
8 , addValues
7 , instantiateType
9 , instantiateType
13+import Control.Monad (foldM)
11import qualified Control.Monad.State as State
14import qualified Control.Monad.State as State
12−import Data.Map ((!))
15+import qualified Data.List as List
13import qualified Data.Map as Map
16import qualified Data.Map as Map
14import qualified Data.Set as Set
17import qualified Data.Set as Set
18+import qualified Data.Text as Text
19+import Data.Text (Text)
16import qualified AST.Type as T
21import qualified AST.Type as T
17−import qualified AST.Variable as V
22+import qualified AST.Variable as Var
18import qualified AST.Module as Module
23import qualified AST.Module as Module
19import Type.Type
24import Type.Type
22−type TypeDict = Map.Map String Type
23−type VarDict = Map.Map String Variable
26−data Env = Env
31+data Env =
27− { _constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
32+ Env
33+ { _ctor :: Dict Instantiator
28− , _types :: TypeDict
34+ , _types :: Dict Type
29− , _value :: TypeDict
35+ , _value :: Dict Type
40+ IO (Int, [Variable], [Type], Type)
33initialize :: [Module.CanonicalUnion] -> IO Env
47initialize :: [Module.CanonicalUnion] -> IO Env
34−initialize datatypes =
48+initialize unions =
35− do types <- makeTypes datatypes
49+ do types <- makeTypes unions
38− { _constructor = Map.empty
52+ { _ctor = Map.empty
39 , _value = Map.empty
53 , _value = Map.empty
40 , _types = types
54 , _types = types
42− return $ env { _constructor = makeConstructors env datatypes }
56+ return $ env { _ctor = makeCtors env unions }
45−makeTypes :: [Module.CanonicalUnion] -> IO TypeDict
47− do unions <- mapM makeImported datatypes
48− bs <- mapM makeBuiltin builtins
49− return (Map.fromList (unions ++ bs))
51− makeImported :: (V.Canonical, Module.UnionInfo V.Canonical) -> IO (String, Type)
52− makeImported (name, _) =
53− do tvar <- mkAtom name
54− return (V.toString name, VarN tvar)
56− makeBuiltin :: (String, Int) -> IO (String, Type)
60+-- TYPES
57− makeBuiltin (name, _) =
58− do name' <- mkAtom (V.builtin name)
59− return (name, VarN name')
61− builtins :: [(String, Int)]
62+
62− builtins =
63+makeTypes :: [Module.CanonicalUnion] -> IO (Dict Type)
65+ do builtinDict <- Map.fromList <$> mapM makeBuiltin builtinTypes
66+ foldM addImported builtinDict unions
69+addImported :: Dict Type -> (Var.Canonical, unionInfo) -> IO (Dict Type)
70+addImported dict ( var, _ ) =
71+ do atom <- mkAtom var
72+ return (Map.insert (Var.toText var) (VarN atom) dict)
75+makeBuiltin :: (Text, Int) -> IO (Text, Type)
76+makeBuiltin (name, _) =
77+ do atom <- mkAtom (Var.builtin name)
78+ return (name, VarN atom)
81+builtinTypes :: [(Text, Int)]
64− [ map tuple [0..9]
84+ [ map tuple [0..9]
65− , kind 1 ["List"]
85+ , kind 1 ["List"]
66− , kind 0 ["Int","Float","Char","String","Bool"]
86+ , kind 0 ["Int","Float","Char","String","Bool"]
69− tuple n = ("_Tuple" ++ show n, n)
70− kind n names = map (\name -> (name, n)) names
75− -> [Module.CanonicalUnion]
76− -> Map.Map String (IO (Int, [Variable], [Type], Type))
77−makeConstructors env datatypes =
78− Map.fromList builtins
89+ tuple n = ( Text.pack ("_Tuple" ++ show n), n )
90+ kind n names = map (\name -> (name, n)) names
97+makeCtors :: Env -> [Module.CanonicalUnion] -> Dict Instantiator
98+makeCtors env unions =
81− (_types env ! "List") <| t
101+ getType env "List" <| t
83− inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
103+ inst :: Int -> ([Type] -> ([Type], Type)) -> Instantiator
84 inst numTVars tipe =
104 inst numTVars tipe =
85 do vars <- mapM (\_ -> mkVar Nothing) [1..numTVars]
105 do vars <- mapM (\_ -> mkVar Nothing) [1..numTVars]
86 let (args, result) = tipe (map (VarN) vars)
106 let (args, result) = tipe (map (VarN) vars)
87 return (length args, vars, args, result)
107 return (length args, vars, args, result)
89 tupleCtor n =
109 tupleCtor n =
90− let name = "_Tuple" ++ show n
112+ Text.pack ("_Tuple" ++ show n)
91− in (name, inst n $ \vs -> (vs, foldl (<|) (_types env ! name) vs))
114+ (name, inst n $ \vs -> (vs, foldl (<|) (getType env name) vs))
93− builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
116+ builtins :: Dict Instantiator
94 builtins =
117 builtins =
95 [ ("[]", inst 1 $ \ [t] -> ([], list t))
119 [ ("[]", inst 1 $ \ [t] -> ([], list t))
96 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
120 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
97− ] ++ map tupleCtor [0..9]
122+ ++ map tupleCtor [0..9]
98− ++ concatMap (ctorToType env) datatypes
123+ in
124+ List.foldl' (makeCtorsHelp env) builtins unions
101−ctorToType
127+type VarDict =
102− :: Env
128+ Map.Map Text Variable
103− -> (V.Canonical, Module.UnionInfo V.Canonical)
104− -> [(String, IO (Int, [Variable], [Type], Type))]
105−ctorToType env (name, (tvars, ctors)) =
106− zip (map (V.toString . fst) ctors) (map inst ctors)
108− inst :: (V.Canonical, [T.Canonical]) -> IO (Int, [Variable], [Type], Type)
110− do ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
111− return (length args, Map.elems dict, args, tipe)
131+makeCtorsHelp :: Env -> Dict Instantiator -> Module.CanonicalUnion -> Dict Instantiator
132+makeCtorsHelp env constructorDict ( var, (rawTypeVars, ctors) ) =
134+ inst :: Dict Instantiator -> (Var.Canonical, [T.Canonical]) -> Dict Instantiator
135+ inst ctorDict (name, rawArgs) =
138+ ( do ((args, tipe), dict) <- State.runStateT (go rawArgs) Map.empty
139+ return ( length args, Map.elems dict, args, tipe )
144+ map T.Var rawTypeVars
114− go :: (V.Canonical, [T.Canonical]) -> State.StateT VarDict IO ([Type], Type)
146+ go :: [T.Canonical] -> State.StateT VarDict IO ([Type], Type)
115− go (_, args) =
147+ go args =
116 do types <- mapM (instantiator Flex env) args
148 do types <- mapM (instantiator Flex env) args
117− returnType <- instantiator Flex env (T.App (T.Type name) (map T.Var tvars))
149+ returnType <- instantiator Flex env (T.App (T.Type var) tvars)
118 return (types, returnType)
150 return (types, returnType)
152+ List.foldl' inst constructorDict ctors
122-- ACCESS TYPES
156-- ACCESS TYPES
125−get :: (Env -> Map.Map String a) -> Env -> String -> a
159+{-# INLINE get #-}
126−get subDict env key =
160+get :: Dict a -> Text -> a
127− Map.findWithDefault (error msg) key (subDict env)
161+get dict var =
128− where
162+ dict Map.! var
129− msg = "Could not find type constructor `" ++ key ++ "` while checking types."
132−getType :: Env -> String -> Type
165+getType :: Env -> Text -> Type
133−getType =
166+getType env var =
134− get _types
167+ get (_types env) var
137−freshDataScheme :: Env -> String -> IO (Int, [Variable], [Type], Type)
170+freshDataScheme :: Env -> Text -> Instantiator
138−freshDataScheme =
171+freshDataScheme env var =
139− get _constructor
172+ get (_ctor env) var
142−ctorNames :: Env -> [String]
175+ctorNames :: Env -> [Text]
143ctorNames env =
176ctorNames env =
144− Map.keys (_constructor env)
177+ Map.keys (_ctor env)
@@ -167,7 +200,7 @@ instantiator flex env sourceType =
167 instantiatorHelp flex env Set.empty sourceType
200 instantiatorHelp flex env Set.empty sourceType
170−instantiatorHelp :: Flex -> Env -> Set.Set String -> T.Canonical -> State.StateT VarDict IO Type
203+instantiatorHelp :: Flex -> Env -> Set.Set Text -> T.Canonical -> State.StateT VarDict IO Type
171instantiatorHelp flex env aliasVars sourceType =
204instantiatorHelp flex env aliasVars sourceType =
@@ -198,7 +231,7 @@ instantiatorHelp flex env aliasVars sourceType =
198 return (VarN variable)
231 return (VarN variable)
200 T.Aliased name args aliasType ->
233 T.Aliased name args aliasType ->
201− do targs <- mapM (\(arg,tipe) -> (,) arg <$> go tipe) args
234+ do targs <- traverse (traverse go) args
202 realType <-
235 realType <-
203 case aliasType of
236 case aliasType of
204 T.Filled tipe ->
237 T.Filled tipe ->
@@ -210,18 +243,11 @@ instantiatorHelp flex env aliasVars sourceType =
210 return (AliasN name targs realType)
243 return (AliasN name targs realType)
212 T.Type name ->
245 T.Type name ->
213− case Map.lookup (V.toString name) (_types env) of
246+ return (getType env (Var.toText name))
219− "Could not find type constructor `" ++
220− V.toString name ++ "` while checking types."
222 T.App func args ->
248 T.App func args ->
223 do tfunc <- go func
249 do tfunc <- go func
224− targs <- mapM go args
250+ targs <- traverse go args
225 return $ foldl (<|) tfunc targs
251 return $ foldl (<|) tfunc targs
227 T.Record fields ext ->
253 T.Record fields ext ->