@@ -13,6 +13,8 @@ import qualified AST.Pattern as P
1313import qualified AST.Type as ST
1414import qualified AST.Variable as V
1515import qualified Reporting.Annotation as A
16+import qualified Reporting.Error.Type as Error
17+import qualified Reporting.Region as R
1618import qualified Type.Constrain.Literal as Literal
1719import qualified Type.Constrain.Pattern as Pattern
1820import qualified Type.Environment as Env
@@ -27,7 +29,7 @@ constrain
2729 -> IO TypeConstraint
2830constrain env (A.A region expression) tipe =
2931 let list t = Env.get env Env.types "List" <| t
30− (===) = CEqual region
32+ (===) = CEqual Error.None region
3133 (<?) = CInstance region
3234 in
3335 case expression of
@@ -113,15 +115,7 @@ constrain env (A.A region expression) tipe =
113115 return (cb /\ ce)
114116
115117 E.Case expr branches ->
116− exists $ \t ->
117− do exprConstraint <- constrain env expr t
118− branchConstraints <- mapM (branch t) branches
119− return (CAnd (exprConstraint : branchConstraints))
120− where
121− branch t (pattern, branchExpr) =
122− do fragment <- Pattern.constrain env pattern t
123− branchConstraint <- constrain env branchExpr tipe
124− return (CLet [Fragment.toScheme fragment] branchConstraint)
118+ constrainCase env region expr branches tipe
125119
126120 E.Data name exprs ->
127121 do vars <- Monad.forM exprs $ \_ -> variable Flexible
@@ -200,6 +194,46 @@ constrain env (A.A region expression) tipe =
200194 constrain env expr tipe
201195
202196
197+-- CONSTRAIN CASE EXPRESSIONS
198+
199+constrainCase
200+ :: Env.Environment
201+ -> R.Region
202+ -> Canonical.Expr
203+ -> [(P.CanonicalPattern, Canonical.Expr)]
204+ -> Type
205+ -> IO TypeConstraint
206+constrainCase env region expr branches tipe =
207+ do exprVar <- variable Flexible
208+
209+ exprCon <- constrain env expr (varN exprVar)
210+
211+ (branchVars, regions, branchExprCons) <-
212+ unzip3 <$> mapM (branch (varN exprVar)) branches
213+
214+ let branchCons =
215+ zipWith3 branchEqual [1..] branchVars regions
216+
217+ return $
218+ ex (exprVar:branchVars)
219+ (CAnd (exprCon : branchExprCons ++ branchCons))
220+ where
221+ branch patternType (pattern, branchExpr@(A.A branchRegion _)) =
222+ do branchVar <- variable Flexible
223+ fragment <- Pattern.constrain env pattern patternType
224+ branchCon <- constrain env branchExpr (varN branchVar)
225+ return
226+ ( branchVar
227+ , branchRegion
228+ , CLet [Fragment.toScheme fragment] branchCon
229+ )
230+
231+ branchEqual n var branchRegion =
232+ CEqual (Error.CaseBranch n branchRegion) region tipe (varN var)
233+
234+
235+-- EXPAND PATTERNS
236+
203237expandPattern :: Canonical.Def -> [Canonical.Def]
204238expandPattern def@(Canonical.Definition lpattern expr maybeType) =
205239 let (A.A patternRegion pattern) = lpattern