on master help sign in
Change functions for creating type variables, distinguish names of different constraint type variables
commit9fe6c9a564d090e4d639b6e5c0436cd3acd56ee3 authorEvan Czaplicki <info@elm-lang.org> dateThu 25 Jul 2013, 18:07 (13 years ago) parent642b1f7
9 files changed+64−68
compiler/Type/Constrain/Expression.hs+12−12 compiler/Type/Constrain/Literal.hs+1−1 compiler/Type/Constrain/Pattern.hs+2−2 compiler/Type/Environment.hs+7−7 compiler/Type/Inference.hs+2−2 compiler/Type/Solve.hs+1−1 compiler/Type/State.hs+1−1 compiler/Type/Type.hs+25−29 compiler/Type/Unify.hs+13−13
compiler/Type/Constrain/Expression.hs+12−12
@@ -33,10 +33,10 @@ test str =
3333 Left err -> error $ "Parse error at " ++ show err
3434 Right expression -> do
3535 env <- Env.initialEnvironment []
36− var <- flexibleVar
36+ v <- var Flexible
3737 let expr = SD.sortDefs expression
3838 print (pretty expr)
39− constraint <- constrain env expr (VarN var)
39+ constraint <- constrain env expr (VarN v)
4040 print =<< extraPretty constraint
4141 state <- execStateT (solve constraint) TS.initialState
4242 let errors = TS.sErrors state
@@ -110,7 +110,7 @@ constrain env (L _ _ expr) tipe =
110110 (ctipe, cs) <- Monad.foldM step (tipe,CTrue) (reverse pairs)
111111 return (cs /\ name <? ctipe)
112112 where
113− pair e = do v <- flexibleVar -- needs an ex
113+ pair e = do v <- var Flexible -- needs an ex
114114 return (e, VarN v)
115115
116116 step (t,c) (e,x) = do
@@ -142,11 +142,11 @@ constrain env (L _ _ expr) tipe =
142142 return (CAnd (cOld : cNew : constraints))
143143 where
144144 dummyField (label, _) = do
145− v <- flexibleVar -- needs an ex
145+ v <- var Flexible -- needs an ex
146146 return (label, [VarN v])
147147
148148 field (label, value) = do
149− v <- flexibleVar -- needs an ex
149+ v <- var Flexible -- needs an ex
150150 c <- ex [v] <$> constrain env value (VarN v)
151151 return ((label, [VarN v]), c)
152152
@@ -157,7 +157,7 @@ constrain env (L _ _ expr) tipe =
157157 return $ ex (map snd pairs) (CAnd (tipe === recordType : cs))
158158 where
159159 field (name, body) = do
160− v <- flexibleVar -- needs an ex
160+ v <- var Flexible -- needs an ex
161161 c <- constrain env body (VarN v)
162162 return ((name, v), c)
163163
@@ -182,7 +182,7 @@ constrainDef env info (pattern, expr, maybeTipe) =
182182 in
183183 case (pattern, maybeTipe) of
184184 (PVar name, Just tipe) ->
185− do flexiVars <- mapM (\_ -> flexibleVar) qs
185+ do flexiVars <- mapM (\_ -> var Flexible) qs
186186 let inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs flexiVars
187187 env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
188188 (vars, typ) <- Env.instantiateTypeWithContext env tipe Map.empty
@@ -199,16 +199,16 @@ constrainDef env info (pattern, expr, maybeTipe) =
199199 , fl rigidQuantifiers c /\ c1 )
200200
201201 (PVar name, Nothing) ->
202− do var <- flexibleVar
203− rigidVars <- mapM (\_ -> rigidVar) qs -- Some mistake may be happening here.
204− -- Currently, qs is always the empty list.
205− let tipe = VarN var
202+ do v <- var Flexible
203+ rigidVars <- mapM (\_ -> var Rigid) qs -- Some mistake may be happening here.
204+ -- Currently, qs is always the empty list.
205+ let tipe = VarN v
206206 inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs rigidVars
207207 env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
208208 c <- constrain env' expr tipe
209209 return ( schemes
210210 , rigidVars ++ rigidQuantifiers
211− , var : flexibleQuantifiers
211+ , v : flexibleQuantifiers
212212 , Map.insert name tipe headers
213213 , c /\ c2
214214 , c1 )
compiler/Type/Constrain/Literal.hs+1−1
@@ -12,7 +12,7 @@ constrain :: Environment -> Literal -> Type -> IO TypeConstraint
1212constrain env literal tipe =
1313 let prim name = Env.get env Env.types name in
1414 case literal of
15− IntNum _ -> fmap (\n -> tipe === VarN n) number
15+ IntNum _ -> fmap (\n -> tipe === VarN n) (var (Is Number))
1616 FloatNum _ -> return $ tipe === prim "Float"
1717 Chr _ -> return $ tipe === prim "Char"
1818 Str _ -> return $ tipe === TermN (App1 (prim "_List") (prim "Char"))
compiler/Type/Constrain/Pattern.hs+2−2
@@ -25,7 +25,7 @@ constrain env pattern tipe =
2525 return $ emptyFragment { typeConstraint = c }
2626
2727 PVar name -> do
28− v <- flexibleVar
28+ v <- var Flexible
2929 return $ Fragment {
3030 typeEnv = Map.singleton name (VarN v),
3131 vars = [v],
@@ -52,7 +52,7 @@ constrain env pattern tipe =
5252 }
5353
5454 PRecord fields -> do
55− pairs <- mapM (\name -> (,) name <$> flexibleVar) fields
55+ pairs <- mapM (\name -> (,) name <$> var Flexible) fields
5656 let tenv = Map.fromList (map (second VarN) pairs)
5757 c <- exists $ \t -> return (tipe === record (Map.map (:[]) tenv) t)
5858 return $ Fragment {
compiler/Type/Environment.hs+7−7
@@ -66,10 +66,10 @@ makeConstructors types = Map.fromList builtins
6666 let (args, result) = tipe (map VarN vars)
6767 return (length args, vars, args, result)
6868
69− inst = instance' flexibleVar
70− nmbr = instance' number 1
71− cmpr = instance' comparable 1
72− apnd = instance' appendable 1
69+ inst = instance' (var Flexible)
70+ nmbr = instance' (var (Is Number)) 1
71+ cmpr = instance' (var (Is Comparable)) 1
72+ apnd = instance' (var (Is Appendable)) 1
7373
7474 tupleCtor n =
7575 let name = "_Tuple" ++ show n
@@ -132,9 +132,9 @@ instantiateTypeWithContext env sourceType dict =
132132 State.put (Map.insert x var dict)
133133 return (VarN var)
134134 where
135− flex | "number" `isPrefixOf` x = IsIn Number
136− | "comparable" `isPrefixOf` x = IsIn Comparable
137− | "appendable" `isPrefixOf` x = IsIn Appendable
135+ flex | "number" `isPrefixOf` x = Is Number
136+ | "comparable" `isPrefixOf` x = Is Comparable
137+ | "appendable" `isPrefixOf` x = Is Appendable
138138 | otherwise = Flexible
139139
140140 Src.Data name ts -> do
compiler/Type/Inference.hs+2−2
@@ -29,7 +29,6 @@ infer interfaces' modul = unsafePerformIO $ do
2929-- mapM print (concatMap iAdts (Map.elems interfaces))
3030
3131 env <- Env.initialEnvironment (datatypes modul ++ concatMap iAdts (Map.elems interfaces))
32− var <- T.flexibleVar
3332 ctors <- forM (Map.keys (Env.constructor env)) $ \name ->
3433 do (_, vars, args, result) <- Env.freshDataScheme env name
3534 return (name, (vars, foldr (T.==>) result args))
@@ -55,7 +54,8 @@ infer interfaces' modul = unsafePerformIO $ do
5554 header = Map.map snd (Map.fromList allTypes)
5655 environ = T.CLet [ T.Scheme vars [] T.CTrue header ]
5756
58− constraint <- environ `fmap` TcExpr.constrain env (program modul) (T.VarN var)
57+ fvar <- T.var T.Flexible
58+ constraint <- environ `fmap` TcExpr.constrain env (program modul) (T.VarN fvar)
5959 --print =<< T.extraPretty constraint
6060
6161 state <- execStateT (Solve.solve constraint) TS.initialState
compiler/Type/Solve.hs+1−1
@@ -123,7 +123,7 @@ solve constraint =
123123 case Map.lookup name env of
124124 Just tipe -> TS.makeInstance tipe
125125 Nothing
126− | List.isPrefixOf "Native." name -> liftIO flexibleVar
126+ | List.isPrefixOf "Native." name -> liftIO (var Flexible)
127127 | otherwise ->
128128 error ("Could not find '" ++ name ++ "' when solving type constraints.")
129129
compiler/Type/State.hs+1−1
@@ -138,7 +138,7 @@ makeCopy alreadyCopied variable = do
138138 rank = maxRank pool,
139139 mark = noMark,
140140 flex = case flex desc of
141− IsIn s -> IsIn s
141+ Is s -> Is s
142142 _ -> Flexible,
143143 copy = Nothing,
144144 name = case flex desc of
compiler/Type/Type.hs+25−29
@@ -88,16 +88,12 @@ outermostRank = 0 :: Int
8888noMark = 0
8989initialMark = 1
9090
91−data Flex = Rigid | Flexible | Constant | IsIn SuperType
91+data Flex = Rigid | Flexible | Constant | Is SuperType
9292 deriving (Show, Eq)
9393
9494data SuperType = Number | Comparable | Appendable
9595 deriving (Show, Eq)
9696
97−number = namedVar (IsIn Number) "number"
98−comparable = namedVar (IsIn Comparable) "comparable"
99−appendable = namedVar (IsIn Appendable) "appendable"
100−
10197namedVar flex name = UF.fresh $ Descriptor {
10298 structure = Nothing,
10399 rank = noRank,
@@ -107,23 +103,15 @@ namedVar flex name = UF.fresh $ Descriptor {
107103 mark = noMark
108104 }
109105
110−flexibleVar = UF.fresh $ Descriptor {
106+var flex = UF.fresh $ Descriptor {
111107 structure = Nothing,
112108 rank = noRank,
113− flex = Flexible,
109+ flex = flex,
114110 name = Nothing,
115111 copy = Nothing,
116112 mark = noMark
117113 }
118114
119−rigidVar = UF.fresh $ Descriptor {
120− structure = Nothing,
121− rank = noRank,
122− flex = Rigid,
123− name = Nothing,
124− copy = Nothing,
125− mark = noMark
126− }
127115
128116-- ex qs constraint == exists qs. constraint
129117ex :: [Variable] -> TypeConstraint -> TypeConstraint
@@ -135,7 +123,7 @@ fl rqs constraint = CLet [Scheme rqs [] constraint Map.empty] CTrue
135123
136124exists :: (Type -> IO TypeConstraint) -> IO TypeConstraint
137125exists f = do
138− v <- flexibleVar
126+ v <- var Flexible
139127 ex [v] <$> f (VarN v)
140128
141129
@@ -252,31 +240,39 @@ extraPretty t = pretty Never <$> addNames t
252240
253241addNames :: (Crawl t) => t -> IO t
254242addNames value = do
255− (_, rawVars) <- runStateT (crawl getNames value) []
243+ (rawVars, _, _, _) <- execStateT (crawl getNames value) ([], 0, 0, 0)
256244 let vars = map head . List.group $ List.sort rawVars
257245 suffix s = map (++s) (map (:[]) ['a'..'z'])
258246 allVars = concatMap suffix $ ["","'","_"] ++ map show [0..]
259247 okayVars = filter (`notElem` vars) allVars
260− runStateT (crawl rename value) okayVars
248+ runStateT (crawl rename value) (okayVars, 0, 0, 0)
261249 return value
262250 where
263− getNames name vars =
264− case name of
265− Just var -> (name, var:vars)
266− Nothing -> (name, vars)
251+ getNames desc state@(vars, a, b, c) =
252+ let name' = name desc in
253+ case name' of
254+ Just var -> (name', (var:vars, a, b, c))
255+ Nothing -> (name', state)
256+
257+ rename desc state@(vars, a, b, c) =
258+ case name desc of
259+ Just var -> (Just var, state)
260+ Nothing ->
261+ case flex desc of
262+ Is Number -> (Just $ "number" ++ replicate a '\'', (vars, a+1, b, c))
263+ Is Comparable -> (Just $ "comparable" ++ replicate b '\'', (vars, a, b+1, c))
264+ Is Appendable -> (Just $ "appendable" ++ replicate c '\'', (vars, a, b, c+1))
265+ _ -> (Just $ head vars, (tail vars, a, b, c))
267266
268− rename name vars =
269− case name of
270− Just var -> (name, vars)
271− Nothing -> (Just (head vars), tail vars)
272267
268+type CrawlState = ([String], Int, Int, Int)
273269
274270-- Code for traversing all the type data-structures and giving
275271-- names to the variables embedded deep in there.
276272class Crawl t where
277− crawl :: (Maybe TypeName -> [String] -> (Maybe TypeName, [String]))
273+ crawl :: (Descriptor -> CrawlState -> (Maybe TypeName, CrawlState))
278274 -> t
279− -> StateT [String] IO t
275+ -> StateT CrawlState IO t
280276
281277instance (Crawl t, Crawl v) => Crawl (Constraint t v) where
282278 crawl nextState constraint =
@@ -324,7 +320,7 @@ instance Crawl a => Crawl (UF.Point a) where
324320instance Crawl Descriptor where
325321 crawl nextState desc = do
326322 state <- get
327− let (name', state') = nextState (name desc) state
323+ let (name', state') = nextState desc state
328324 structure' <- traverse (crawl nextState) (structure desc)
329325 put state'
330326 return $ desc { name = name', structure = structure' }
compiler/Type/Unify.hs+13−13
@@ -23,9 +23,9 @@ actuallyUnify variable1 variable2 = do
2323 case (flex desc1, flex desc2) of
2424 (_, Flexible) -> Just name1
2525 (Flexible, _) -> Just name2
26− (IsIn Number, IsIn _) -> Just name1
27− (IsIn _, IsIn Number) -> Just name2
28− (IsIn _, IsIn _) -> Just name1
26+ (Is Number, Is _) -> Just name1
27+ (Is _, Is Number) -> Just name2
28+ (Is _, Is _) -> Just name1
2929 (_, _) -> Nothing
3030 (Just name1, _) -> Just name1
3131 (_, Just name2) -> Just name2
@@ -35,9 +35,9 @@ actuallyUnify variable1 variable2 = do
3535 flex' = case (flex desc1, flex desc2) of
3636 (f, Flexible) -> f
3737 (Flexible, f) -> f
38− (IsIn Number, IsIn _) -> IsIn Number
39− (IsIn _, IsIn Number) -> IsIn Number
40− (IsIn super, IsIn _) -> IsIn super
38+ (Is Number, Is _) -> Is Number
39+ (Is _, Is Number) -> Is Number
40+ (Is super, Is _) -> Is super
4141 (_, _) -> Flexible
4242
4343 rank' :: Int
@@ -73,24 +73,24 @@ actuallyUnify variable1 variable2 = do
7373
7474 superUnify =
7575 case (flex desc1, flex desc2, name desc1, name desc2) of
76− (IsIn super1, IsIn super2, _, _)
76+ (Is super1, Is super2, _, _)
7777 | super1 == super2 -> merge
78− (IsIn Number, IsIn Comparable, _, _) -> merge1
79− (IsIn Comparable, IsIn Number, _, _) -> merge2
78+ (Is Number, Is Comparable, _, _) -> merge1
79+ (Is Comparable, Is Number, _, _) -> merge2
8080
81− (IsIn Number, _, _, Just name)
81+ (Is Number, _, _, Just name)
8282 | name `elem` ["Int","Float"] -> flexAndUnify variable1
8383 | otherwise -> TS.addError "Expecting a number (Int or Float)" variable1 variable2
8484
85− (_, IsIn Number, Just name, _)
85+ (_, Is Number, Just name, _)
8686 | name `elem` ["Int","Float"] -> flexAndUnify variable2
8787 | otherwise -> TS.addError "Expecting a number (Int or Float)" variable1 variable2
8888
89− (IsIn Comparable, _, _, Just name)
89+ (Is Comparable, _, _, Just name)
9090 | name `elem` ["Int","Float","Char"] -> flexAndUnify variable1
9191 | otherwise -> TS.addError "Expecting something comparable (Int, Float, Char, [comparable])." variable1 variable2
9292
93− (_, IsIn Comparable, Just name, _)
93+ (_, Is Comparable, Just name, _)
9494 | name `elem` ["Int","Float","Char"] -> flexAndUnify variable2
9595 | otherwise -> TS.addError "Expecting something comparable (Int, Float, Char, [comparable])." variable1 variable2
9696