@@ -237,34 +237,17 @@ constrainList env region exprs tipe =
237 do (exprInfo, exprCons) <-
237 do (exprInfo, exprCons) <-
238 unzip <$> mapM elementConstraint exprs
238 unzip <$> mapM elementConstraint exprs
240− let pairwiseCons = pairwiseConstraints 2 exprInfo
240+ (vars, cons) <- pairCons region Error.ListElement varToCon exprInfo
243− ex (map fst exprInfo)
244− (CAnd (exprCons ++ pairwiseCons))
242+ return $ ex vars (CAnd (exprCons ++ cons))
247− Env.get env Env.types "List" <| t
249 elementConstraint expr@(A.A region' _) =
244 elementConstraint expr@(A.A region' _) =
250 do var <- variable Flexible
245 do var <- variable Flexible
251 con <- constrain env expr (varN var)
246 con <- constrain env expr (varN var)
252 return ( (var, region'), con )
247 return ( (var, region'), con )
254− pairwiseConstraints n exprInfo =
249+ varToCon var =
260− [ CEqual Error.List region tipe (list (varN var)) ]
250+ CEqual Error.List region tipe (Env.get env Env.types "List" <| varN var)
262− (var,_) : (var',region') : rest ->
264− hint = Error.ListElement n region'
265− con = CEqual hint region (varN var) (varN var')
267− con : pairwiseConstraints (n+1) ((var', region') : rest)
270-- CONSTRAIN IF EXPRESSIONS
253-- CONSTRAIN IF EXPRESSIONS
@@ -279,9 +262,9 @@ constrainIf env region branches tipe =
279 do (branchInfo, branchExprCons) <-
262 do (branchInfo, branchExprCons) <-
280 unzip <$> mapM constrainBranch branches
263 unzip <$> mapM constrainBranch branches
282− return $
265+ (vars,cons) <- branchCons branchInfo
283− ex (map fst branchInfo)
266+
284− (CAnd (branchExprCons ++ branchCons branchInfo))
267+ return $ ex vars (CAnd (branchExprCons ++ cons))
286 bool = Env.get env Env.types "Bool"
269 bool = Env.get env Env.types "Bool"
@@ -297,27 +280,18 @@ constrainIf env region branches tipe =
297 branchCons branchInfo =
280 branchCons branchInfo =
298 case branchInfo of
281 case branchInfo of
299 [(thenVar, _), (elseVar, _)] ->
282 [(thenVar, _), (elseVar, _)] ->
300− [ CEqual Error.IfBranches region (varN thenVar) (varN elseVar)
285+ , [ CEqual Error.IfBranches region (varN thenVar) (varN elseVar)
301− , CEqual Error.If region tipe (varN thenVar)
286+ , varToCon thenVar
305− buildBranchCons 2 branchInfo
291+ pairCons region Error.MultiIfBranch varToCon branchInfo
307− buildBranchCons n branchInfo =
312− (var,_) : [] ->
293+ varToCon var =
313− [ CEqual Error.If region tipe (varN var) ]
294+ CEqual Error.If region tipe (varN var)
315− (var,_) : (var',region') : rest ->
317− hint = Error.MultiIfBranch n region'
318− con = CEqual hint region (varN var) (varN var')
320− con : buildBranchCons (n+1) ((var', region') : rest)
323-- CONSTRAIN CASE EXPRESSIONS
297-- CONSTRAIN CASE EXPRESSIONS
@@ -331,15 +305,14 @@ constrainCase
331 -> IO TypeConstraint
305 -> IO TypeConstraint
332constrainCase env region expr branches tipe =
306constrainCase env region expr branches tipe =
333 do exprVar <- variable Flexible
307 do exprVar <- variable Flexible
335 exprCon <- constrain env expr (varN exprVar)
308 exprCon <- constrain env expr (varN exprVar)
337 (branchInfo, branchExprCons) <-
310 (branchInfo, branchExprCons) <-
338 unzip <$> mapM (branch (varN exprVar)) branches
311 unzip <$> mapM (branch (varN exprVar)) branches
340− return $
313+ (vars, cons) <- pairCons region Error.CaseBranch varToCon branchInfo
341− ex (exprVar : map fst branchInfo)
314+
342− (CAnd (exprCon : branchExprCons ++ branchCons 2 branchInfo))
315+ return $ ex (exprVar : vars) (CAnd (exprCon : branchExprCons ++ cons))
344 branch patternType (pattern, branchExpr@(A.A branchRegion _)) =
317 branch patternType (pattern, branchExpr@(A.A branchRegion _)) =
345 do branchVar <- variable Flexible
318 do branchVar <- variable Flexible
@@ -350,20 +323,52 @@ constrainCase env region expr branches tipe =
350 , CLet [Fragment.toScheme fragment] branchCon
323 , CLet [Fragment.toScheme fragment] branchCon
353− branchCons n branchInfo =
326+ varToCon var =
354− case branchInfo of
327+ CEqual Error.Case region tipe (varN var)
359− [ CEqual Error.Case region tipe (varN var) ]
361− (var,_) : (var',region') : rest ->
330+-- COLLECT PAIRS
336+ , _region :: R.Region
342+ -> (Int -> R.Region -> Error.Hint)
343+ -> (Variable -> TypeConstraint)
344+ -> [(Variable, R.Region)]
345+ -> IO ([Variable], [TypeConstraint])
346+pairCons region pairHint varToCon items =
363− hint = Error.CaseBranch n region'
348+ pairToCon (Pair index var1 var2 subregion) =
364− con = CEqual hint region (varN var) (varN var')
349+ CEqual (pairHint index subregion) region (varN var1) (varN var2)
366− con : branchCons (n+1) ((var', region') : rest)
351+ case collectPairs 2 items of
353+ do var <- variable Flexible
354+ return ([var], [varToCon var])
356+ Just (pairs, var) ->
357+ return (map fst items, map pairToCon pairs ++ [varToCon var])
360+collectPairs :: Int -> [(Variable, R.Region)] -> Maybe ([Pair], Variable)
361+collectPairs index items =
369+ (var,_) : rest@((var',region) : _) ->
370+ do (pairs, summaryVar) <- collectPairs (index+1) rest
371+ return (Pair index var var' region : pairs, summaryVar)
369-- EXPAND PATTERNS
374-- EXPAND PATTERNS