@@ -1,5 +1,5 @@
11
2−module Constrain (constrain, Context (..)) where
2+module Types.Constrain (constrain) where
33
44import Ast
55import Types
@@ -7,28 +7,29 @@ import Data.List (foldl')
77import qualified Data.Set as Set
88import qualified Data.Map as Map
99import Control.Arrow (second)
10−import Control.Monad (liftM,mapM,zipWithM)
10+import Control.Monad (liftM,mapM,zipWithM,foldM)
1111import Control.Monad.State (evalState)
1212import Guid
13+import Types.Substitutions
14+
15+--import System.IO.Unsafe
16+
17+prints xs v = v --unsafePerformIO (putStrLn "~~~~~~~~~~" >> mapM print xs) `seq` v
1318
1419beta = VarT `liftM` guid
1520unionA = Map.unionWith (++)
1621unionsA = Map.unionsWith (++)
1722
18−data Context a b = Context a b deriving (Eq, Show)
19−ctx e = Context e
20−
21−instance (Ord a, Eq c) => Ord (Context c a) where
22− compare (Context _ x) (Context _ y) = compare x y
23−
2423constrain hints (Module _ _ _ stmts) = do
2524 (ass,css,schemess) <- unzip3 `liftM` mapM stmtGen stmts
26− let allHints = Map.fromList $ hints ++ concat schemess
27− let combine k s vs = map (\v -> ctx (Var k) $ VarT v :<<: s) vs
28− let cMap = Map.intersectionWithKey combine allHints (unionsA ass)
29− return (Set.toList (Set.unions css) ++ (concatMap snd $ Map.toList cMap))
25+ allHints <- liftM (Map.fromList . (++ concat schemess)) hints
26+ let insert as n = do v <- guid; return $ Map.insertWith' (\_ x -> x) n [v] as
27+ assumptions <- foldM insert (unionsA ass) $ map fst (concat schemess)
28+ let cs = let f k s vs = map (\v -> Context k $ v :<<: s) vs in
29+ concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
30+ return $ cs ++ Set.toList (Set.unions css)
3031
31−gen :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context Expr Constraint), Type)
32+gen :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context String Constraint), Type)
3233
3334gen (Var x) =
3435 do b <- guid
@@ -56,7 +57,8 @@ gen (Let defs e) =
5657 let names = map (\(Definition x _ _) -> x) defs
5758 let genCs name s = do
5859 v <- guid
59− return . map (\x -> ctx (Var name) $ VarT x :<<: s) $ Map.findWithDefault [v] name assumptions
60+ let vs = Map.findWithDefault [v] name assumptions
61+ return $ map (\x -> ctx (Var name) $ x :<<: s) vs
6062 cs' <- zipWithM genCs names schemes
6163 return ( foldr Map.delete assumptions names
6264 , Set.union (Set.fromList . concat $ cs') cs
@@ -96,50 +98,62 @@ gen other =
9698primitive t = return (Map.empty, Set.empty, t)
9799
98100caseGen tipe (p,e) = do
99− (as,cs,t) <- gen e
100− return ( foldr Map.delete as (namesIn p)
101− , cs
102− , t)
103−
104−namesIn PAnything = []
105−namesIn (PVar v) = [v]
106−namesIn (PData name ps) = concatMap namesIn ps
107−
108−defScheme (Definition name args e) =
109− do argDict <- mapM (\a -> liftM ((,) a) guid) args
110− (as,cs,t) <- gen e
111− let genCs (arg,x) = do
112− v <- guid
113− return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
114− cs' <- concat `liftM` mapM genCs argDict
115− let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
116− let tipe = foldr (==>) t $ map (VarT . snd) argDict
117− return ( foldr Map.delete as args
118− , Forall (map snd argDict) (cs' ++ cs'') tipe)
119−
120−stmtGen (Def name args e) = do
101+ (as ,cs , t ) <- gen e
102+ (as',cs',[t']) <- patternGen (as,cs,[]) p
103+ let cs'' = Set.union cs' . Set.singleton . ctx p $ t' :=: tipe
104+ return ( as', cs'', t )
105+
106+patternGen (as,cs,ts) PAnything = ((,,) as cs . (\t -> ts++[t])) `liftM` beta
107+patternGen (as,cs,ts) (PVar v) = do
108+ b <- beta
109+ let cs' = map (\x -> ctx (Var v) $ VarT x :=: b) $ Map.findWithDefault [] v as
110+ return ( Map.delete v as, Set.union cs $ Set.fromList cs', ts ++ [b] )
111+patternGen (as,cs,ts) p@(PData name ps) = do
112+ constr <- guid
113+ output <- beta
114+ (as',cs',ts') <- foldM patternGen (as,cs,[]) ps
115+ let t = foldr (==>) output ts'
116+ let getC | isTupleString name = do
117+ vs <- mapM (\_ -> beta) ps
118+ return . Set.singleton . ctx p $ output :=: ADT name vs
119+ | otherwise = return Set.empty
120+ cs'' <- getC
121+ return ( unionA as' (Map.singleton name [constr])
122+ , Set.unions [cs',cs'', Set.singleton . ctx p $ VarT constr :=: t]
123+ , ts ++ [output] )
124+
125+
126+defScheme :: Definition -> GuidCounter (Map.Map String [X], Scheme)
127+defScheme (Definition name args e) = do
128+ (as,cs,hint) <- defGen name args e
129+ return ( as, snd hint )
130+
131+defGen name args e = do
121132 argDict <- mapM (\a -> liftM ((,) a) guid) args
122133 (as,cs,t) <- gen e
123134 let genCs (arg,x) = do
124135 v <- guid
125− return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
136+ return . map (\y -> Context arg $ VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
126137 cs' <- concat `liftM` mapM genCs argDict
127− let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
138+ let as' = foldr Map.delete as args
128139 let tipe = foldr (==>) t $ map (VarT . snd) argDict
129− return ( foldr Map.delete as args
130− , Set.empty
131− , [ (name, Forall (map snd argDict) (cs' ++ cs'') tipe) ] )
140+ scheme <- generalize (concat $ Map.elems as') $
141+ Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
142+ return ( as', Set.empty, (name, scheme) )
143+
144+stmtGen (Def name args e) = do (as,cs,hint) <- defGen name args e
145+ return ( as, cs, [hint] )
132146
133147stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
134148 return (Map.empty, Set.empty, schemes)
135149 where names = map (+ (length xs)) [1..5]
136150 tcs' = map (second . map $ rnm names) tcs
137− supers t = zipWith (:<:) (map VarT names)
151+ supers t = map (Context name) $ zipWith (:<:) (map VarT names)
138152 [ number, time, appendable t, comparable, transformable ]
139− gen' (n,ts) = do
140− t <- beta
141− return . (,) n . Forall (xs ++ names) (supers t) $
142− foldr (==>) (ADT name $ map VarT xs) ts
153+ gen' (n,ts) = do t <- beta
154+ let s = Forall (xs ++ names) (supers t) $
155+ foldr (==>) (ADT name $ map VarT xs) ts
156+ (,) n `liftM` generalize [] s
143157 rnm [a,b,c,d,e] (ADT n []) | n == "Number" = VarT a
144158 | n == "Time" = VarT b
145159 | n == "Appendable" = VarT c
@@ -156,12 +170,10 @@ stmtGen (ExportEvent js elm tipe) = do
156170stmtGen (ImportEvent js base elm tipe) = do
157171 (as,cs,t) <- gen base
158172 return ( as
159− , Set.insert (ctx (Var elm) (t :=: tipe)) cs
173+ , Set.insert (ctx base (signalOf t :=: tipe)) cs
160174 , [ (elm, Forall [] [] tipe) ] )
161175
162−ffiHints (ims,exs) =
163− map (\(_,_,n,t) -> n -: t) ims ++ map (\(_,n,t) -> n -: t) exs
176+getDatatypeInfo (Datatype name args tcs) =
177+ Just (name, args, tcs)
178+getDatatypeInfo _ = Nothing
164179
165−checkFFI dict ims exs = list $ ims' ++ exs'
166− where ims' = map (\(_,b,n,_)-> Binop "==" (Var n) (App (Var "constant") b)) ims
167− exs' = map (\(_,n,_) -> Binop "==" (Var n) (Var $ dict n)) exs