1{-# OPTIONS_GHC -Wall #-}
2module Type.Constrain.Pattern
10import Control.Arrow (second)
11import Control.Monad (foldM)
12import qualified Data.Map.Strict as Map
14import qualified AST.Canonical as Can
15import qualified AST.Module.Name as ModuleName
16import qualified Data.Index as Index
17import qualified Elm.Name as N
18import qualified Reporting.Annotation as A
19import qualified Reporting.Error.Type as E
20import qualified Reporting.Region as R
21import qualified Type.Instantiate as Instantiate
26-- ACTUALLY ADD CONSTRAINTS
29-- The constraints are stored in reverse order so that adding a new
30-- constraint is O(1) and we can reverse it at some later time.
36 , _revCons :: [Constraint]
40type Header = Map.Map N.Name (A.Located Type)
43add :: Can.Pattern -> E.PExpected Type -> State -> IO State
44add (A.At region pattern) expectation state =
50 return $ addToHeaders region name expectation state
52 Can.PAlias realPattern name ->
53 add realPattern expectation $
54 addToHeaders region name expectation state
57 do let (State headers vars revCons) = state
58 let unitCon = CPattern region E.PUnit UnitN expectation
59 return $ State headers vars (unitCon:revCons)
61 Can.PTuple a b maybeC ->
62 addTuple region a b maybeC expectation state
64 Can.PCtor home typeName (Can.Union typeVars _ _ _) ctorName _ args ->
65 addCtor region home typeName typeVars ctorName args expectation state
68 do entryVar <- mkFlexVar
69 let entryType = VarN entryVar
70 let listType = AppN ModuleName.list N.list [entryType]
72 (State headers vars revCons) <-
73 foldM (addEntry region entryType) state (Index.indexedMap (,) patterns)
75 let listCon = CPattern region E.PList listType expectation
76 return $ State headers (entryVar:vars) (listCon:revCons)
78 Can.PCons headPattern tailPattern ->
79 do entryVar <- mkFlexVar
80 let entryType = VarN entryVar
81 let listType = AppN ModuleName.list N.list [entryType]
83 let headExpectation = E.PNoExpectation entryType
84 let tailExpectation = E.PFromContext region E.PTail listType
86 (State headers vars revCons) <-
87 add headPattern headExpectation =<<
88 add tailPattern tailExpectation state
90 let listCon = CPattern region E.PList listType expectation
91 return $ State headers (entryVar:vars) (listCon : revCons)
94 do extVar <- mkFlexVar
95 let extType = VarN extVar
97 fieldVars <- traverse (\field -> (,) field <$> mkFlexVar) fields
98 let fieldTypes = Map.fromList (map (fmap VarN) fieldVars)
99 let recordType = RecordN fieldTypes extType
101 let (State headers vars revCons) = state
102 let recordCon = CPattern region E.PRecord recordType expectation
105 { _headers = Map.union headers (Map.map (A.At region) fieldTypes)
106 , _vars = map snd fieldVars ++ extVar : vars
107 , _revCons = recordCon : revCons
111 do let (State headers vars revCons) = state
112 let intCon = CPattern region E.PInt T.int expectation
113 return $ State headers vars (intCon:revCons)
116 do let (State headers vars revCons) = state
117 let strCon = CPattern region E.PStr T.string expectation
118 return $ State headers vars (strCon:revCons)
121 do let (State headers vars revCons) = state
122 let chrCon = CPattern region E.PChr T.char expectation
123 return $ State headers vars (chrCon:revCons)
130{-# NOINLINE emptyState #-}
133 State Map.empty [] []
136addToHeaders :: R.Region -> N.Name -> E.PExpected Type -> State -> State
137addToHeaders region name expectation (State headers vars revCons) =
139 tipe = getType expectation
140 newHeaders = Map.insert name (A.At region tipe) headers
142 State newHeaders vars revCons
145getType :: E.PExpected Type -> Type
148 E.PNoExpectation tipe -> tipe
149 E.PFromContext _ _ tipe -> tipe
156addEntry :: R.Region -> Type -> State -> (Index.ZeroBased, Can.Pattern) -> IO State
157addEntry listRegion tipe state (index, pattern) =
160 E.PFromContext listRegion (E.PListEntry index) tipe
162 add pattern expectation state
169addTuple :: R.Region -> Can.Pattern -> Can.Pattern -> Maybe Can.Pattern -> E.PExpected Type -> State -> IO State
170addTuple region a b maybeC expectation state =
173 let aType = VarN aVar
174 let bType = VarN bVar
178 do (State headers vars revCons) <-
179 simpleAdd b bType =<<
180 simpleAdd a aType state
182 let tupleCon = CPattern region E.PTuple (TupleN aType bType Nothing) expectation
184 return $ State headers (aVar:bVar:vars) (tupleCon:revCons)
188 let cType = VarN cVar
190 (State headers vars revCons) <-
191 simpleAdd c cType =<<
192 simpleAdd b bType =<<
193 simpleAdd a aType state
195 let tupleCon = CPattern region E.PTuple (TupleN aType bType (Just cType)) expectation
197 return $ State headers (aVar:bVar:cVar:vars) (tupleCon:revCons)
200simpleAdd :: Can.Pattern -> Type -> State -> IO State
201simpleAdd pattern patternType state =
202 add pattern (E.PNoExpectation patternType) state
206-- CONSTRAIN CONSTRUCTORS
209addCtor :: R.Region -> ModuleName.Canonical -> N.Name -> [N.Name] -> N.Name -> [Can.PatternCtorArg] -> E.PExpected Type -> State -> IO State
210addCtor region home typeName typeVarNames ctorName args expectation state =
211 do varPairs <- traverse (\var -> (,) var <$> nameToFlex var) typeVarNames
212 let typePairs = map (second VarN) varPairs
213 let freeVarDict = Map.fromList typePairs
215 (State headers vars revCons) <-
216 foldM (addCtorArg region ctorName freeVarDict) state args
218 let ctorType = AppN home typeName (map snd typePairs)
219 let ctorCon = CPattern region (E.PCtor ctorName) ctorType expectation
224 , _vars = map snd varPairs ++ vars
225 , _revCons = ctorCon : revCons
229addCtorArg :: R.Region -> N.Name -> Map.Map N.Name Type -> State -> Can.PatternCtorArg -> IO State
230addCtorArg region ctorName freeVarDict state (Can.PatternCtorArg index srcType pattern) =
231 do tipe <- Instantiate.fromSrcType freeVarDict srcType
232 let expectation = E.PFromContext region (E.PCtorArg ctorName index) tipe
233 add pattern expectation state
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