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 Data.List (isPrefixOf)
10import qualified Data.UnionFind.IO as UF
12import qualified SourceSyntax.Type as Src
13import SourceSyntax.Module (ADT)
16data Environment = Environment {
17 constructor :: Map.Map String (IO (Int, [Variable], [Type], Type)),
18 types :: Map.Map String Type,
19 value :: Map.Map String Type
22initialEnvironment :: [ADT] -> IO Environment
23initialEnvironment datatypes = do
24 types <- makeTypes datatypes
26 return $ Environment {
27 constructor = makeConstructors types datatypes,
32makeTypes :: [ADT] -> IO (Map.Map String Type)
34 Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
36 nameAndKind (name, tvars, _) = (name, length tvars)
38 makeCtor (name, kind) = do
39 ctor <- VarN <$> namedVar Constant name
42 tuple n = ("_Tuple" ++ show n, n)
44 kind n names = map (\name -> (name, n)) names
46 builtins :: [(String,Int)]
47 builtins = concat [ map tuple [0..9]
48 , kind 1 ["_List","Signal"]
49 , kind 0 ["Int","Float","Char","Bool","Element","Text"
54makeConstructors :: Map.Map String Type
56 -> Map.Map String (IO (Int, [Variable], [Type], Type))
57makeConstructors types datatypes = Map.fromList builtins
59 list t = (types ! "_List") <| t
61 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
62 inst numTVars tipe = do
63 vars <- forM [1..numTVars] $ \_ -> var Flexible
64 let (args, result) = tipe (map VarN vars)
65 return (length args, vars, args, result)
68 let name = "_Tuple" ++ show n
69 in (name, inst n $ \vs -> (vs, foldl (<|) (types ! name) vs))
71 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
72 builtins = [ ("[]" , inst 1 $ \ [t] -> ([], list t))
73 , ("::" , inst 1 $ \ [t] -> ([t, list t], list t))
74 ] ++ map tupleCtor [0..9]
75 ++ concatMap (ctorToType tempEnv) datatypes
77 tempEnv = Environment { types = types, constructor = Map.empty, value = Map.empty }
79ctorToType :: Environment -> ADT -> [ (String, IO (Int, [Variable], [Type], Type)) ]
80ctorToType env (name, tvars, ctors) =
81 zip (map fst ctors) (map inst ctors)
83 inst :: (String, [Src.Type]) -> IO (Int, [Variable], [Type], Type)
85 ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
86 return (length args, Map.elems dict, args, tipe)
89 go :: (String, [Src.Type]) -> State.StateT (Map.Map String Variable) IO ([Type], Type)
91 types <- mapM (instantiator env) args
92 returnType <- instantiator env (Src.Data name (map Src.Var tvars))
93 return (types, returnType)
96get :: Environment -> (Environment -> Map.Map String a) -> String -> a
97get env subDict key = Map.findWithDefault err key (subDict env)
99 err = error $ "Could not find '" ++ key ++ "' in the type environment."
102freshDataScheme :: Environment -> String -> IO (Int, [Variable], [Type], Type)
103freshDataScheme env name = get env constructor name
106 Environment -> Src.Type -> Map.Map String Variable -> IO ([Variable], Type)
107instantiateType env sourceType dict =
108 do (tipe, dict') <- State.runStateT (instantiator env sourceType) dict
109 return (Map.elems dict', tipe)
111instantiator :: Environment -> Src.Type -> State.StateT (Map.Map String Variable) IO Type
112instantiator env sourceType = go sourceType
114 go :: Src.Type -> State.StateT (Map.Map String Variable) IO Type
117 Src.Lambda t1 t2 -> (==>) <$> go t1 <*> go t2
121 case Map.lookup x dict of
122 Just var -> return (VarN var)
124 do var <- State.liftIO $ namedVar flex x
125 State.put (Map.insert x var dict)
128 flex | "number" `isPrefixOf` x = Is Number
129 | "comparable" `isPrefixOf` x = Is Comparable
130 | "appendable" `isPrefixOf` x = Is Appendable
131 | otherwise = Flexible
133 Src.Data "String" [] ->
134 return (get env types "_List" <| get env types "Char")
136 Src.Data name ts -> do
138 return $ foldl (<|) (get env types name) ts'
140 Src.EmptyRecord -> return (TermN EmptyRecord1)
142 Src.Record fields ext ->
143 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