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
29constrain :: Can.Pattern -> Type -> IO (Map.Map N.Name (A.Located Type), [Variable], Constraint)
30constrain pattern tipe =
31 do (Info headers vars cons) <-
32 addConstraints Error.PatternUnknown pattern tipe $
33 Info Map.empty Bag.empty []
35 return ( headers, Bag.toList vars, CAnd (reverse cons) )
44 { _headers :: Map.Map N.Name (A.Located Type)
45 , _vars :: Bag.Bag Variable
46 , _cons :: [Constraint]
50addConstraints :: Error.PatternContext -> Can.Pattern -> Type -> Info -> IO Info
51addConstraints context (A.A region pattern) tipe info =
57 do let (Info headers vars revCons) = info
58 litCon <- Literal.constrain region lit tipe
59 return $ Info headers vars (litCon:revCons)
62 do let (Info headers vars revCons) = info
63 let newHeaders = Map.insert name (A.A region tipe) headers
64 return $ Info newHeaders vars revCons
66 Can.PAlias realPattern name ->
67 do let (Info headers vars revCons) = info
68 addConstraints context realPattern tipe $
69 Info (Map.insert name (A.A region tipe) headers) vars revCons
72 do let (Info headers vars revCons) = info
73 let unitCon = CEqual (Error.Pattern context Error.PUnit) region UnitN tipe
74 return $ Info headers vars (unitCon:revCons)
76 Can.PTuple a b maybeC ->
77 addTupleConstraint context region a b maybeC tipe info
79 Can.PCtor home typeName vs ctorName args ->
80 do (Instantiate.Ctor tvars targs ttype) <- Instantiate.pattern home typeName vs args
82 (Info headers vars revCons) <-
83 foldM (addCtorConstraint ctorName) info targs
88 , _vars = Bag.append vars (Bag.fromList id tvars)
90 CEqual (Error.Pattern context (Error.PCtor ctorName)) region ttype tipe
95 do entryVar <- mkFlexVar
96 let entryVarN = VarN entryVar
97 let listType = AppN ModuleName.list N.list [entryVarN]
99 (Info headers vars revCons) <-
101 (addListConstraint entryVarN)
103 (zip patterns [ 1 .. length patterns ])
105 let listCon = CEqual (Error.Pattern context Error.PList) region listType tipe
106 return $ Info headers (Bag.insert entryVar vars) (listCon:revCons)
108 Can.PCons headPattern tailPattern ->
109 do headVar <- mkFlexVar
111 let headVarN = VarN headVar
112 let tailVarN = VarN tailVar
113 let tailType = AppN ModuleName.list N.list [tailVarN]
115 (Info headers vars revCons) <-
116 addConstraints Error.PatternTail tailPattern tailType =<<
117 addConstraints Error.PatternUnknown headPattern headVarN info
122 , _vars = Bag.insert headVar (Bag.insert tailVar vars)
124 CEqual (Error.Pattern context Error.PList) region tailType tipe
125 : CEqual Error.PatternCons region headVarN tailVarN
129 Can.PRecord fields ->
130 do extVar <- mkFlexVar
132 fieldVars <- traverse (\field -> (,) field <$> mkFlexVar) fields
133 let fieldVarN = Map.fromList (map (fmap VarN) fieldVars)
135 let (Info headers vars revCons) = info
138 { _headers = Map.union headers (Map.map (A.A region) fieldVarN)
139 , _vars = Bag.insert extVar (Bag.append vars (Bag.fromList snd fieldVars))
142 (Error.Pattern context Error.PRecord)
144 (RecordN fieldVarN (VarN extVar))
151-- CONSTRAIN CONSTRUCTORS
154addCtorConstraint :: N.Name -> Info -> (Int, Type, Can.Pattern) -> IO Info
155addCtorConstraint name info (index, argType, argPattern) =
156 addConstraints (Error.PatternArg name index) argPattern argType info
163addListConstraint :: Type -> Info -> (Can.Pattern, Int) -> IO Info
164addListConstraint tipe info (pattern, index) =
165 addConstraints (Error.PatternList index) pattern tipe info
173 :: Error.PatternContext
181addTupleConstraint context region a b maybeC tipe (Info headers vars revCons) =
182 do let equal = CEqual (Error.Pattern context Error.PTuple) region
183 let addCon = addConstraints Error.PatternUnknown
187 let aVarN = VarN aVar
188 let bVarN = VarN bVar
192 do let tupleCon = equal (TupleN aVarN bVarN Nothing) tipe
193 let newVars = Bag.insert aVar (Bag.insert bVar vars)
195 addCon a aVarN (Info headers newVars (tupleCon:revCons))
199 let cVarN = VarN cVar
200 let tupleCon = equal (TupleN aVarN bVarN (Just cVarN)) tipe
201 let newVars = Bag.insert aVar (Bag.insert bVar (Bag.insert cVar vars))
204 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