@@ -1,11 +1,12 @@
2−module Constrain where
2+module Constrain (constrain, Context (..)) where
5import Types
5import Types
6import Data.List (foldl')
6import Data.List (foldl')
7import qualified Data.Set as Set
7import qualified Data.Set as Set
8import qualified Data.Map as Map
8import qualified Data.Map as Map
9+import Control.Arrow (second)
9import Control.Monad (liftM,mapM,zipWithM)
10import Control.Monad (liftM,mapM,zipWithM)
10import Control.Monad.State (evalState)
11import Control.Monad.State (evalState)
11import Guid
12import Guid
@@ -14,39 +15,42 @@ beta = VarT `liftM` guid
14unionA = Map.unionWith (++)
15unionA = Map.unionWith (++)
15unionsA = Map.unionsWith (++)
16unionsA = Map.unionsWith (++)
17−data Context a b = Context a b deriving (Eq,Show)
18+data Context a b = Context a b deriving (Eq, Show)
18ctx e = Context e
19ctx e = Context e
20instance (Ord a, Eq c) => Ord (Context c a) where
21instance (Ord a, Eq c) => Ord (Context c a) where
21 compare (Context _ x) (Context _ y) = compare x y
22 compare (Context _ x) (Context _ y) = compare x y
23−constrain hints expr = do
24+constrain hints (Module _ _ _ stmts) = do
24− (as,cs,t) <- inference expr
25+ (ass,css,schemess) <- unzip3 `liftM` mapM stmtGen stmts
25− let cMap = Map.intersectionWithKey combine (Map.fromList hints) as
26+ let allHints = Map.fromList $ hints ++ concat schemess
26− where combine k s vs = map (\v -> ctx (Var k) $ VarT v :<<: s) vs
27+ let combine k s vs = map (\v -> ctx (Var k) $ VarT v :<<: s) vs
28+ let cMap = Map.intersectionWithKey combine allHints (unionsA ass)
27− return (Set.toList cs ++ (concatMap snd $ Map.toList cMap))
29+ return (Set.toList (Set.unions css) ++ (concatMap snd $ Map.toList cMap))
29−inference :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context Expr Constraint), Type)
31+gen :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context Expr Constraint), Type)
30−inference (Var x) =
33+gen (Var x) =
31 do b <- guid
34 do b <- guid
32 return (Map.singleton x [b], Set.empty, VarT b)
35 return (Map.singleton x [b], Set.empty, VarT b)
33−inference e@(App e1 e2) =
37+gen e@(App e1 e2) =
34− do (a1,c1,t1) <- inference e1
38+ do (a1,c1,t1) <- gen e1
35− (a2,c2,t2) <- inference e2
39+ (a2,c2,t2) <- gen e2
37 return ( unionA a1 a2
41 return ( unionA a1 a2
38 , Set.unions [c1,c2,Set.singleton . ctx e $ t1 :=: (LambdaT t2 b)]
42 , Set.unions [c1,c2,Set.singleton . ctx e $ t1 :=: (LambdaT t2 b)]
40−inference (Lambda x e) =
44+gen (Lambda x e) =
41− do (a,c,t) <- inference e
45+ do (a,c,t) <- gen e
44 return ( Map.delete x a
48 return ( Map.delete x a
45 , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
49 , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
46 Map.findWithDefault [v] x a
50 Map.findWithDefault [v] x a
47 , LambdaT b t )
51 , LambdaT b t )
48−inference (Let defs e) =
52+gen (Let defs e) =
49− do (as,cs,t) <- inference e
53+ do (as,cs,t) <- gen e
50 (ass, schemes) <- liftM unzip (mapM defScheme defs)
54 (ass, schemes) <- liftM unzip (mapM defScheme defs)
51 let assumptions = unionsA (as:ass)
55 let assumptions = unionsA (as:ass)
52 let names = map (\(Definition x _ _) -> x) defs
56 let names = map (\(Definition x _ _) -> x) defs
@@ -58,28 +62,28 @@ inference (Let defs e) =
58 , Set.union (Set.fromList . concat $ cs') cs
62 , Set.union (Set.fromList . concat $ cs') cs
61−inference ce@(Case e cases) =
65+gen ce@(Case e cases) =
62− do (as,cs,t) <- inference e
66+ do (as,cs,t) <- gen e
63− (ass,css,ts) <- liftM unzip3 $ mapM (caseInference t) cases
67+ (ass,css,ts) <- liftM unzip3 $ mapM (caseGen t) cases
64 return ( unionsA $ as:ass
68 return ( unionsA $ as:ass
65 , let combine t1 t2 = ctx ce (t1 :=: t2) in
69 , let combine t1 t2 = ctx ce (t1 :=: t2) in
66 Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
70 Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
67 , head ts)
71 , head ts)
69−inference e@(If e1 e2 e3) =
73+gen e@(If e1 e2 e3) =
70− do (a1,c1,t1) <- inference e1
74+ do (a1,c1,t1) <- gen e1
71− (a2,c2,t2) <- inference e2
75+ (a2,c2,t2) <- gen e2
72− (a3,c3,t3) <- inference e3
76+ (a3,c3,t3) <- gen e3
73 return ( unionsA [a1,a2,a3]
77 return ( unionsA [a1,a2,a3]
74 , Set.unions [c1,c2,c3, Set.fromList [ ctx e1 (t1 :=: bool), ctx e (t2 :=: t3) ] ]
78 , Set.unions [c1,c2,c3, Set.fromList [ ctx e1 (t1 :=: bool), ctx e (t2 :=: t3) ] ]
77−inference (Data name es) = inference $ foldl' App (Var name) es
81+gen (Data name es) = gen $ foldl' App (Var name) es
78−inference (Binop op e1 e2) = inference (Var op `App` e1 `App` e2)
82+gen (Binop op e1 e2) = gen (Var op `App` e1 `App` e2)
79−inference (Access (Var x) y) = inference . Var $ x ++ "." ++ y
83+gen (Access (Var x) y) = gen . Var $ x ++ "." ++ y
80−inference (Range e1 e2) = inference (Var "elmRange" `App` e1 `App` e2)
84+gen (Range e1 e2) = gen (Var "elmRange" `App` e1 `App` e2)
82−inference other =
86+gen other =
83 case other of
87 case other of
84 IntNum _ -> do t <- beta
88 IntNum _ -> do t <- beta
85 return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
89 return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
@@ -91,8 +95,8 @@ inference other =
92primitive t = return (Map.empty, Set.empty, t)
96primitive t = return (Map.empty, Set.empty, t)
94−caseInference tipe (p,e) = do
98+caseGen tipe (p,e) = do
95− (as,cs,t) <- inference e
99+ (as,cs,t) <- gen e
96 return ( foldr Map.delete as (namesIn p)
100 return ( foldr Map.delete as (namesIn p)
@@ -103,7 +107,7 @@ namesIn (PData name ps) = concatMap namesIn ps
104defScheme (Definition name args e) =
108defScheme (Definition name args e) =
105 do argDict <- mapM (\a -> liftM ((,) a) guid) args
109 do argDict <- mapM (\a -> liftM ((,) a) guid) args
106− (as,cs,t) <- inference e
110+ (as,cs,t) <- gen e
107 let genCs (arg,x) = do
111 let genCs (arg,x) = do
108 v <- guid
112 v <- guid
109 return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
113 return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
@@ -112,3 +116,52 @@ defScheme (Definition name args e) =
112 let tipe = foldr (==>) t $ map (VarT . snd) argDict
116 let tipe = foldr (==>) t $ map (VarT . snd) argDict
113 return ( foldr Map.delete as args
117 return ( foldr Map.delete as args
114 , Forall (map snd argDict) (cs' ++ cs'') tipe)
118 , Forall (map snd argDict) (cs' ++ cs'') tipe)
120+stmtGen (Def name args e) = do
121+ argDict <- mapM (\a -> liftM ((,) a) guid) args
123+ let genCs (arg,x) = do
125+ return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
126+ cs' <- concat `liftM` mapM genCs argDict
127+ let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
128+ let tipe = foldr (==>) t $ map (VarT . snd) argDict
129+ return ( foldr Map.delete as args
131+ , [ (name, Forall (map snd argDict) (cs' ++ cs'') tipe) ] )
133+stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
134+ return (Map.empty, Set.empty, schemes)
135+ where names = map (+ (length xs)) [1..5]
136+ tcs' = map (second . map $ rnm names) tcs
137+ supers t = zipWith (:<:) (map VarT names)
138+ [ number, time, appendable t, comparable, transformable ]
141+ return . (,) n . Forall (xs ++ names) (supers t) $
142+ foldr (==>) (ADT name $ map VarT xs) ts
143+ rnm [a,b,c,d,e] (ADT n []) | n == "Number" = VarT a
144+ | n == "Time" = VarT b
145+ | n == "Appendable" = VarT c
146+ | n == "Comparable" = VarT d
147+ | n == "Transformable" = VarT e
150+stmtGen (ExportEvent js elm tipe) = do
152+ return ( Map.singleton elm [x]
153+ , Set.singleton . ctx (Var elm) $ VarT x :=: tipe
156+stmtGen (ImportEvent js base elm tipe) = do
157+ (as,cs,t) <- gen base
159+ , Set.insert (ctx (Var elm) (t :=: tipe)) cs
160+ , [ (elm, Forall [] [] tipe) ] )
163+ map (\(_,_,n,t) -> n -: t) ims ++ map (\(_,n,t) -> n -: t) exs
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