@@ -105,14 +105,7 @@ constrain env (A.A region expression) tipe =
105105 return (funcCon /\ argCon)
106106
107107 E.MultiIf branches ->
108− CAnd <$> mapM constrain' branches
109− where
110− bool = Env.get env Env.types "Bool"
111−
112− constrain' (cond, expr) =
113− do cb <- constrain env cond bool
114− ce <- constrain env expr tipe
115− return (cb /\ ce)
108+ constrainIf env region branches tipe
116109
117110 E.Case expr branches ->
118111 constrainCase env region expr branches tipe
@@ -194,6 +187,59 @@ constrain env (A.A region expression) tipe =
194187 constrain env expr tipe
195188
196189
190+-- CONSTRAIN IF EXPRESSIONS
191+
192+constrainIf
193+ :: Env.Environment
194+ -> R.Region
195+ -> [(Canonical.Expr, Canonical.Expr)]
196+ -> Type
197+ -> IO TypeConstraint
198+constrainIf env region branches tipe =
199+ do (branchInfo, branchExprCons) <-
200+ unzip <$> mapM constrainBranch branches
201+
202+ return $
203+ ex (map fst branchInfo)
204+ (CAnd (branchExprCons ++ branchCons branchInfo))
205+ where
206+ bool = Env.get env Env.types "Bool"
207+
208+ constrainBranch (cond, expr@(A.A branchRegion _)) =
209+ do branchVar <- variable Flexible
210+ condCon <- constrain env cond bool
211+ exprCon <- constrain env expr (varN branchVar)
212+ return
213+ ( (branchVar, branchRegion)
214+ , condCon /\ exprCon
215+ )
216+
217+ branchCons branchInfo =
218+ case branchInfo of
219+ [(thenVar, _), (elseVar, _)] ->
220+ [ CEqual Error.IfBranches region (varN thenVar) (varN elseVar)
221+ , CEqual Error.If region tipe (varN thenVar)
222+ ]
223+
224+ _ ->
225+ buildBranchCons 2 branchInfo
226+
227+ buildBranchCons n branchInfo =
228+ case branchInfo of
229+ [] ->
230+ []
231+
232+ (var,_) : [] ->
233+ [ CEqual Error.If region tipe (varN var) ]
234+
235+ (var,_) : (var',region') : rest ->
236+ let
237+ hint = Error.MultiIfBranch n region'
238+ con = CEqual hint region (varN var) (varN var')
239+ in
240+ con : buildBranchCons (n+1) ((var', region') : rest)
241+
242+
197243-- CONSTRAIN CASE EXPRESSIONS
198244
199245constrainCase