@@ -1,41 +1,133 @@
1module Type.Environment where
1module Type.Environment where
3+import Control.Applicative ((<$>), (<*>))
5+import qualified Control.Monad.State as State
6+import qualified Data.Traversable as Traverse
3import qualified Data.Map as Map
7import qualified Data.Map as Map
4import Data.Map ((!))
8import Data.Map ((!))
5import qualified Data.UnionFind.IO as UF
9import qualified Data.UnionFind.IO as UF
11+import qualified SourceSyntax.Type as Src
7import Type.Type
12import Type.Type
9data Environment = Environment {
14data Environment = Environment {
10− constructor :: Map.Map String ([Variable], Type),
15+ constructor :: Map.Map String (IO (Int, [Variable], Type)),
11− builtin :: Map.Map String Type,
16+ types :: Map.Map String Type,
12 value :: Map.Map String Type
17 value :: Map.Map String Type
15−initialEnvironment :: IO Environment
20+initialEnvironment :: [(String, [String], [(String,[Src.Type])])] -> IO Environment
16−initialEnvironment = do
21+initialEnvironment datatypes = do
17− let mkPair name = fmap ((,) name . VarN) (namedVar name)
22+ types <- makeTypes datatypes
20− prims <- mapM mkPair ["Float","Char","Bool","Element"]
21− let builtins = list : int : prims
23− cons <- do v <- flexibleVar
24− let vlist = TermN (App1 (snd list) (VarN v))
25− return ([v], VarN v ==> vlist ==> vlist)
27− nil <- do v <- flexibleVar
28− return ([v], TermN (App1 (snd list) (VarN v)))
30− let add = snd int ==> snd int ==> snd int
32 return $ Environment {
24 return $ Environment {
33− constructor = Map.fromList [("::", cons), ("[]", nil)],
25+ constructor = makeConstructors types datatypes,
34− builtin = Map.fromList builtins,
26+ types = types,
35− value = Map.empty -- Map.fromList [("+", add)]
27+ value = Map.empty
31+ Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
33+ nameAndKind (name, tvars, _) = (name, length tvars)
35+ makeCtor (name, kind) = do
36+ ctor <- VarN <$> namedVar name
39+ tuple n = ("_Tuple" ++ show n, n)
41+ kind n names = map (\name -> (name, n)) names
43+ builtins :: [(String,Int)]
44+ builtins = concat [ map tuple [0..10]
45+ , kind 1 ["_List","Maybe","Signal"]
46+ , kind 0 ["Int","Float","Char","Bool","Element"]
49+makeConstructors types datatypes =
50+ Map.union (Map.fromList builtins) (Map.unions $ map (instances dummyEnv) datatypes)
52+ dummyEnv = Environment { constructor=Map.empty, types=types, value=Map.empty }
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..10]
38get :: Environment -> (Environment -> Map.Map String a) -> String -> a
75get :: Environment -> (Environment -> Map.Map String a) -> String -> a
39get env subDict key = Map.findWithDefault err key (subDict env)
76get env subDict key = Map.findWithDefault err key (subDict env)
41− err = error $ "Could not find '" ++ key ++ "' in the type environment."
78+ err = error $ "Could not find '" ++ key ++ "' in the type environment."
81+freshDataScheme :: Environment -> String -> IO (Int, [Variable], Type)
82+freshDataScheme env name = do
83+ putStr "fresh " >> putStrLn name
84+ get env constructor name
87+instances :: Environment
88+ -> (String, [String], [(String, [Src.Type])])
89+ -> Map.Map String (IO (Int, [Variable], Type))
90+instances env (name, tvars, ctors) = Map.fromList $ map go ctors
92+ tipe = Src.Data name (map Src.Var tvars)
94+ go (ctor, tipes) = (,) ctor $ do
95+ let funcType = foldr Src.Lambda tipe tipes
96+ (vars, ttype) <- instantiateTypeWithContext env funcType Map.empty
97+ return (length tipes, vars, ttype)
99+instantiateType :: Environment -> Src.Type -> IO Type
100+instantiateType env sourceType =
101+ snd <$> instantiateTypeWithContext env sourceType Map.empty
103+instantiateTypeWithContext :: Environment
105+ -> Map.Map String Variable
106+ -> IO ([Variable], Type)
107+instantiateTypeWithContext env sourceType dict =
108+ do (tipe, dict') <- State.runStateT (go sourceType) dict
109+ return (Map.elems dict', tipe)
111+ go :: Src.Type -> State.StateT (Map.Map String Variable) IO Type
114+ Src.Lambda t1 t2 -> TermN <$> (Fun1 <$> go t1 <*> go t2)
118+ case Map.lookup x dict of
119+ Just var -> return (VarN var)
121+ var <- State.liftIO $ namedVar x -- should this be Constant or Flexible?
122+ State.put (Map.insert x var dict)
125+ Src.Data name ts -> do
126+ State.liftIO $ putStr "instantiate " >> putStrLn name
128+ return $ foldr (\t result -> TermN $ App1 t result) (get env types name) ts'
130+ Src.EmptyRecord -> return (TermN EmptyRecord1)
132+ Src.Record fields ext ->
133+ TermN <$> (Record1 <$> Traverse.traverse (mapM go) fields <*> go ext)