@@ -1,7 +1,9 @@
1+{-# OPTIONS_GHC -Wall #-}
1−module Type.Constrain.Pattern where
2+module Type.Constrain.Pattern (Info(..), infoToScheme, constrain) where
3import Control.Arrow (second)
4import Control.Arrow (second)
4import qualified Control.Monad as Monad
5import qualified Control.Monad as Monad
6+import qualified Data.List as List
5import qualified Data.Map as Map
7import qualified Data.Map as Map
7import qualified AST.Pattern as P
9import qualified AST.Pattern as P
@@ -10,11 +12,50 @@ import qualified Reporting.Annotation as A
10import qualified Reporting.Error.Type as Error
12import qualified Reporting.Error.Type as Error
11import qualified Type.Constrain.Literal as Literal
13import qualified Type.Constrain.Literal as Literal
12import qualified Type.Environment as Env
14import qualified Type.Environment as Env
14import Type.Type
15import Type.Type
24+ { _headers :: Map.Map String (A.Located Type)
25+ , _vars :: [Variable]
26+ , _cons :: TypeConstraint
32+ Info Map.empty [] CTrue
35+joinInfo :: Info -> Info -> Info
36+joinInfo (Info headers1 vars1 cons1) (Info headers2 vars2 cons2) =
38+ { _headers = Map.union headers1 headers2
39+ , _vars = vars1 ++ vars2
40+ , _cons = cons1 /\ cons2
44+joinInfos :: [Info] -> Info
46+ List.foldl' (flip joinInfo) emptyInfo infos
49+infoToScheme :: Info -> Scheme Type Variable
50+infoToScheme (Info headers vars cons) =
51+ Scheme [] vars cons headers
17−constrain :: Env.Environment -> P.Canonical -> Type -> IO Fragment
58+constrain :: Env.Environment -> P.Canonical -> Type -> IO Info
18constrain env (A.A region pattern) tipe =
59constrain env (A.A region pattern) tipe =
20 equal patternError leftType rightType =
61 equal patternError leftType rightType =
@@ -23,50 +64,49 @@ constrain env (A.A region pattern) tipe =
24 A.A region (VarN v)
65 A.A region (VarN v)
26− case pattern of
67+ case pattern of
27− P.Anything ->
68+ P.Anything ->
28− return emptyFragment
69+ return emptyInfo
30− P.Literal lit ->
71+ P.Literal lit ->
31 do c <- Literal.constrain env region lit tipe
72 do c <- Literal.constrain env region lit tipe
32− return $ emptyFragment { typeConstraint = c }
73+ return $ emptyInfo { _cons = c }
34− P.Var name ->
75+ P.Var name ->
35 do variable <- mkVar Nothing
76 do variable <- mkVar Nothing
36− return $ Fragment
77+ return $ Info
37− { typeEnv = Map.singleton name (rvar variable)
78+ { _headers = Map.singleton name (rvar variable)
38− , vars = [variable]
79+ , _vars = [variable]
40− equal (Error.PVar name) (VarN variable) tipe
80+ , _cons = equal (Error.PVar name) (VarN variable) tipe
43− P.Alias name p ->
83+ P.Alias name ptrn ->
44 do variable <- mkVar Nothing
84 do variable <- mkVar Nothing
45− fragment <- constrain env p tipe
85+ info <- constrain env ptrn tipe
46− return $ fragment
86+ return $ info
47− { typeEnv = Map.insert name (rvar variable) (typeEnv fragment)
87+ { _headers = Map.insert name (rvar variable) (_headers info)
48− , vars = variable : vars fragment
88+ , _vars = variable : _vars info
49− , typeConstraint =
89+ , _cons =
50 equal (Error.PAlias name) (VarN variable) tipe
90 equal (Error.PAlias name) (VarN variable) tipe
51− /\ typeConstraint fragment
91+ /\ _cons info
54− P.Data name patterns ->
94+ P.Data name patterns ->
55 do let stringName = V.toString name
95 do let stringName = V.toString name
57 (_kind, cvars, args, result) <-
97 (_kind, cvars, args, result) <-
58 Env.freshDataScheme env stringName
98 Env.freshDataScheme env stringName
60 fragList <- Monad.zipWithM (constrain env) patterns args
100 fragList <- Monad.zipWithM (constrain env) patterns args
61− let fragment = joinFragments fragList
101+ let info = joinInfos fragList
62− return $ fragment
102+ return $ info
63− { vars = cvars ++ vars fragment
103+ { _vars = cvars ++ _vars info
64− , typeConstraint =
104+ , _cons =
65− typeConstraint fragment
66− /\ equal (Error.PData stringName) tipe result
105+ equal (Error.PData stringName) result tipe
69− P.Record fields ->
109+ P.Record fields ->
70 do pairs <-
110 do pairs <-
71 mapM (\name -> (,) name <$> mkVar Nothing) fields
111 mapM (\name -> (,) name <$> mkVar Nothing) fields
@@ -79,8 +119,8 @@ constrain env (A.A region pattern) tipe =
79 con <- exists $ \t ->
119 con <- exists $ \t ->
80 return (equal Error.PRecord tipe (record unannotatedTenv t))
120 return (equal Error.PRecord tipe (record unannotatedTenv t))
82− return $ Fragment
122+ return $ Info
83− { typeEnv = tenv
123+ { _headers = tenv
84− , vars = map snd pairs
124+ , _vars = map snd pairs
85− , typeConstraint = con
125+ , _cons = con