on master help sign in
Provide a way to define super-types in type annotations. Should not be used outside of core libraries.
commit7d03f69f8c1e8c0cf2702c933855be60148b3dbc authorevancz <info@elm-lang.org> dateTue 9 Apr 2013, 19:50 (14 years ago) parentcf2357f
5 files changed+48−42
compiler/Types/Constrain.hs+3−3 compiler/Types/Hints.hs+8−6 compiler/Types/Solver.hs+3−2 compiler/Types/Substitutions.hs+27−28 compiler/Types/Types.hs+7−3
compiler/Types/Constrain.hs+3−3
@@ -14,7 +14,7 @@ import Context
1414import Guid
1515
1616import Types.Types
17−import Types.Substitutions
17+import qualified Types.Substitutions as Subs
1818
1919beta = VarT `liftM` guid
2020unionA = Map.unionWith (++)
@@ -283,7 +283,7 @@ defGenHelp name args e = do
283283 let as' = Map.findWithDefault [v] arg as
284284 return $ map (\y -> ctx arg NoSpan $ VarT x :=: VarT y) as'
285285 cs' <- concat `liftM` mapM genCs argDict
286− scheme <- generalize (concat $ Map.elems as') $
286+ scheme <- Subs.generalize (concat $ Map.elems as') $
287287 Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
288288 return ( as', Set.empty, (name, scheme) )
289289
@@ -312,7 +312,7 @@ stmtGen stmt =
312312 , Map.singleton elm (Forall [] [] tipe) )
313313
314314 TypeAnnotation name tipe ->
315− do schm <- generalize [] (Forall [] [] tipe)
315+ do schm <- Subs.generalize [] =<< Subs.superize name tipe
316316 return (Map.empty, Set.empty, Map.singleton name schm)
317317
318318 TypeAlias _ _ _ -> return (Map.empty, Set.empty, Map.empty)
compiler/Types/Hints.hs+8−6
@@ -3,22 +3,24 @@ module Types.Hints (hints) where
33import Control.Arrow (first)
44import qualified Data.Map as Map
55import Guid
6−import Libraries
6+import qualified Libraries as Libs
77import Parse.Library (iParse)
88import Parse.Types
9−import Types.Substitutions
9+import qualified Types.Substitutions as Subs
1010import Types.Types
1111
1212hints :: GuidCounter [(String, Scheme)]
1313hints = mapM toScheme values
1414 where
15+ values :: [(String, String)]
16+ values = addPrefixes (Map.toList (Map.map Map.toList Libs.libraries))
1517
16− values = addPrefixes (Map.toList (Map.map Map.toList libraries))
17−
18+ addPrefixes :: [(String,[(String, String)])] -> [(String, String)]
1819 addPrefixes = concatMap (\(m,vs) -> map (first (\n -> m ++ "." ++ n)) vs)
1920
21+ toScheme :: (String, String) -> GuidCounter (String, Scheme)
2022 toScheme (name, tipeString) =
2123 case iParse (fmap toType typeExpr) "parsing types in docs.json" tipeString of
2224 Left err -> error (show err)
23− Right tipe -> do scheme <- generalize [] =<< superize name tipe
24− return (name, scheme)
25+ Right tipe -> do scheme <- Subs.generalize [] =<< Subs.superize name tipe
26+ return (name, scheme)
compiler/Types/Solver.hs+3−2
@@ -161,12 +161,13 @@ solver aliases subs (C txt span c : cs) =
161161 | any f (Set.toList ts) -> solv cs
162162 | otherwise -> subtypeError txt span (ADT "List" [t]) (Super ts)
163163 where f (ADT "List" [VarT _]) = True
164− f (ADT "List" [t']) = t == t'
164+ f (ADT "List" [t']) = dealias aliases t == t'
165165 f _ = False
166166
167167 t :<: Super ts
168168 | Set.member t ts -> solv cs
169− | otherwise -> subtypeError txt span t (Super ts)
169+ | Set.member (dealias aliases t) ts -> solv cs
170+ | otherwise -> subtypeError txt span t (Super ts)
170171
171172 x :<<: s
172173 | any (occurs x) cs ->
compiler/Types/Substitutions.hs+27−28
@@ -11,12 +11,11 @@ import Ast
1111import Context
1212import Control.Monad (liftM, liftM2)
1313import Control.Monad.State (runState, State, get, put)
14−import Data.List (foldl')
15−import Data.Maybe (catMaybes)
14+import Data.List (nub)
1615import qualified Data.Set as Set
1716import qualified Data.Map as Map
1817import Guid
19−import Types.Types as Types
18+import Types.Types
2019
2120class Subst a where
2221 subst :: [(X,Type)] -> a -> a
@@ -92,21 +91,25 @@ generalize exceptions (Forall xs cs t) = rescheme (Forall (xs ++ frees) cs t)
9291 where allFrees = Set.fromList $ freeVars t ++ concatMap freeVars cs
9392 frees = Set.toList $ Set.difference allFrees (Set.fromList exceptions)
9493
95−newtype Superize a = S { runSuper :: State (Int, Maybe X, Maybe X) a }
94+newtype Superize a = S { runSuper :: State ([X], [X], [X]) a }
9695 deriving (Monad)
9796
9897superize :: String -> Type -> GuidCounter Scheme
9998superize 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')
99+ do constraints <- liftM concat $
100+ sequence [ mapM (<: nmbr) (nub ns)
101+ , mapM (<: apnd) (nub as)
102+ , mapM (<: comp) (nub cs) ]
103+ return (Forall (concat [ns,as,cs]) constraints tipe')
109104 where
105+ (tipe', (ns,as,cs)) = runState (runSuper (go tipe)) ([],[],[])
106+ t <: super = do x <- guid
107+ return $ C (Just name) NoSpan (VarT t :<: super x)
108+
109+ nmbr t = number
110+ apnd t = appendable t
111+ comp t = comparable t
112+
110113 go :: Type -> Superize Type
111114 go t =
112115 case t of
@@ -114,24 +117,20 @@ superize name tipe =
114117 Super _ -> return t
115118 VarT _ -> return t
116119 LambdaT t1 t2 -> liftM2 LambdaT (go t1) (go t2)
117− ADT "Number" [] -> liftM VarT number
118− ADT "Appendable" [t] -> liftM VarT append
120+ ADT "Number" [VarT t] -> addNumber t
121+ ADT "Appendable" [VarT t] -> addAppendable t
122+ ADT "Comparable" [VarT t] -> addComparable t
119123 ADT name ts -> liftM (ADT name) (mapM go ts)
120124 RecordT fs t -> liftM2 RecordT fs' (go t)
121125 where pairs = Map.toList fs
122126 fs' = do ps <- mapM (\(f,t) -> liftM ((,) f) (mapM go t)) pairs
123127 return (Map.fromList ps)
124128
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
129+ add :: (X -> ([X],[X],[X]) -> ([X],[X],[X])) -> X -> Superize Type
130+ add f v = S $ do (ns, as, cs) <- get
131+ put $ f v (ns, as, cs)
132+ return (VarT v)
133+
134+ addNumber = add (\n (ns,as,cs) -> (n:ns,as,cs))
135+ addAppendable = add (\a (ns,as,cs) -> (ns,a:as,cs))
136+ addComparable = add (\c (ns,as,cs) -> (ns,as,c:cs))
compiler/Types/Types.hs+7−3
@@ -35,13 +35,19 @@ tipe t = ADT t []
3535
3636int = tipe "Int"
3737float = tipe "Float"
38−number = Super (Set.fromList [ int, float ])
38+time = tipe "Time"
39+date = tipe "Date"
3940
4041char = tipe "Char"
4142bool = tipe "Bool"
4243text = tipe "Text"
44+order = tipe "Order"
4345string = tipe "String"
4446
47+number = Super $ Set.fromList [ int, float, time ]
48+appendable t = Super $ Set.fromList [ string, text, listOf (VarT t) ]
49+comparable t = Super $ Set.fromList [ int, float, char, string, time, date ]
50+
4551element = tipe "Element"
4652
4753listOf t = ADT "List" [t]
@@ -51,8 +57,6 @@ maybeOf t = ADT "Maybe" [t]
5157eitherOf a b = ADT "Either" [a,b]
5258pairOf t = tupleOf [t,t]
5359point = pairOf int
54−appendable t = Super (Set.fromList [ string, text, listOf (VarT t) ])
55−--comparable = Super (Set.fromList [ int, float, char, string, time, date ])
5660
5761infixr ==>
5862t1 ==> t2 = LambdaT t1 t2