1module Type.Environment where
3import Control.Applicative ((<$>), (<*>))
5import qualified Control.Monad.State as State
6import qualified Data.Traversable as Traverse
7import qualified Data.Map as Map
9import qualified Data.UnionFind.IO as UF
11import qualified SourceSyntax.Type as Src
14data Environment = Environment {
15 constructor :: Map.Map String (IO (Int, [Variable], Type)),
16 types :: Map.Map String Type,
17 value :: Map.Map String Type
20initialEnvironment :: [(String, [String], [(String,[Src.Type])])] -> IO Environment
21initialEnvironment datatypes = do
22 types <- makeTypes datatypes
24 return $ Environment {
25 constructor = makeConstructors types,
30makeTypes :: [(String, [String], [(String, [Src.Type])])] -> IO (Map.Map String Type)
32 Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
34 nameAndKind (name, tvars, _) = (name, length tvars)
36 makeCtor (name, kind) = do
37 ctor <- VarN <$> namedVar Constant name
40 tuple n = ("_Tuple" ++ show n, n)
42 kind n names = map (\name -> (name, n)) names
44 builtins :: [(String,Int)]
45 builtins = concat [ map tuple [0..9]
46 , kind 1 ["_List","Maybe","Signal"]
47 , kind 0 ["Int","Float","Char","Bool","Element"]
51makeConstructors :: Map.Map String Type -> Map.Map String (IO (Int, [Variable], Type))
52makeConstructors types = Map.fromList builtins
54 list t = (types ! "_List") <| t
55 maybe t = (types ! "Maybe") <| t
57 inst :: Int -> Int -> ([Type] -> Type) -> IO (Int, [Variable], Type)
58 inst kind numTVars tipe = do
59 vars <- forM [1..numTVars] $ \_ -> flexibleVar
60 return (kind, vars, tipe $ map VarN vars)
63 let name = "_Tuple" ++ show n
64 in (name, inst n n $ \vs -> foldr (==>) (foldl (<|) (types ! name) vs) vs)
66 builtins :: [ (String, IO (Int, [Variable], Type)) ]
67 builtins = [ ("Nothing", inst 0 1 $ \ [t] -> maybe t)
68 , ("Just" , inst 1 1 $ \ [t] -> t ==> maybe t)
69 , ("[]" , inst 0 1 $ \ [t] -> list t)
70 , ("::" , inst 2 1 $ \ [t] -> t ==> list t ==> list t)
71 ] ++ map tupleCtor [0..9]
74get :: Environment -> (Environment -> Map.Map String a) -> String -> a
75get env subDict key = Map.findWithDefault err key (subDict env)
77 err = error $ "Could not find '" ++ key ++ "' in the type environment."
80freshDataScheme :: Environment -> String -> IO (Int, [Variable], Type)
81freshDataScheme env name = get env constructor name
84instantiateType :: Environment -> Src.Type -> IO Type
85instantiateType env sourceType =
86 snd <$> instantiateTypeWithContext env sourceType Map.empty
88instantiateTypeWithContext :: Environment
90 -> Map.Map String Variable
91 -> IO ([Variable], Type)
92instantiateTypeWithContext env sourceType dict =
93 do (tipe, dict') <- State.runStateT (go sourceType) dict
94 return (Map.elems dict', tipe)
96 go :: Src.Type -> State.StateT (Map.Map String Variable) IO Type
99 Src.Lambda t1 t2 -> TermN <$> (Fun1 <$> go t1 <*> go t2)
103 case Map.lookup x dict of
104 Just var -> return (VarN var)
106 var <- State.liftIO $ namedVar Flexible x -- should this be Constant or Flexible?
107 State.put (Map.insert x var dict)
110 Src.Data name ts -> do
112 return $ foldl (\tyFn ty -> TermN $ App1 tyFn ty) (get env types name) ts'
114 Src.EmptyRecord -> return (TermN EmptyRecord1)
116 Src.Record fields ext ->
117 TermN <$> (Record1 <$> Traverse.traverse (mapM go) fields <*> go 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