1{-# OPTIONS_GHC -Wall #-}
2module Type.Constrain.Pattern
9import Control.Monad (foldM)
10import qualified Data.Map.Strict as Map
12import qualified AST.Expression.Canonical as Can
13import qualified AST.Module.Name as ModuleName
14import qualified Data.Bag as Bag
15import qualified Elm.Name as N
16import qualified Reporting.Annotation as A
17import qualified Reporting.Error.Type as Error
18import qualified Reporting.Region as R
20import qualified Type.Constrain.Literal as Literal
21import qualified Type.Instantiate as Instantiate
32constrain :: Env -> Can.Pattern -> Type -> IO (Map.Map N.Name (A.Located Type), [Variable], Constraint)
33constrain env pattern tipe =
34 do (Info headers vars cons) <-
35 addConstraints env Error.PatternUnknown pattern tipe $
36 Info Map.empty Bag.empty []
38 return ( headers, Bag.toList vars, CAnd (reverse cons) )
47 { _headers :: Map.Map N.Name (A.Located Type)
48 , _vars :: Bag.Bag Variable
49 , _cons :: [Constraint]
53addConstraints :: Env -> Error.PatternContext -> Can.Pattern -> Type -> Info -> IO Info
54addConstraints env context (A.A region pattern) tipe info =
60 do let (Info headers vars revCons) = info
61 litCon <- Literal.constrain region lit tipe
62 return $ Info headers vars (litCon:revCons)
65 do let (Info headers vars revCons) = info
66 let newHeaders = Map.insert name (A.A region tipe) headers
67 return $ Info newHeaders vars revCons
69 Can.PAlias realPattern name ->
70 do let (Info headers vars revCons) = info
71 addConstraints env context realPattern tipe $
72 Info (Map.insert name (A.A region tipe) headers) vars revCons
75 do let (Info headers vars revCons) = info
76 let unitCon = CEqual (Error.Pattern context Error.PUnit) region UnitN tipe
77 return $ Info headers vars (unitCon:revCons)
79 Can.PTuple a b maybeC ->
80 addTupleConstraint env context region a b maybeC tipe info
82 Can.PCtor home typeName vs ctorName args ->
83 do (Instantiate.Ctor tvars targs ttype) <- Instantiate.pattern home typeName vs args
85 (Info headers vars revCons) <-
86 foldM (addCtorConstraint env ctorName) info targs
91 , _vars = Bag.append vars (Bag.fromList id tvars)
93 CEqual (Error.Pattern context (Error.PCtor ctorName)) region ttype tipe
98 do entryVar <- mkFlexVar
99 let entryVarN = VarN entryVar
100 let listType = AppN ModuleName.list N.list [entryVarN]
102 (Info headers vars revCons) <-
104 (addListConstraint env entryVarN)
106 (zip patterns [ 1 .. length patterns ])
108 let listCon = CEqual (Error.Pattern context Error.PList) region listType tipe
109 return $ Info headers (Bag.insert entryVar vars) (listCon:revCons)
111 Can.PCons headPattern tailPattern ->
112 do headVar <- mkFlexVar
114 let headVarN = VarN headVar
115 let tailVarN = VarN tailVar
116 let tailType = AppN ModuleName.list N.list [tailVarN]
118 (Info headers vars revCons) <-
119 addConstraints env Error.PatternTail tailPattern tailType =<<
120 addConstraints env Error.PatternUnknown headPattern headVarN info
125 , _vars = Bag.insert headVar (Bag.insert tailVar vars)
127 CEqual (Error.Pattern context Error.PList) region tailType tipe
128 : CEqual Error.PatternCons region headVarN tailVarN
132 Can.PRecord fields ->
133 do extVar <- mkFlexVar
135 fieldVars <- traverse (\field -> (,) field <$> mkFlexVar) fields
136 let fieldVarN = Map.fromList (map (fmap VarN) fieldVars)
138 let (Info headers vars revCons) = info
141 { _headers = Map.union headers (Map.map (A.A region) fieldVarN)
142 , _vars = Bag.insert extVar (Bag.append vars (Bag.fromList snd fieldVars))
145 (Error.Pattern context Error.PRecord)
147 (RecordN fieldVarN (VarN extVar))
154-- CONSTRAIN CONSTRUCTORS
157addCtorConstraint :: Env -> N.Name -> Info -> (Int, Type, Can.Pattern) -> IO Info
158addCtorConstraint env name info (index, argType, argPattern) =
159 addConstraints env (Error.PatternArg name index) argPattern argType info
166addListConstraint :: Env -> Type -> Info -> (Can.Pattern, Int) -> IO Info
167addListConstraint env tipe info (pattern, index) =
168 addConstraints env (Error.PatternList index) pattern tipe info
177 -> Error.PatternContext
185addTupleConstraint env context region a b maybeC tipe (Info headers vars revCons) =
186 do let equal = CEqual (Error.Pattern context Error.PTuple) region
187 let addCon = addConstraints env Error.PatternUnknown
191 let aVarN = VarN aVar
192 let bVarN = VarN bVar
196 do let tupleCon = equal (TupleN aVarN bVarN Nothing) tipe
197 let newVars = Bag.insert aVar (Bag.insert bVar vars)
199 addCon a aVarN (Info headers newVars (tupleCon:revCons))
203 let cVarN = VarN cVar
204 let tupleCon = equal (TupleN aVarN bVarN (Just cVarN)) tipe
205 let newVars = Bag.insert aVar (Bag.insert bVar (Bag.insert cVar vars))
208 addCon a aVarN (Info headers newVars (tupleCon:revCons))
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