1{-# OPTIONS_GHC -Wall #-}
2module Type.Constrain.Pattern
9import Control.Arrow (second)
10import Control.Monad (foldM)
11import qualified Data.Map.Strict as Map
13import qualified AST.Canonical as Can
14import qualified AST.Module.Name as ModuleName
15import qualified Data.Bag as Bag
16import qualified Data.Index as Index
17import qualified Elm.Name as N
18import qualified Reporting.Annotation as A
19import qualified Reporting.Error.Type as Error
20import qualified Reporting.Region as R
22import qualified Type.Instantiate as Instantiate
30-- The constraints are stored in reverse order so that adding a new
31-- constraint is O(1) and we can reverse it at some later time.
35 { _headers :: Map.Map N.Name (A.Located Type)
36 , _vars :: Bag.Bag Variable
37 , _revCons :: [Constraint]
41addConstraints :: R.Region -> Error.PatternContext -> Can.Pattern -> Type -> State -> IO State
42addConstraints outerRegion context (A.A region pattern) tipe state =
48 do let (State headers vars revCons) = state
49 let newHeaders = Map.insert name (A.A region tipe) headers
50 return $ State newHeaders vars revCons
52 Can.PAlias realPattern name ->
53 do let (State headers vars revCons) = state
54 addConstraints outerRegion context realPattern tipe $
55 State (Map.insert name (A.A region tipe) headers) vars revCons
58 do let (State headers vars revCons) = state
59 let unitCon = CPattern outerRegion context Error.PUnit region UnitN tipe
60 return $ State headers vars (unitCon:revCons)
62 Can.PTuple a b maybeC ->
63 addTupleConstraint outerRegion context region a b maybeC tipe state
65 Can.PCtor home typeName typeVars ctorName args ->
66 addCtorConstraint outerRegion context region home typeName typeVars ctorName args tipe state
69 do entryVar <- mkFlexVar
70 let entryVarN = VarN entryVar
71 let listType = AppN ModuleName.list N.list [entryVarN]
73 (State headers vars revCons) <-
74 foldM (addListConstraint region entryVarN) state (Index.indexedMap (,) patterns)
76 let listCon = CPattern outerRegion context Error.PList region listType tipe
77 return $ State headers (Bag.insert entryVar vars) (listCon:revCons)
79 Can.PCons headPattern tailPattern ->
80 do entryVar <- mkFlexVar
81 let entryType = VarN entryVar
82 let listType = AppN ModuleName.list N.list [entryType]
84 (State headers vars revCons) <-
85 addConstraints region Error.PatternHead headPattern entryType =<<
86 addConstraints region Error.PatternTail tailPattern listType state
88 let listCon = CPattern outerRegion context Error.PList region listType tipe
89 return $ State headers (Bag.insert entryVar vars) (listCon : revCons)
92 do extVar <- mkFlexVar
93 let extType = VarN extVar
95 fieldVars <- traverse (\field -> (,) field <$> mkFlexVar) fields
96 let fieldTypes = Map.fromList (map (fmap VarN) fieldVars)
97 let recordType = RecordN fieldTypes extType
99 let (State headers vars revCons) = state
100 let recordCon = CPattern outerRegion context Error.PRecord region recordType tipe
103 { _headers = Map.union headers (Map.map (A.A region) fieldTypes)
104 , _vars = Bag.insert extVar (Bag.append vars (Bag.fromList snd fieldVars))
105 , _revCons = recordCon : revCons
109 do let (State headers vars revCons) = state
110 let intCon = CPattern outerRegion context Error.PInt region T.int tipe
111 return $ State headers vars (intCon:revCons)
114 do let (State headers vars revCons) = state
115 let strCon = CPattern outerRegion context Error.PStr region T.string tipe
116 return $ State headers vars (strCon:revCons)
119 do let (State headers vars revCons) = state
120 let chrCon = CPattern outerRegion context Error.PChr region T.char tipe
121 return $ State headers vars (chrCon:revCons)
130addListConstraint :: R.Region -> Type -> State -> (Index.ZeroBased, Can.Pattern) -> IO State
131addListConstraint listRegion tipe state (index, pattern) =
132 addConstraints listRegion (Error.PatternList index) pattern tipe state
141 -> Error.PatternContext
149addTupleConstraint parentRegion context tupleRegion a b maybeC tipe (State headers vars revCons) =
152 let aVarN = VarN aVar
153 let bVarN = VarN bVar
155 let equal = CPattern parentRegion context Error.PTuple tupleRegion
156 let addCon = addConstraints tupleRegion Error.PatternUnknown
160 do let tupleCon = equal (TupleN aVarN bVarN Nothing) tipe
161 let newVars = Bag.insert aVar (Bag.insert bVar vars)
163 addCon a aVarN (State headers newVars (tupleCon:revCons))
167 let cVarN = VarN cVar
168 let tupleCon = equal (TupleN aVarN bVarN (Just cVarN)) tipe
169 let newVars = Bag.insert aVar (Bag.insert bVar (Bag.insert cVar vars))
172 addCon a aVarN (State headers newVars (tupleCon:revCons))
176-- CONSTRAIN CONSTRUCTORS
181 -> Error.PatternContext
183 -> ModuleName.Canonical
187 -> [Can.PatternCtorArg]
191addCtorConstraint outerRegion context ctorRegion home typeName typeVarNames ctorName args tipe state =
192 do varPairs <- traverse (\var -> (,) var <$> nameToFlex var) typeVarNames
193 let typePairs = map (second VarN) varPairs
194 let freeVarDict = Map.fromList typePairs
196 (State headers vars revCons) <-
197 foldM (addCtorArgConstraint ctorRegion ctorName freeVarDict) state args
199 let ctorType = AppN home typeName (map snd typePairs)
200 let ctorCon = CPattern outerRegion context (Error.PCtor ctorName) ctorRegion ctorType tipe
205 , _vars = Bag.append vars (Bag.fromList snd varPairs)
206 , _revCons = ctorCon : revCons
210addCtorArgConstraint :: R.Region -> N.Name -> Map.Map N.Name Type -> State -> Can.PatternCtorArg -> IO State
211addCtorArgConstraint ctorRegion ctorName freeVarDict state (Can.PatternCtorArg index srcType pattern) =
212 do tipe <- Instantiate.fromSrcType freeVarDict srcType
213 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