on master help sign in
Fix prelude imports and correctly generalize for library types that use `Number`.
commit703508f1c358bb3de3e6430d05408016c0d0fba1 authorevancz <info@elm-lang.org> dateSun 7 Apr 2013, 17:55 (14 years ago) parentebb570d
6 files changed+89−41
compiler/Model/Guid.hs+3−1 compiler/Model/Libraries.hs+4−3 compiler/Types/Constrain.hs+13−14 compiler/Types/Hints.hs+8−8 compiler/Types/Substitutions.hs+59−12 compiler/Types/Types.hs+2−3
compiler/Model/Guid.hs+3−1
@@ -1,5 +1,5 @@
11{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−module Guid (guid, run, runAt, GuidCounter) where
2+module Guid (guid, set, run, runAt, GuidCounter) where
33
44import Control.Monad.State (evalState, State, get, put)
55
@@ -13,5 +13,7 @@ guid = GC $ do n <- get
1313 put (n + 1)
1414 return n
1515
16+set n = GC (put n)
17+
1618run = runAt 0
1719runAt n x = evalState (runGC x) n
compiler/Model/Libraries.hs+4−3
@@ -1,4 +1,4 @@
1−module Libraries (libraries, addPrelude, prelude) where
1+module Libraries (libraries, addPrelude) where
22
33import Ast
44import qualified Data.Map as Map
@@ -11,8 +11,9 @@ addPrelude (Module name exs ims stmts) = Module name exs (customIms ++ ims) stmt
1111 where customIms = concatMap addModule prelude
1212
1313 addModule (n, method) = case lookup n ims of
14− Nothing -> [(n, method)]
15− Just _ -> []
14+ Nothing -> [(n, method)]
15+ Just (As m) -> [(n, method)]
16+ Just _ -> []
1617
1718prelude = text : map (\n -> (n, Hiding [])) modules
1819 where
compiler/Types/Constrain.hs+13−14
@@ -12,7 +12,6 @@ import qualified Data.Set as Set
1212import Ast
1313import Context
1414import Guid
15−import qualified Libraries as Libraries
1615
1716import Types.Types
1817import Types.Substitutions
@@ -21,12 +20,11 @@ beta = VarT `liftM` guid
2120unionA = Map.unionWith (++)
2221unionsA = Map.unionsWith (++)
2322
24−getAliases imports hints = hints ++ concatMap aliasesFrom imports
23+getAliases imports hints = concatMap aliasesFrom imports
2524 where aliasesFrom (name,method) =
2625 let values = concatMap (getValue name) hints
2726 in case method of
28− As alias -> if alias == name then [] else
29− map (\(n,t) -> (alias ++ "." ++ n, t)) values
27+ As alias -> map (\(n,t) -> (alias ++ "." ++ n, t)) values
3028 Hiding vs -> filter (\(n,t) -> n `notElem` vs) values
3129 Importing vs -> filter (\(n,t) -> n `elem` vs) values
3230 getValue inModule (name,tipe) =
@@ -34,13 +32,15 @@ getAliases imports hints = hints ++ concatMap aliasesFrom imports
3432 True -> [ (drop (length inModule + 1) name, tipe) ]
3533 False -> []
3634
37−findAmbiguous hints hints' assumptions continue =
38− let potentialDups = map head . filter (\g -> length g > 1) . group $ sort hints'
39− dups = filter (\k -> Map.member k assumptions) potentialDups
40− in case dups of
41− n:_ -> return . Left $ "Error: Ambiguous occurrence of '" ++ n ++
42− "' could refer to " ++ intercalate ", " (filter (isSuffixOf n) hints)
43− _ -> continue
35+findAmbiguous hints assumptions continue =
36+ let potentialDups = map head . filter (\g -> length g > 1) . group . sort $
37+ filter (elem '.') hints
38+ dups = filter (\k -> Map.member k assumptions) potentialDups
39+ in case dups of
40+ n:_ -> return . Left $ "Error: Ambiguous occurrence of '" ++ n ++
41+ "' could refer to " ++
42+ intercalate ", " (filter (isSuffixOf n) hints)
43+ _ -> continue
4444
4545mergeSchemes :: [Map.Map String Scheme]
4646 -> GuidCounter (TVarMap, ConstraintSet, Map.Map String Scheme)
@@ -61,15 +61,14 @@ mergeSchemes schmss = do (ass,css,sss) <- unzip3 `liftM` mapM split kvs
6161
6262constrain typeHints (Module _ _ imports stmts) = do
6363 (ass,css,schemess) <- unzip3 `liftM` mapM stmtGen stmts
64− hints <- typeHints
64+ aliasHints <- getAliases imports `liftM` typeHints
6565 (as', cs', schemes) <- mergeSchemes schemess
6666 let constraints = Set.unions (cs':css)
6767 as = unionsA (as':ass)
68− aliasHints = getAliases (imports ++ Libraries.prelude) hints
6968 allHints = Map.union schemes (Map.fromList aliasHints)
7069 insert as n = do v <- guid; return $ Map.insertWith' (\_ x -> x) n [v] as
7170 assumptions <- foldM insert as (Map.keys schemes)
72− findAmbiguous (map fst hints) (map fst aliasHints) assumptions $ do
71+ findAmbiguous (map fst aliasHints) assumptions $ do
7372 let f k s vs = map (\v -> C (Just k) NoSpan $ v :<<: s) vs
7473 cs = concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
7574 escapees = Map.keys $ Map.difference assumptions allHints
compiler/Types/Hints.hs+8−8
@@ -11,11 +11,11 @@ import Types.Types
1111
1212hints :: GuidCounter [(String, Scheme)]
1313hints = mapM toScheme values
14− where
15− addPrefixes = concatMap (\(m,vs) -> map (first (\n -> m ++ "." ++ n)) vs)
16− values = addPrefixes (Map.toList (Map.map Map.toList libraries))
17− toScheme (name, tipeString) =
18− case iParse (fmap toType typeExpr) "parsing types in docs.json" tipeString of
19− Left err -> error (show err)
20− Right tipe -> do scheme <- generalize [] (Forall [] [] tipe)
21− return (name, scheme)
14+ where
15+ addPrefixes = concatMap (\(m,vs) -> map (first (\n -> m ++ "." ++ n)) vs)
16+ values = addPrefixes (Map.toList (Map.map Map.toList libraries))
17+ toScheme (name, tipeString) =
18+ case iParse (fmap toType typeExpr) "parsing types in docs.json" tipeString of
19+ Left err -> error (show err)
20+ Right tipe -> do scheme <- generalize [] =<< superize name tipe
21+ return (name, scheme)
compiler/Types/Substitutions.hs+59−12
@@ -1,20 +1,22 @@
1−
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
22module Types.Substitutions (subst,
33 occurs,
44 freeVars,
55 concretize,
66 rescheme,
7− generalize) where
7+ generalize,
8+ superize) where
89
910import Ast
1011import Context
11−import Control.DeepSeq (NFData (..), deepseq)
12−import Control.Monad (liftM)
12+import Control.Monad (liftM, liftM2)
13+import Control.Monad.State (runState, State, get, put)
1314import Data.List (foldl')
15+import Data.Maybe (catMaybes)
1416import qualified Data.Set as Set
1517import qualified Data.Map as Map
1618import Guid
17−import Types.Types
19+import Types.Types as Types
1820
1921class Subst a where
2022 subst :: [(X,Type)] -> a -> a
@@ -51,13 +53,14 @@ class FreeVars a where
5153 freeVars :: a -> [X]
5254
5355instance FreeVars Type where
54− freeVars (VarT v) = [v]
55− freeVars (LambdaT t1 t2) = freeVars t1 ++ freeVars t2
56− freeVars (ADT _ ts) = concatMap freeVars ts
57− freeVars (RecordT fs t) =
58− freeVars (concat $ Map.elems fs) ++ freeVars t
59− freeVars EmptyRecord = []
60− freeVars (Super _ ) = []
56+ freeVars t =
57+ case t of
58+ VarT v -> [v]
59+ LambdaT t1 t2 -> freeVars t1 ++ freeVars t2
60+ ADT _ ts -> concatMap freeVars ts
61+ RecordT fs t -> freeVars (concat $ Map.elems fs) ++ freeVars t
62+ EmptyRecord -> []
63+ Super _ -> []
6164
6265instance FreeVars Constraint where
6366 freeVars (t1 :=: t2) = freeVars t1 ++ freeVars t2
@@ -88,3 +91,47 @@ generalize :: [X] -> Scheme -> GuidCounter Scheme
8891generalize exceptions (Forall xs cs t) = rescheme (Forall (xs ++ frees) cs t)
8992 where allFrees = Set.fromList $ freeVars t ++ concatMap freeVars cs
9093 frees = Set.toList $ Set.difference allFrees (Set.fromList exceptions)
94+
95+newtype Superize a = S { runSuper :: State (Int, Maybe X, Maybe X) a }
96+ deriving (Monad)
97+
98+superize :: String -> Type -> GuidCounter Scheme
99+superize name tipe =
100+ do x <- guid
101+ let (tipe', (m, number, append)) =
102+ runState (runSuper (go tipe)) (x+1, Nothing, Nothing)
103+ mkC super = liftM (\x -> C (Just name) NoSpan (VarT x :<: super))
104+ set m
105+ return (Forall (catMaybes [number,append])
106+ (catMaybes [ mkC Types.number number
107+ , mkC (Types.appendable x) append])
108+ tipe')
109+ where
110+ go :: Type -> Superize Type
111+ go t =
112+ case t of
113+ EmptyRecord -> return t
114+ Super _ -> return t
115+ VarT _ -> return t
116+ LambdaT t1 t2 -> liftM2 LambdaT (go t1) (go t2)
117+ ADT "Number" [] -> liftM VarT number
118+ ADT "Appendable" [] -> liftM VarT append
119+ ADT name ts -> liftM (ADT name) (mapM go ts)
120+ RecordT fs t -> liftM2 RecordT fs' (go t)
121+ where pairs = Map.toList fs
122+ fs' = do ps <- mapM (\(f,t) -> liftM ((,) f) (mapM go t)) pairs
123+ return (Map.fromList ps)
124+
125+ number :: Superize X
126+ number = S $ do (n, num, append) <- get
127+ case num of
128+ Just x -> return x
129+ Nothing -> do put (n + 1, Just n, append)
130+ return n
131+
132+ append :: Superize X
133+ append = S $ do (n, number, app) <- get
134+ case app of
135+ Just x -> return x
136+ Nothing -> do put (n + 1, number, Just n)
137+ return n
compiler/Types/Types.hs+2−3
@@ -39,9 +39,8 @@ number = Super (Set.fromList [ int, float ])
3939
4040char = tipe "Char"
4141bool = tipe "Bool"
42−
42+text = tipe "Text"
4343string = tipe "String"
44−text = tipe "Text"
4544
4645element = tipe "Element"
4746
@@ -52,7 +51,7 @@ maybeOf t = ADT "Maybe" [t]
5251eitherOf a b = ADT "Either" [a,b]
5352pairOf t = tupleOf [t,t]
5453point = pairOf int
55−appendable t = Super (Set.fromList [ string, text, listOf t ])
54+appendable t = Super (Set.fromList [ string, text, listOf (VarT t) ])
5655--comparable = Super (Set.fromList [ int, float, char, string, time, date ])
5756
5857infixr ==>