@@ -11,12 +11,11 @@ import Ast
11import Context
11import Context
12import Control.Monad (liftM, liftM2)
12import Control.Monad (liftM, liftM2)
13import Control.Monad.State (runState, State, get, put)
13import Control.Monad.State (runState, State, get, put)
14−import Data.List (foldl')
14+import Data.List (nub)
15−import Data.Maybe (catMaybes)
16import qualified Data.Set as Set
15import qualified Data.Set as Set
17import qualified Data.Map as Map
16import qualified Data.Map as Map
18import Guid
17import Guid
19−import Types.Types as Types
18+import Types.Types
21class Subst a where
20class Subst a where
22 subst :: [(X,Type)] -> a -> a
21 subst :: [(X,Type)] -> a -> a
@@ -92,21 +91,25 @@ generalize exceptions (Forall xs cs t) = rescheme (Forall (xs ++ frees) cs t)
92 where allFrees = Set.fromList $ freeVars t ++ concatMap freeVars cs
91 where allFrees = Set.fromList $ freeVars t ++ concatMap freeVars cs
93 frees = Set.toList $ Set.difference allFrees (Set.fromList exceptions)
92 frees = Set.toList $ Set.difference allFrees (Set.fromList exceptions)
95−newtype Superize a = S { runSuper :: State (Int, Maybe X, Maybe X) a }
94+newtype Superize a = S { runSuper :: State ([X], [X], [X]) a }
96 deriving (Monad)
95 deriving (Monad)
98superize :: String -> Type -> GuidCounter Scheme
97superize :: String -> Type -> GuidCounter Scheme
99superize name tipe =
98superize name tipe =
100− do x <- guid
99+ do constraints <- liftM concat $
101− let (tipe', (m, number, append)) =
100+ sequence [ mapM (<: nmbr) (nub ns)
102− runState (runSuper (go tipe)) (x+1, Nothing, Nothing)
101+ , mapM (<: apnd) (nub as)
103− mkC super = liftM (\x -> C (Just name) NoSpan (VarT x :<: super))
102+ , mapM (<: comp) (nub cs) ]
104− set m
103+ return (Forall (concat [ns,as,cs]) constraints tipe')
105− return (Forall (catMaybes [number,append])
106− (catMaybes [ mkC Types.number number
107− , mkC (Types.appendable x) append])
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)
110+ apnd t = appendable t
111+ comp t = comparable t
110 go :: Type -> Superize Type
113 go :: Type -> Superize Type
112 case t of
115 case t of
@@ -114,24 +117,20 @@ superize name tipe =
114 Super _ -> return t
117 Super _ -> return t
115 VarT _ -> return t
118 VarT _ -> return t
116 LambdaT t1 t2 -> liftM2 LambdaT (go t1) (go t2)
119 LambdaT t1 t2 -> liftM2 LambdaT (go t1) (go t2)
117− ADT "Number" [] -> liftM VarT number
120+ ADT "Number" [VarT t] -> addNumber t
118− ADT "Appendable" [t] -> liftM VarT append
121+ ADT "Appendable" [VarT t] -> addAppendable t
122+ ADT "Comparable" [VarT t] -> addComparable t
119 ADT name ts -> liftM (ADT name) (mapM go ts)
123 ADT name ts -> liftM (ADT name) (mapM go ts)
120 RecordT fs t -> liftM2 RecordT fs' (go t)
124 RecordT fs t -> liftM2 RecordT fs' (go t)
121 where pairs = Map.toList fs
125 where pairs = Map.toList fs
122 fs' = do ps <- mapM (\(f,t) -> liftM ((,) f) (mapM go t)) pairs
126 fs' = do ps <- mapM (\(f,t) -> liftM ((,) f) (mapM go t)) pairs
123 return (Map.fromList ps)
127 return (Map.fromList ps)
125− number :: Superize X
129+ add :: (X -> ([X],[X],[X]) -> ([X],[X],[X])) -> X -> Superize Type
126− number = S $ do (n, num, append) <- get
130+ add f v = S $ do (ns, as, cs) <- get
127− case num of
131+ put $ f v (ns, as, cs)
128− Just x -> return x
132+ return (VarT v)
129− Nothing -> do put (n + 1, Just n, append)
133+
130− return n
134+ addNumber = add (\n (ns,as,cs) -> (n:ns,as,cs))
131−
135+ addAppendable = add (\a (ns,as,cs) -> (ns,a:as,cs))
132− append :: Superize X
136+ addComparable = add (\c (ns,as,cs) -> (ns,as,c:cs))
133− append = S $ do (n, number, app) <- get
136− Nothing -> do put (n + 1, number, Just n)