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.Bag as Bag
17import qualified Data.Index as Index
18import qualified Elm.Name as N
19import qualified Reporting.Annotation as A
20import qualified Reporting.Error.Type as Error
21import qualified Reporting.Region as R
23import qualified Type.Instantiate as Instantiate
31-- The constraints are stored in reverse order so that adding a new
32-- constraint is O(1) and we can reverse it at some later time.
36 { _headers :: Map.Map N.Name (A.Located Type)
37 , _vars :: Bag.Bag Variable
38 , _revCons :: [Constraint]
44 State Map.empty Bag.empty []
47addConstraints :: R.Region -> Error.PatternContext -> Can.Pattern -> Type -> State -> IO State
48addConstraints outerRegion context (A.A region pattern) tipe state =
54 do let (State headers vars revCons) = state
55 let newHeaders = Map.insert name (A.A region tipe) headers
56 return $ State newHeaders vars revCons
58 Can.PAlias realPattern name ->
59 do let (State headers vars revCons) = state
60 addConstraints outerRegion context realPattern tipe $
61 State (Map.insert name (A.A region tipe) headers) vars revCons
64 do let (State headers vars revCons) = state
65 let unitCon = CPattern outerRegion context Error.PUnit region UnitN tipe
66 return $ State headers vars (unitCon:revCons)
68 Can.PTuple a b maybeC ->
69 addTupleConstraint outerRegion context region a b maybeC tipe state
71 Can.PCtor home typeName typeVars ctorName args ->
72 addCtorConstraint outerRegion context region home typeName typeVars ctorName args tipe state
75 do entryVar <- mkFlexVar
76 let entryVarN = VarN entryVar
77 let listType = AppN ModuleName.list N.list [entryVarN]
79 (State headers vars revCons) <-
80 foldM (addListConstraint region entryVarN) state (Index.indexedMap (,) patterns)
82 let listCon = CPattern outerRegion context Error.PList region listType tipe
83 return $ State headers (Bag.insert entryVar vars) (listCon:revCons)
85 Can.PCons headPattern tailPattern ->
86 do entryVar <- mkFlexVar
87 let entryType = VarN entryVar
88 let listType = AppN ModuleName.list N.list [entryType]
90 (State headers vars revCons) <-
91 addConstraints region Error.PatternHead headPattern entryType =<<
92 addConstraints region Error.PatternTail tailPattern listType state
94 let listCon = CPattern outerRegion context Error.PList region listType tipe
95 return $ State headers (Bag.insert entryVar vars) (listCon : revCons)
98 do extVar <- mkFlexVar
99 let extType = VarN extVar
101 fieldVars <- traverse (\field -> (,) field <$> mkFlexVar) fields
102 let fieldTypes = Map.fromList (map (fmap VarN) fieldVars)
103 let recordType = RecordN fieldTypes extType
105 let (State headers vars revCons) = state
106 let recordCon = CPattern outerRegion context Error.PRecord region recordType tipe
109 { _headers = Map.union headers (Map.map (A.A region) fieldTypes)
110 , _vars = Bag.insert extVar (Bag.append vars (Bag.fromList snd fieldVars))
111 , _revCons = recordCon : revCons
115 do let (State headers vars revCons) = state
116 let intCon = CPattern outerRegion context Error.PInt region T.int tipe
117 return $ State headers vars (intCon:revCons)
120 do let (State headers vars revCons) = state
121 let strCon = CPattern outerRegion context Error.PStr region T.string tipe
122 return $ State headers vars (strCon:revCons)
125 do let (State headers vars revCons) = state
126 let chrCon = CPattern outerRegion context Error.PChr region T.char tipe
127 return $ State headers vars (chrCon:revCons)
136addListConstraint :: R.Region -> Type -> State -> (Index.ZeroBased, Can.Pattern) -> IO State
137addListConstraint listRegion tipe state (index, pattern) =
138 addConstraints listRegion (Error.PatternList index) pattern tipe state
147 -> Error.PatternContext
155addTupleConstraint parentRegion context tupleRegion a b maybeC tipe (State headers vars revCons) =
158 let aVarN = VarN aVar
159 let bVarN = VarN bVar
161 let equal = CPattern parentRegion context Error.PTuple tupleRegion
162 let addCon = addConstraints tupleRegion Error.PatternUnknown
166 do let tupleCon = equal (TupleN aVarN bVarN Nothing) tipe
167 let newVars = Bag.insert aVar (Bag.insert bVar vars)
169 addCon a aVarN (State headers newVars (tupleCon:revCons))
173 let cVarN = VarN cVar
174 let tupleCon = equal (TupleN aVarN bVarN (Just cVarN)) tipe
175 let newVars = Bag.insert aVar (Bag.insert bVar (Bag.insert cVar vars))
178 addCon a aVarN (State headers newVars (tupleCon:revCons))
182-- CONSTRAIN CONSTRUCTORS
187 -> Error.PatternContext
189 -> ModuleName.Canonical
193 -> [Can.PatternCtorArg]
197addCtorConstraint outerRegion context ctorRegion home typeName typeVarNames ctorName args tipe state =
198 do varPairs <- traverse (\var -> (,) var <$> nameToFlex var) typeVarNames
199 let typePairs = map (second VarN) varPairs
200 let freeVarDict = Map.fromList typePairs
202 (State headers vars revCons) <-
203 foldM (addCtorArgConstraint ctorRegion ctorName freeVarDict) state args
205 let ctorType = AppN home typeName (map snd typePairs)
206 let ctorCon = CPattern outerRegion context (Error.PCtor ctorName) ctorRegion ctorType tipe
211 , _vars = Bag.append vars (Bag.fromList snd varPairs)
212 , _revCons = ctorCon : revCons
216addCtorArgConstraint :: R.Region -> N.Name -> Map.Map N.Name Type -> State -> Can.PatternCtorArg -> IO State
217addCtorArgConstraint ctorRegion ctorName freeVarDict state (Can.PatternCtorArg index srcType pattern) =
218 do tipe <- Instantiate.fromSrcType freeVarDict srcType
219 addConstraints ctorRegion (Error.PatternCtorArg ctorName index) pattern tipe 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