6import Data.List (foldl')
7import qualified Data.Set as Set
8import qualified Data.Map as Map
9import Control.Monad (liftM,mapM)
10import Control.Monad.State (evalState)
13data Constraint = Type :=: Type
16 deriving (Eq, Ord, Show)
18beta = VarT `liftM` guid
19unionA = Map.unionWith (++)
20unionsA = Map.unionsWith (++)
22constrain hints expr = do
23 (as,cs,t) <- inference expr
25 let cMap = Map.intersectionWith (\t -> map (:<: t)) (Map.fromList hs) as
26 return $ Set.toList cs ++ (concat . map snd $ Map.toList cMap)
30 return (Map.singleton x [b], Set.empty, b)
31inference (App e1 e2) =
32 do (a1,c1,t1) <- inference e1
33 (a2,c2,t2) <- inference e2
36 , Set.unions [c1,c2,Set.singleton $ t1 :=: (LambdaT t2 b)]
38inference (Lambda x e) =
39 do (a,c,t) <- inference e
41 return ( Map.delete x a
42 , Set.union c . Set.fromList . map (:=: b) $
43 Map.findWithDefault [] x a
45inference (Let defs e) =
46 do (a,c,t) <- inference e
47 let (xs,es) = unzip defs
48 (as,cs,ts) <- unzip3 `liftM` mapM inference es
49 let assumptions = unionsA (a:as)
50 let f x t = map (:<: t) $ Map.findWithDefault [] x assumptions
51 let constraints = Set.fromList . concat $ zipWith f xs ts
52 return ( foldr Map.delete assumptions xs
53 , Set.unions $ c:constraints:cs
56inference (If e1 e2 e3) =
57 do (a1,c1,t1) <- inference e1
58 (a2,c2,t2) <- inference e2
59 (a3,c3,t3) <- inference e3
60 return ( unionsA [a1,a2,a3]
61 , Set.unions [c1,c2,c3, Set.fromList [ t1 :=: BoolT, t2 :=: t3 ] ]
64inference (Data name es) = inference $ foldl' App (Var name) es
65inference (Binop op e1 e2) = inference (Var op `App` e1 `App` e2)
66inference (Access (Var x) y) = inference . Var $ x ++ "." ++ y
67inference (Range e1 e2) = inference (Var "elmRange" `App` e1 `App` e2)
71 Number _ -> primitive IntT
72 Chr _ -> primitive CharT
73 Str _ -> primitive string
74 Boolean _ -> primitive BoolT
75 _ -> beta >>= primitive
77primitive t = return (Map.empty, Set.empty, t)
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