on master help sign in
Remove the Type.Alias module
commit07907a0941ef0de02b3b27130fbbd9520b010417 authorEvan Czaplicki <info@elm-lang.org> dateWed 4 Jun 2014, 16:11 (12 years ago) parent9715180
6 files changed+24−180
Elm.cabal−2 compiler/Build/Print.hs+1−4 compiler/Type/Alias.hs−148 compiler/Type/ExtraChecks.hs+12−14 compiler/Type/Inference.hs+3−5 compiler/Type/State.hs+8−7
Elm.cabal−2
@@ -78,7 +78,6 @@ Library
7878 Parse.Parse,
7979 Parse.Pattern,
8080 Parse.Type,
81− Type.Alias,
8281 Type.Constrain.Expression,
8382 Type.Constrain.Literal,
8483 Type.Constrain.Pattern,
@@ -170,7 +169,6 @@ Executable elm
170169 Parse.Parse,
171170 Parse.Pattern,
172171 Parse.Type,
173− Type.Alias,
174172 Type.Constrain.Expression,
175173 Type.Constrain.Literal,
176174 Type.Constrain.Pattern,
compiler/Build/Print.hs+1−4
@@ -7,7 +7,6 @@ import qualified Data.Map as Map
77import qualified Data.List as List
88import qualified AST.Module as M
99import qualified AST.PrettyPrint as Pretty
10−import qualified Type.Alias as Alias
1110import qualified Text.PrettyPrint as P
1211
1312moduleTypes :: Map.Map String M.Interface -> M.CanonicalModule -> IO ()
@@ -25,12 +24,10 @@ types interfaces types' aliases imports =
2524 mapM_ printType (Map.toList types')
2625 putStrLn ""
2726 where
28− rules = Alias.rules interfaces aliases imports
29−
3027 printType (n,t) = do
3128 print $ P.hsep [ Pretty.variable n
3229 , P.text ":"
33− , Pretty.pretty (Alias.realias rules t) ]
30+ , Pretty.pretty t ]
3431
3532errors :: [P.Doc] -> IO ()
3633errors errs =
compiler/Type/Alias.hsdeleted−148
@@ -1,148 +0,0 @@
1−{-# OPTIONS_GHC -W #-}
2−module Type.Alias (realias, rules, canonicalRealias, Rules) where
3−
4−import Control.Applicative ((<$>),(<*>))
5−import Control.Monad
6−import Control.Arrow (second)
7−import Data.Map ((!))
8−import qualified Data.Map as Map
9−import qualified Data.List as List
10−import AST.Type
11−import AST.Module
12−
13−type Rules = (Aliases, CanonicalType -> CanonicalType)
14−
15−rules interfaces moduleAliases moduleImports = (Map.empty, id)
16− --(error "Type.Alias.rules is not defined")
17− --(collect interfaces moduleAliases, localizer moduleImports)
18−{--
19−collect interfaces moduleAliases =
20− filter (not . isPrimitive) rawAliases
21− where
22− rawAliases =
23− moduleAliases ++ concatMap iAliases (Map.elems interfaces)
24−
25− isPrimitive (_,_,tipe) =
26− case tipe of
27− Data _ [] -> True
28− _ -> False
29−--}
30−{--
31−localizer moduleImports = go
32− where
33− go tipe =
34− case tipe of
35− Var _ -> tipe
36− Lambda t1 t2 -> Lambda (go t1) (go t2)
37− Data name ts -> Data (localize name) (map go ts)
38− Record fs ext -> Record (map (second go) fs) ext
39−
40− byMethod = foldr (\(n,m) d -> Map.insertWith (++) n [m] d)
41− Map.empty moduleImports
42−
43− separate name =
44− case List.elemIndices '.' name of
45− [] -> ("",name)
46− is -> let i = last is in
47− (take i name, drop (i+1) name)
48−
49− shortest = List.minimumBy (\a b -> compare (length a) (length b))
50−
51− localize name = shortest (name : concatMap (localize' value) methods)
52− where (modul, value) = separate name
53− methods = Map.findWithDefault [] modul byMethod
54−
55− localize' name method =
56− case method of
57− As modul -> [modul ++ "." ++ name]
58− Hiding xs | name `notElem` xs -> [name]
59− Importing xs | name `elem` xs -> [name]
60− _ -> []
61−--}
62−realias :: Rules -> CanonicalType -> CanonicalType
63−realias (aliases,localize) tipe = tipe
64− -- (error "Type.Alias.realias is not defined")
65− -- localize (canonicalRealias aliases tipe)
66−
67−-- Realias using canonical aliases, so results will have aliases
68−-- that are fully qualified and possible to compare.
69−canonicalRealias :: Aliases -> CanonicalType -> CanonicalType
70−canonicalRealias aliases tipe = tipe
71−-- (error "Type.Alias.rules is not defined")
72−{--
73− case concatMap tryRealias aliases of
74− [] -> if tipe == tipe' then tipe else f tipe'
75− tipes -> f (bestType tipes)
76− where
77− tryRealias (name, args, aliasTipe) =
78− case diff aliasTipe tipe of
79− Nothing -> []
80− Just kvs ->
81− let holes = collectFields kvs
82− hasArgs = List.sort args == Map.keys holes
83− isConsistent = all allEqual (Map.elems holes)
84− in case hasArgs && isConsistent of
85− False -> []
86− True -> [Data name $ map (\arg -> head (holes ! arg)) args]
87−
88− f = canonicalRealias aliases
89− tipe' =
90− case tipe of
91− Var _ -> tipe
92− Lambda t1 t2 -> Lambda (f t1) (f t2)
93− Data name ts -> Data name (map f ts)
94− Record fs ext -> Record (map (second f) fs) ext
95−--}
96−
97−allEqual [] = True
98−allEqual (x:xs) = all (==x) xs
99−
100−{--
101−bestType tipes = fst $ List.minimumBy (\a b -> compare (snd a) (snd b)) pairs
102− where
103− pairs :: [(Type,Int)]
104− pairs = zip tipes (map numFields tipes)
105−
106− numFields :: Type -> Int
107− numFields tipe =
108− case tipe of
109− Lambda t1 t2 -> numFields t1 + numFields t2
110− Var _ -> 0
111− Data _ ts -> sum (map numFields ts)
112− Record fields _ -> length fields + sum (map (numFields . snd) fields)
113−
114−diff :: CanonicalType -> CanonicalType -> Maybe [(String,CanonicalType)]
115−diff general specific =
116− case (general, specific) of
117− (Lambda g1 g2, Lambda s1 s2) -> (++) <$> diff g1 s1 <*> diff g2 s2
118− (Var x, t) -> Just [(x,t)]
119− (Data gname gts, Data sname sts)
120− | gname == sname && length gts == length sts ->
121− concat <$> zipWithM diff gts sts
122− (Record [] Nothing, Record [] Nothing) -> Just []
123− (Record _ _, Record [] Nothing) -> Nothing
124− (Record [] Nothing, Record _ _) -> Nothing
125− (Record gfs gext, Record sfs sext) ->
126− let gfields = collectFields gfs
127− sfields = collectFields sfs
128−
129− overlap = Map.intersectionWith (\gs ss -> length gs == length ss) sfields gfields
130− isAligned = Map.size gfields == Map.size overlap && and (Map.elems overlap)
131− in
132− case isAligned of
133− False -> Nothing
134− True -> let remaining = Map.difference sfields gfields
135− sext' = case sext of
136− Just x | Map.null remaining -> Var x
137− _ -> Record (flattenFields remaining) sext
138− gext' = maybe (Record [] Nothing) Var gext
139− matchMap = Map.intersectionWith (zipWith diff) gfields sfields
140− in concat <$> sequence (diff gext' sext' : concat (Map.elems matchMap))
141− (_,_) -> Nothing
142−
143−collectFields fields =
144− foldr (\(f,t) fs -> Map.insertWith (++) f [t] fs) Map.empty fields
145−
146−flattenFields fields =
147− concatMap (\(f,ts) -> map ((,) f) ts) (Map.toList fields)
148−--}
compiler/Type/ExtraChecks.hs+12−14
@@ -21,17 +21,16 @@ import qualified AST.Variable as V
2121import qualified Transform.Expression as Expr
2222import qualified Type.Type as TT
2323import qualified Type.State as TS
24−import qualified Type.Alias as Alias
2524
2625throw :: [Doc] -> Either [Doc] a
2726throw err = Left [ P.vcat err ]
2827
29−mainType :: Alias.Rules -> TS.Env -> IO (Either [P.Doc] (Map.Map String ST.CanonicalType))
30−mainType aliasRules environment =
31− mainCheck aliasRules <$> Traverse.traverse TT.toSrcType environment
28+mainType :: TS.Env -> IO (Either [P.Doc] (Map.Map String ST.CanonicalType))
29+mainType environment =
30+ mainCheck <$> Traverse.traverse TT.toSrcType environment
3231 where
33− mainCheck :: Alias.Rules -> Map.Map String ST.CanonicalType -> Either [P.Doc] (Map.Map String ST.CanonicalType)
34− mainCheck rules env =
32+ mainCheck :: Map.Map String ST.CanonicalType -> Either [P.Doc] (Map.Map String ST.CanonicalType)
33+ mainCheck env =
3534 case Map.lookup "main" env of
3635 Nothing -> Right env
3736 Just typeOfMain
@@ -41,16 +40,16 @@ mainType aliasRules environment =
4140 acceptable = [ "Graphics.Element.Element"
4241 , "Signal.Signal Graphics.Element.Element" ]
4342
44− tipe = PP.renderPretty $ Alias.canonicalRealias (fst rules) typeOfMain
43+ tipe = PP.renderPretty typeOfMain
4544 err = [ P.text "Type Error: 'main' must have type Element or (Signal Element)."
4645 , P.text "Instead 'main' has type:\n"
47− , P.nest 4 . PP.pretty $ Alias.realias rules typeOfMain
46+ , P.nest 4 (PP.pretty typeOfMain)
4847 , P.text " " ]
4948
5049data Direction = In | Out
5150
52−portTypes :: Alias.Rules -> Canonical.Expr -> Either [P.Doc] ()
53−portTypes rules expr =
51+portTypes :: Canonical.Expr -> Either [P.Doc] ()
52+portTypes expr =
5453 const () <$> Expr.checkPorts (check In) (check Out) expr
5554 where
5655 check = isValid True False False
@@ -111,7 +110,7 @@ portTypes rules expr =
111110 [ txt [ "Type Error: the value ", dir "coming in" "sent out"
112111 , " through port '", name, "' is invalid." ]
113112 , txt [ "It contains ", kind, ":\n" ]
114− , (P.nest 4 . PP.pretty $ Alias.realias rules tipe) <> P.text "\n"
113+ , P.nest 4 (PP.pretty tipe) <> P.text "\n"
115114 , txt [ "Acceptable values for ", dir "incoming" "outgoing", " ports include:" ]
116115 , txt [ " Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples," ]
117116 , txt [ " Json.Values, ", dir "" "first-order functions, ", "and concrete records." ]
@@ -131,17 +130,16 @@ occurs (name, variable) =
131130 desc <- liftIO $ UF.descriptor var
132131 case TT.structure desc of
133132 Nothing ->
134− modify $ \s -> s { TS.sErrors = fallback : TS.sErrors s }
133+ modify $ \s -> s { TS.sErrors = P.text msg : TS.sErrors s }
135134 Just _ ->
136135 do liftIO $ UF.setDescriptor var (desc { TT.structure = Nothing })
137136 var' <- liftIO $ UF.fresh desc
138137 TS.addError (A.None (P.text name)) (Just msg) var var'
139138 where
140139 msg = "Infinite types are not allowed"
141− fallback _ = return $ P.text msg
142140
143141 infiniteVars :: [TT.Variable] -> TT.Variable -> IO [TT.Variable]
144− infiniteVars seen var =
142+ infiniteVars seen var =
145143 let go = infiniteVars (var:seen) in
146144 if var `elem` seen
147145 then return [var]
compiler/Type/Inference.hs+3−5
@@ -18,7 +18,6 @@ import qualified Type.ExtraChecks as Check
1818import Control.Arrow (first, second)
1919import Control.Monad.State (execStateT, forM)
2020import Control.Monad.Error (ErrorT, runErrorT, liftIO)
21−import qualified Type.Alias as Alias
2221
2322import System.IO.Unsafe -- Possible to switch over to the ST monad instead of
2423 -- the IO monad. I don't think that'd be worthwhile.
@@ -49,12 +48,11 @@ infer interfaces modul = unsafePerformIO $ do
4948 Left err -> return $ Left err
5049 Right (header, constraint) -> do
5150 state <- execStateT (Solve.solve constraint) TS.initialState
52− let rules = Alias.rules interfaces (aliases moduleBody) (imports modul)
5351 case TS.sErrors state of
54− errors@(_:_) -> Left `fmap` sequence (map ($ rules) (reverse errors))
55− [] -> case Check.portTypes rules (program moduleBody) of
52+ errors@(_:_) -> return (Left errors)
53+ [] -> case Check.portTypes (program moduleBody) of
5654 Left err -> return (Left err)
57− Right () -> Check.mainType rules types
55+ Right () -> Check.mainType types
5856 where
5957 header' = Map.delete "::" header
6058 types = Map.difference (TS.sSavedEnv state) header'
compiler/Type/State.hs+8−7
@@ -10,7 +10,6 @@ import qualified Data.UnionFind.IO as UF
1010import qualified AST.Annotation as A
1111import AST.PrettyPrint
1212import Text.PrettyPrint as P
13−import qualified Type.Alias as Alias
1413import Type.Type
1514
1615-- Pool
@@ -33,7 +32,7 @@ data SolverState = SS {
3332 sSavedEnv :: Env,
3433 sPool :: Pool,
3534 sMark :: Int,
36− sErrors :: [Alias.Rules -> IO P.Doc]
35+ sErrors :: [P.Doc]
3736}
3837
3938initialState = SS {
@@ -47,13 +46,15 @@ initialState = SS {
4746modifyEnv f = modify $ \state -> state { sEnv = f (sEnv state) }
4847modifyPool f = modify $ \state -> state { sPool = f (sPool state) }
4948
49+addError :: A.Region -> Maybe String -> UF.Point Descriptor -> UF.Point Descriptor
50+ -> StateT SolverState IO ()
5051addError region hint t1 t2 =
51− modify $ \state -> state { sErrors = makeError : sErrors state }
52+ do err <- liftIO makeError
53+ modify $ \state -> state { sErrors = err : sErrors state }
5254 where
53− makeError rules = do
54− let prettiest = pretty . Alias.realias rules
55− t1' <- prettiest <$> toSrcType t1
56− t2' <- prettiest <$> toSrcType t2
55+ makeError = do
56+ t1' <- pretty <$> toSrcType t1
57+ t2' <- pretty <$> toSrcType t2
5758 return . P.vcat $
5859 [ P.text "Type error" <+> pretty region <> P.colon
5960 , maybe P.empty P.text hint