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
15data Environment = Environment {
16 constructor :: Map.Map String (IO (Int, [Variable], [Type], Type)),
17 types :: Map.Map String Type,
18 value :: Map.Map String Type
21initialEnvironment :: [(String, [String], [(String,[Src.Type])])] -> IO Environment
22initialEnvironment datatypes = do
23 types <- makeTypes datatypes
25 return $ Environment {
26 constructor = makeConstructors types,
31makeTypes :: [(String, [String], [(String, [Src.Type])])] -> IO (Map.Map String Type)
33 Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
35 nameAndKind (name, tvars, _) = (name, length tvars)
37 makeCtor (name, kind) = do
38 ctor <- VarN <$> namedVar Constant name
41 tuple n = ("_Tuple" ++ show n, n)
43 kind n names = map (\name -> (name, n)) names
45 builtins :: [(String,Int)]
46 builtins = concat [ map tuple [0..9]
47 , kind 1 ["_List","Maybe","Signal"]
48 , kind 0 ["Int","Float","Char","Bool","Element","Text","Color","Order"]
52makeConstructors :: Map.Map String Type -> Map.Map String (IO (Int, [Variable], [Type], Type))
53makeConstructors types = Map.fromList builtins
55 list t = (types ! "_List") <| t
56 maybe t = (types ! "Maybe") <| t
58 inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
59 inst numTVars tipe = do
60 vars <- forM [1..numTVars] $ \_ -> var Flexible
61 let (args, result) = tipe (map VarN vars)
62 return (length args, vars, args, result)
65 let name = "_Tuple" ++ show n
66 in (name, inst n $ \vs -> (vs, foldl (<|) (types ! name) vs))
68 builtins :: [ (String, IO (Int, [Variable], [Type], Type)) ]
69 builtins = [ ("Nothing", inst 1 $ \ [t] -> ([], maybe t))
70 , ("Just" , inst 1 $ \ [t] -> ([t], maybe t))
71 , ("[]" , inst 1 $ \ [t] -> ([], list t))
72 , ("::" , inst 1 $ \ [t] -> ([t, list t], list t))
73 ] ++ map tupleCtor [0..9]
76get :: Environment -> (Environment -> Map.Map String a) -> String -> a
77get env subDict key = Map.findWithDefault err key (subDict env)
79 err = error $ "Could not find '" ++ key ++ "' in the type environment."
82freshDataScheme :: Environment -> String -> IO (Int, [Variable], [Type], Type)
83freshDataScheme env name = get env constructor name
86instantiateType :: Environment -> Src.Type -> IO Type
87instantiateType env sourceType =
88 snd <$> instantiateTypeWithContext env sourceType Map.empty
90instantiateTypeWithContext :: Environment
92 -> Map.Map String Variable
93 -> IO ([Variable], Type)
94instantiateTypeWithContext env sourceType dict =
95 do (tipe, dict') <- State.runStateT (go sourceType) dict
96 return (Map.elems dict', tipe)
98 go :: Src.Type -> State.StateT (Map.Map String Variable) IO Type
101 Src.Lambda t1 t2 -> (==>) <$> go t1 <*> go t2
105 case Map.lookup x dict of
106 Just var -> return (VarN var)
108 do var <- State.liftIO $ namedVar flex x
109 State.put (Map.insert x var dict)
112 flex | "number" `isPrefixOf` x = Is Number
113 | "comparable" `isPrefixOf` x = Is Comparable
114 | "appendable" `isPrefixOf` x = Is Appendable
115 | otherwise = Flexible
117 Src.Data "String" [] ->
118 return (get env types "_List" <| get env types "Char")
120 Src.Data name ts -> do
122 return $ foldl (<|) (get env types name) ts'
124 Src.EmptyRecord -> return (TermN EmptyRecord1)
126 Src.Record fields ext ->
127 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