@@ -6,7 +6,7 @@ import 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.Monad (liftM,mapM)
9+import Control.Monad (liftM,mapM,zipWithM)
10import Control.Monad.State (evalState)
10import Control.Monad.State (evalState)
11import Guid
11import Guid
@@ -14,53 +14,64 @@ beta = VarT `liftM` guid
14unionA = Map.unionWith (++)
14unionA = Map.unionWith (++)
15unionsA = Map.unionsWith (++)
15unionsA = Map.unionsWith (++)
17+data Context a b = Context a b deriving (Eq,Show)
20+instance (Ord a, Eq c) => Ord (Context c a) where
21+ compare (Context _ x) (Context _ y) = compare x y
17constrain hints expr = do
23constrain hints expr = do
18 (as,cs,t) <- inference expr
24 (as,cs,t) <- inference expr
19− let cMap = Map.intersectionWith (\s -> map (\v -> VarT v:<<: s)) (Map.fromList hints) as
25+ let cMap = Map.intersectionWithKey combine (Map.fromList hints) as
26+ where combine k s vs = map (\v -> ctx (Var k) $ VarT v :<<: s) vs
20− return $ Set.toList cs ++ (concat . map snd $ Map.toList cMap)
27+ return (Set.toList cs ++ (concatMap snd $ Map.toList cMap))
22−inference :: Expr -> GuidCounter (Map.Map String [X], Set.Set Constraint, Type)
29+inference :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context Expr Constraint), Type)
23inference (Var x) =
30inference (Var x) =
24 do b <- guid
31 do b <- guid
25 return (Map.singleton x [b], Set.empty, VarT b)
32 return (Map.singleton x [b], Set.empty, VarT b)
26−inference (App e1 e2) =
33+inference e@(App e1 e2) =
27 do (a1,c1,t1) <- inference e1
34 do (a1,c1,t1) <- inference e1
28 (a2,c2,t2) <- inference e2
35 (a2,c2,t2) <- inference e2
30 return ( unionA a1 a2
37 return ( unionA a1 a2
31− , Set.unions [c1,c2,Set.singleton $ t1 :=: (LambdaT t2 b)]
38+ , Set.unions [c1,c2,Set.singleton . ctx e $ t1 :=: (LambdaT t2 b)]
33inference (Lambda x e) =
40inference (Lambda x e) =
34 do (a,c,t) <- inference e
41 do (a,c,t) <- inference e
36 return ( Map.delete x a
44 return ( Map.delete x a
37− , Set.union c . Set.fromList . map (\x -> VarT x :=: b) $
45+ , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
38− Map.findWithDefault [] x a
46+ Map.findWithDefault [v] x a
39 , LambdaT b t )
47 , LambdaT b t )
40inference (Let defs e) =
48inference (Let defs e) =
41 do (as,cs,t) <- inference e
49 do (as,cs,t) <- inference e
42 (ass, schemes) <- liftM unzip (mapM defScheme defs)
50 (ass, schemes) <- liftM unzip (mapM defScheme defs)
43 let assumptions = unionsA (as:ass)
51 let assumptions = unionsA (as:ass)
44 let names = map (\(Definition x _ _) -> x) defs
52 let names = map (\(Definition x _ _) -> x) defs
53+ let genCs name s = do
45− let genCs name s = map (\x -> VarT x :<<: s) $ Map.findWithDefault [] name assumptions
55+ return . map (\x -> ctx (Var name) $ VarT x :<<: s) $ Map.findWithDefault [v] name assumptions
46− let cs' = Set.fromList . concat $ zipWith genCs names schemes
56+ cs' <- zipWithM genCs names schemes
47 return ( foldr Map.delete assumptions names
57 return ( foldr Map.delete assumptions names
48− , Set.union cs' cs
58+ , Set.union (Set.fromList . concat $ cs') cs
51−inference (Case e cases) =
61+inference ce@(Case e cases) =
52 do (as,cs,t) <- inference e
62 do (as,cs,t) <- inference e
53 (ass,css,ts) <- liftM unzip3 $ mapM (caseInference t) cases
63 (ass,css,ts) <- liftM unzip3 $ mapM (caseInference t) cases
54 return ( unionsA $ as:ass
64 return ( unionsA $ as:ass
65+ , let combine t1 t2 = ctx ce (t1 :=: t2) in
55− , Set.unions $ Set.fromList (zipWith (:=:) ts $ tail ts) : cs : css
66+ Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
56 , head ts)
67 , head ts)
58−inference (If e1 e2 e3) =
69+inference e@(If e1 e2 e3) =
59 do (a1,c1,t1) <- inference e1
70 do (a1,c1,t1) <- inference e1
60 (a2,c2,t2) <- inference e2
71 (a2,c2,t2) <- inference e2
61 (a3,c3,t3) <- inference e3
72 (a3,c3,t3) <- inference e3
62 return ( unionsA [a1,a2,a3]
73 return ( unionsA [a1,a2,a3]
63− , Set.unions [c1,c2,c3, Set.fromList [ t1 :=: bool, t2 :=: t3 ] ]
74+ , Set.unions [c1,c2,c3, Set.fromList [ ctx e1 (t1 :=: bool), ctx e (t2 :=: t3) ] ]
66inference (Data name es) = inference $ foldl' App (Var name) es
77inference (Data name es) = inference $ foldl' App (Var name) es
@@ -71,7 +82,7 @@ inference (Range e1 e2) = inference (Var "elmRange" `App` e1 `App` e2)
71inference other =
82inference other =
72 case other of
83 case other of
73 IntNum _ -> do t <- beta
84 IntNum _ -> do t <- beta
74− return (Map.empty, Set.singleton (t :<: number), t)
85+ return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
75 FloatNum _ -> primitive float
86 FloatNum _ -> primitive float
76 Chr _ -> primitive char
87 Chr _ -> primitive char
77 Str _ -> primitive string
88 Str _ -> primitive string
@@ -93,8 +104,11 @@ namesIn (PData name ps) = concatMap namesIn ps
93defScheme (Definition name args e) =
104defScheme (Definition name args e) =
94 do argDict <- mapM (\a -> liftM ((,) a) guid) args
105 do argDict <- mapM (\a -> liftM ((,) a) guid) args
95 (as,cs,t) <- inference e
106 (as,cs,t) <- inference e
107+ let genCs (arg,x) = do
96− let genCs (arg,x) = map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [] arg as
109+ return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
97− let cs' = concatMap genCs argDict
110+ cs' <- concat `liftM` mapM genCs argDict
111+ let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
98 let tipe = foldr (==>) t $ map (VarT . snd) argDict
112 let tipe = foldr (==>) t $ map (VarT . snd) argDict
99− return (foldr Map.delete as args
113+ return ( foldr Map.delete as args
100− , Forall (map snd argDict) (cs' ++ Set.toList cs) tipe)
114+ , Forall (map snd argDict) (cs' ++ cs'') tipe)