1{-# OPTIONS_GHC -Wall #-}
5 , getType, freshDataScheme, ctorNames
11import qualified Control.Monad.State as State
12import qualified Data.List as List
14import qualified Data.Map as Map
15import qualified Data.Set as Set
17import qualified AST.Type as T
18import qualified AST.Variable as V
19import qualified AST.Module as Module
23type TypeDict = Map.Map String Type
24type VarDict = Map.Map String Variable
27data Environment = Environment
28 { _constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
34initialize :: [Module.CanonicalUnion] -> IO Environment
36 do types <- makeTypes datatypes
39 { _constructor = Map.empty
43 return $ env { _constructor = makeConstructors env datatypes }
46makeTypes :: [Module.CanonicalUnion] -> IO TypeDict
48 do unions <- mapM makeImported datatypes
49 bs <- mapM makeBuiltin builtins
50 return (Map.fromList (unions ++ bs))
52 makeImported :: (V.Canonical, Module.UnionInfo V.Canonical) -> IO (String, Type)
53 makeImported (name, _) =
54 do tvar <- mkAtom name
55 return (V.toString name, VarN tvar)
57 makeBuiltin :: (String, Int) -> IO (String, Type)
58 makeBuiltin (name, _) =
59 do name' <- mkAtom (V.builtin name)
60 return (name, VarN name')
62 builtins :: [(String, Int)]
67 , kind 0 ["Int","Float","Char","String","Bool"]
70 tuple n = ("_Tuple" ++ show n, n)
71 kind n names = map (\name -> (name, n)) names
76 -> [Module.CanonicalUnion]
77 -> Map.Map String (IO (Int, [Variable], [Type], Type))
78makeConstructors env datatypes =
82 (_types env ! "List") <| t
84 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
86 do vars <- mapM (\_ -> mkVar Nothing) [1..numTVars]
87 let (args, result) = tipe (map (VarN) vars)
88 return (length args, vars, args, result)
91 let name = "_Tuple" ++ show n
92 in (name, inst n $ \vs -> (vs, foldl (<|) (_types env ! name) vs))
94 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
96 [ ("[]", inst 1 $ \ [t] -> ([], list t))
97 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
98 ] ++ map tupleCtor [0..9]
99 ++ concatMap (ctorToType env) datatypes
104 -> (V.Canonical, Module.UnionInfo V.Canonical)
105 -> [(String, IO (Int, [Variable], [Type], Type))]
106ctorToType env (name, (tvars, ctors)) =
107 zip (map (V.toString . fst) ctors) (map inst ctors)
109 inst :: (V.Canonical, [T.Canonical]) -> IO (Int, [Variable], [Type], Type)
111 do ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
112 return (length args, Map.elems dict, args, tipe)
115 go :: (V.Canonical, [T.Canonical]) -> State.StateT VarDict IO ([Type], Type)
117 do types <- mapM (instantiator env) args
118 returnType <- instantiator env (T.App (T.Type name) (map T.Var tvars))
119 return (types, returnType)
126get :: (Environment -> Map.Map String a) -> Environment -> String -> a
128 Map.findWithDefault (error msg) key (subDict env)
130 msg = "Could not find type constructor `" ++ key ++ "` while checking types."
133getType :: Environment -> String -> Type
138freshDataScheme :: Environment -> String -> IO (Int, [Variable], [Type], Type)
143ctorNames :: Environment -> [String]
145 Map.keys (_constructor env)
151addValues :: Environment -> [(String, Variable)] -> Environment
152addValues env newValues =
156 (\dict (name, var) -> Map.insert name (VarN var) dict)
166instantiateType :: Environment -> T.Canonical -> VarDict -> IO ([Variable], Type)
167instantiateType env sourceType dict =
168 do (tipe, dict') <- State.runStateT (instantiator env sourceType) dict
169 return (Map.elems dict', tipe)
172instantiator :: Environment -> T.Canonical -> State.StateT VarDict IO Type
173instantiator env sourceType =
174 instantiatorHelp env Set.empty sourceType
177instantiatorHelp :: Environment -> Set.Set String -> T.Canonical -> State.StateT VarDict IO Type
178instantiatorHelp env aliasVars sourceType =
181 instantiatorHelp env aliasVars
185 (==>) <$> go t1 <*> go t2
188 if Set.member name aliasVars then
189 return (PlaceHolder name)
193 case Map.lookup name dict of
195 return (VarN variable)
198 do variable <- State.liftIO (mkNamedVar name)
199 State.put (Map.insert name variable dict)
200 return (VarN variable)
202 T.Aliased name args aliasType ->
203 do targs <- mapM (\(arg,tipe) -> (,) arg <$> go tipe) args
207 instantiatorHelp env Set.empty tipe
210 instantiatorHelp env (Set.fromList (map fst args)) tipe
212 return (AliasN name targs realType)
215 case Map.lookup (V.toString name) (_types env) of
221 "Could not find type constructor `" ++
222 V.toString name ++ "` while checking types."
226 targs <- mapM go args
227 return $ foldl (<|) tfunc targs
229 T.Record fields ext ->
230 do tfields <- traverse go (Map.fromList fields)
234 return $ TermN EmptyRecord1
239 return $ TermN (Record1 tfields text)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list