6import qualified Data.Set as Set
7import qualified Data.Map as Map
8import Control.Monad (liftM,mapM)
9import Control.Monad.State (evalState)
12data Constraint = Type :=: Type
15 deriving (Eq, Ord, Show)
17beta = VarT `liftM` guid
18unionA = Map.unionWith (++)
19unionsA = Map.unionsWith (++)
21constrain hints expr = do
22 (as,cs,t) <- inference expr
24 let cMap = Map.intersectionWith (\t -> map (:<: t)) (Map.fromList hs) as
25 return $ Set.toList cs ++ (concat . map snd $ Map.toList cMap)
29 return (Map.singleton x [b], Set.empty, b)
30inference (App e1 e2) =
31 do (a1,c1,t1) <- inference e1
32 (a2,c2,t2) <- inference e2
35 , Set.unions [c1,c2,Set.singleton $ t1 :=: (LambdaT t2 b)]
37inference (Lambda x e) =
38 do (a,c,t) <- inference e
40 return ( Map.delete x a
41 , Set.union c . Set.fromList . map (:=: b) $
42 Map.findWithDefault [] x a
44inference (Let defs e) =
45 do (a,c,t) <- inference e
46 let (xs,es) = unzip defs
47 (as,cs,ts) <- unzip3 `liftM` mapM inference es
48 let assumptions = unionsA (a:as)
49 let f x t = map (:<: t) $ Map.findWithDefault [] x assumptions
50 let constraints = Set.fromList . concat $ zipWith f xs ts
51 return ( foldr Map.delete assumptions xs
52 , Set.unions $ c:constraints:cs
55inference (If e1 e2 e3) =
56 do (a1,c1,t1) <- inference e1
57 (a2,c2,t2) <- inference e2
58 (a3,c3,t3) <- inference e3
59 return ( unionsA [a1,a2,a3]
60 , Set.unions [c1,c2,c3, Set.fromList [ t1 :=: BoolT, t2 :=: t3 ] ]
63inference (Data name es) = inference $ foldl App (Var name) es
64inference (Binop op e1 e2) = inference (Var op `App` e1 `App` e2)
65inference (Access (Var x) y) = inference . Var $ x ++ "." ++ y
66inference (Range e1 e2) = inference (Var "elmRange" `App` e1 `App` e2)
70 Number _ -> primitive IntT
71 Chr _ -> primitive CharT
72 Boolean _ -> primitive BoolT
73 _ -> beta >>= primitive
75primitive t = return (Map.empty, Set.empty, t)
78 do (a1,c1,t1) <- inference e1
79 (a2,c2,t2) <- inference e2
80 let ts = Map.findWithDefault (error "inference") x a
81 return ( unionA a1 $ Map.delete x a2
82 , Set.unions [ c1, c2, Set.fromList $ map (:<: t1) ts ]
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list