1module Type.Environment where
3import Control.Applicative ((<$>), (<*>))
4import Control.Exception (try, SomeException)
6import Control.Monad.Error (ErrorT, throwError, liftIO)
7import qualified Control.Monad.State as State
8import qualified Data.Traversable as Traverse
9import qualified Data.Map as Map
10import Data.List (isPrefixOf)
11import qualified Text.PrettyPrint as PP
13import qualified AST.Type as T
14import qualified AST.Variable as V
15import AST.Module (CanonicalAdt, AdtInfo)
19type TypeDict = Map.Map String Type
20type VarDict = Map.Map String Variable
23data Environment = Environment
24 { constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
30initialEnvironment :: [CanonicalAdt] -> IO Environment
31initialEnvironment datatypes =
32 do types <- makeTypes datatypes
35 { constructor = Map.empty
39 return $ env { constructor = makeConstructors env datatypes }
42makeTypes :: [CanonicalAdt] -> IO TypeDict
44 do adts <- mapM makeImported datatypes
45 bs <- mapM makeBuiltin builtins
46 return (Map.fromList (adts ++ bs))
48 makeImported :: (V.Canonical, AdtInfo V.Canonical) -> IO (String, Type)
49 makeImported (var, _) =
50 do tvar <- namedVar Constant var
51 return (V.toString var, varN tvar)
53 makeBuiltin :: (String, Int) -> IO (String, Type)
54 makeBuiltin (name, _) =
55 do name' <- namedVar Constant (V.builtin name)
56 return (name, varN name')
58 builtins :: [(String, Int)]
63 , kind 0 ["Int","Float","Char","String","Bool"]
66 tuple n = ("_Tuple" ++ show n, n)
67 kind n names = map (\name -> (name, n)) names
73 -> Map.Map String (IO (Int, [Variable], [Type], Type))
74makeConstructors env datatypes =
78 (types env Map.! "List") <| t
80 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
82 do vars <- forM [1..numTVars] $ \_ -> variable Flexible
83 let (args, result) = tipe (map (varN) vars)
84 return (length args, vars, args, result)
87 let name = "_Tuple" ++ show n
88 in (name, inst n $ \vs -> (vs, foldl (<|) (types env Map.! name) vs))
90 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
92 [ ("[]", inst 1 $ \ [t] -> ([], list t))
93 , ("::", inst 1 $ \ [t] -> ([t, list t], list t))
94 ] ++ map tupleCtor [0..9]
95 ++ concatMap (ctorToType env) datatypes
100 -> (V.Canonical, AdtInfo V.Canonical)
101 -> [(String, IO (Int, [Variable], [Type], Type))]
102ctorToType env (name, (tvars, ctors)) =
103 zip (map (V.toString . fst) ctors) (map inst ctors)
105 inst :: (V.Canonical, [T.CanonicalType]) -> IO (Int, [Variable], [Type], Type)
107 do ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
108 return (length args, Map.elems dict, args, tipe)
111 go :: (V.Canonical, [T.CanonicalType]) -> State.StateT VarDict IO ([Type], Type)
113 do types <- mapM (instantiator env) args
114 returnType <- instantiator env (T.App (T.Type name) (map T.Var tvars))
115 return (types, returnType)
118get :: Environment -> (Environment -> Map.Map String a) -> String -> a
120 Map.findWithDefault (error msg) key (subDict env)
122 msg = "Could not find type constructor '" ++ key ++ "' while checking types."
128 -> IO (Int, [Variable], [Type], Type)
129freshDataScheme env name =
130 get env constructor name
137 -> ErrorT [PP.Doc] IO ([Variable], Type)
138instantiateType env sourceType dict =
139 do result <- liftIO $ try (State.runStateT (instantiator env sourceType) dict)
140 case result :: Either SomeException (Type, VarDict) of
142 throwError [ PP.text $ show someError ]
144 Right (tipe, dict') ->
145 return (Map.elems dict', tipe)
151 -> State.StateT VarDict IO Type
152instantiator env sourceType =
155 go :: T.CanonicalType -> State.StateT VarDict IO Type
159 (==>) <$> go t1 <*> go t2
163 case Map.lookup x dict of
164 Just v -> return (varN v)
166 do v <- State.liftIO $ namedVar flex (V.local x)
167 State.put (Map.insert x v dict)
170 flex | "number" `isPrefixOf` x = Is Number
171 | "comparable" `isPrefixOf` x = Is Comparable
172 | "appendable" `isPrefixOf` x = Is Appendable
173 | otherwise = Flexible
178 VarN _ v -> return (VarN (Just name) v)
179 TermN _ term -> return (TermN (Just name) term)
182 case Map.lookup (V.toString name) (types env) of
186 "Could not find type constructor '" ++
187 V.toString name ++ "' while checking types."
192 return $ foldl (<|) t' ts'
194 T.Record fields ext ->
195 do fields' <- Traverse.traverse (mapM go) (T.fieldMap fields)
198 Nothing -> return $ termN EmptyRecord1
200 return $ termN (Record1 fields' ext')
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