@@ -6,7 +6,7 @@ import Types
66import Data.List (foldl')
77import qualified Data.Set as Set
88import qualified Data.Map as Map
9−import Control.Monad (liftM,mapM)
9+import Control.Monad (liftM,mapM,zipWithM)
1010import Control.Monad.State (evalState)
1111import Guid
1212
@@ -14,53 +14,64 @@ beta = VarT `liftM` guid
1414unionA = Map.unionWith (++)
1515unionsA = Map.unionsWith (++)
1616
17+data Context a b = Context a b deriving (Eq,Show)
18+ctx e = Context e
19+
20+instance (Ord a, Eq c) => Ord (Context c a) where
21+ compare (Context _ x) (Context _ y) = compare x y
22+
1723constrain hints expr = do
1824 (as,cs,t) <- inference expr
19− let cMap = Map.intersectionWith (\s -> map (\v -> VarT v:<<: s)) (Map.fromList hints) as
20− return $ Set.toList cs ++ (concat . map snd $ Map.toList cMap)
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
27+ return (Set.toList cs ++ (concatMap snd $ Map.toList cMap))
2128
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)
2330inference (Var x) =
2431 do b <- guid
2532 return (Map.singleton x [b], Set.empty, VarT b)
26−inference (App e1 e2) =
33+inference e@(App e1 e2) =
2734 do (a1,c1,t1) <- inference e1
2835 (a2,c2,t2) <- inference e2
2936 b <- beta
3037 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)]
3239 , b )
3340inference (Lambda x e) =
3441 do (a,c,t) <- inference e
3542 b <- beta
43+ v <- guid
3644 return ( Map.delete x a
37− , Set.union c . Set.fromList . map (\x -> VarT x :=: b) $
38− Map.findWithDefault [] x a
45+ , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
46+ Map.findWithDefault [v] x a
3947 , LambdaT b t )
4048inference (Let defs e) =
4149 do (as,cs,t) <- inference e
4250 (ass, schemes) <- liftM unzip (mapM defScheme defs)
4351 let assumptions = unionsA (as:ass)
4452 let names = map (\(Definition x _ _) -> x) defs
45− let genCs name s = map (\x -> VarT x :<<: s) $ Map.findWithDefault [] name assumptions
46− let cs' = Set.fromList . concat $ zipWith genCs names schemes
53+ let genCs name s = do
54+ v <- guid
55+ return . map (\x -> ctx (Var name) $ VarT x :<<: s) $ Map.findWithDefault [v] name assumptions
56+ cs' <- zipWithM genCs names schemes
4757 return ( foldr Map.delete assumptions names
48− , Set.union cs' cs
58+ , Set.union (Set.fromList . concat $ cs') cs
4959 , t )
5060
51−inference (Case e cases) =
61+inference ce@(Case e cases) =
5262 do (as,cs,t) <- inference e
5363 (ass,css,ts) <- liftM unzip3 $ mapM (caseInference t) cases
5464 return ( unionsA $ as:ass
55− , Set.unions $ Set.fromList (zipWith (:=:) ts $ tail ts) : cs : css
65+ , let combine t1 t2 = ctx ce (t1 :=: t2) in
66+ Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
5667 , head ts)
5768
58−inference (If e1 e2 e3) =
69+inference e@(If e1 e2 e3) =
5970 do (a1,c1,t1) <- inference e1
6071 (a2,c2,t2) <- inference e2
6172 (a3,c3,t3) <- inference e3
6273 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) ] ]
6475 , t2 )
6576
6677inference (Data name es) = inference $ foldl' App (Var name) es
@@ -71,7 +82,7 @@ inference (Range e1 e2) = inference (Var "elmRange" `App` e1 `App` e2)
7182inference other =
7283 case other of
7384 IntNum _ -> do t <- beta
74− return (Map.empty, Set.singleton (t :<: number), t)
85+ return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
7586 FloatNum _ -> primitive float
7687 Chr _ -> primitive char
7788 Str _ -> primitive string
@@ -93,8 +104,11 @@ namesIn (PData name ps) = concatMap namesIn ps
93104defScheme (Definition name args e) =
94105 do argDict <- mapM (\a -> liftM ((,) a) guid) args
95106 (as,cs,t) <- inference e
96− let genCs (arg,x) = map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [] arg as
97− let cs' = concatMap genCs argDict
107+ let genCs (arg,x) = do
108+ v <- guid
109+ return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
110+ cs' <- concat `liftM` mapM genCs argDict
111+ let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
98112 let tipe = foldr (==>) t $ map (VarT . snd) argDict
99− return (foldr Map.delete as args
100− , Forall (map snd argDict) (cs' ++ Set.toList cs) tipe)
113+ return ( foldr Map.delete as args
114+ , Forall (map snd argDict) (cs' ++ cs'') tipe)