1{-# LANGUAGE OverloadedStrings #-}
2module Type.Inference where
4import Control.Arrow (first, second)
5import Control.Monad.Except (Except, forM, liftIO, runExceptT, throwError)
6import qualified Data.Map as Map
7import Data.Monoid ((<>))
10import qualified AST.Module as Module
11import qualified AST.Module.Name as ModuleName
12import qualified AST.Type as Type
13import qualified AST.Variable as Var
14import qualified Reporting.Annotation as A
15import qualified Reporting.Error.Type as Error
16import qualified Type.Constrain.Expression as TcExpr
17import qualified Type.Environment as Env
18import qualified Type.Solve as Solve
19import qualified Type.State as TS
20import qualified Type.Type as T
22import System.IO.Unsafe
23 -- Maybe possible to switch over to ST instead of IO.
24 -- I don't think that'd be worthwhile though.
30 -> Except [A.Located Error.Error] (Map.Map Text Type.Canonical)
31infer interfaces modul =
32 either throwError return $ unsafePerformIO $ runExceptT $
33 do (header, constraint) <-
34 liftIO (genConstraints interfaces modul)
36 state <- Solve.solve constraint
38 let header' = Map.delete "::" header
39 let types = Map.map A.drop (Map.difference (TS.sSavedEnv state) header')
41 liftIO (traverse T.toSrcType types)
47 -> IO (Map.Map Text T.Type, T.TypeConstraint)
48genConstraints interfaces modul =
50 Env.initialize (canonicalizeUnions interfaces modul)
53 forM (Env.ctorNames env) $ \name ->
54 do (_, vars, args, result) <- Env.freshDataScheme env name
55 return (name, (vars, foldr (T.==>) result args))
58 mapM (canonicalizeValues env) (Map.toList interfaces)
60 let allTypes = concat (ctors : importedVars)
61 let vars = concatMap (fst . snd) allTypes
62 let header = Map.map snd (Map.fromList allTypes)
63 let environ = T.CLet [ T.Scheme vars [] T.CTrue (Map.map (A.A undefined) header) ]
65 fvar <- T.mkVar Nothing
68 TcExpr.constrain env (Module.program (Module.info modul)) (T.VarN fvar)
70 return (header, environ constraint)
75 -> (ModuleName.Canonical, Module.Interface)
76 -> IO [(Text, ([T.Variable], T.Type))]
77canonicalizeValues env (moduleName, iface) =
78 forM (Map.toList (Module.iTypes iface)) $ \(name, tipe) ->
79 do (flexType, flexVars) <- Env.instantiateType T.Flex env tipe
81 ( ModuleName.canonicalToText moduleName <> "." <> name
82 , ( Map.elems flexVars
88canonicalizeUnions :: Module.Interfaces -> Module.Canonical -> [Module.CanonicalUnion]
89canonicalizeUnions interfaces (Module.Module name _ info) =
90 localUnions ++ importedUnions
92 localUnions :: [Module.CanonicalUnion]
94 format (name, Module.unions info)
96 importedUnions :: [Module.CanonicalUnion]
98 concatMap (format . second Module.iUnions) (Map.toList interfaces)
101format :: (ModuleName.Canonical, Module.Unions) -> [Module.CanonicalUnion]
102format (home, unions) =
103 map canonical (Map.toList unions)
105 canonical :: (Text, Module.UnionInfo Text) -> Module.CanonicalUnion
106 canonical (name, (tvars, ctors)) =
108 , (tvars, map (first toVar) ctors)
111 toVar :: Text -> Var.Canonical
113 Var.fromModule home name
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