@@ -9,6 +9,7 @@ import AST.PrettyPrint
99import qualified AST.Helpers as Help
1010import Text.PrettyPrint as P
1111
12+
1213data Type var
1314 = Lambda (Type var) (Type var)
1415 | Var String
@@ -18,47 +19,64 @@ data Type var
1819 | Aliased Var.Canonical (Type var)
1920 deriving (Eq,Show)
2021
21−type RawType = Type Var.Raw
22−type CanonicalType = Type Var.Canonical
22+
23+type RawType =
24+ Type Var.Raw
25+
26+
27+type CanonicalType =
28+ Type Var.Canonical
29+
2330
2431fieldMap :: [(String,a)] -> Map.Map String [a]
2532fieldMap fields =
26− foldl (\r (x,t) -> Map.insertWith (++) x [t] r) Map.empty fields
33+ foldl (\r (field,tipe) -> Map.insertWith (++) field [tipe] r) Map.empty fields
34+
2735
2836recordOf :: [(String, Type var)] -> Type var
29−recordOf fields = Record fields Nothing
37+recordOf fields =
38+ Record fields Nothing
39+
3040
3141listOf :: RawType -> RawType
32−listOf t = App (Type (Var.Raw "List")) [t]
42+listOf tipe =
43+ App (Type (Var.Raw "List")) [tipe]
44+
3345
3446tupleOf :: [RawType] -> RawType
35−tupleOf ts = App (Type t) ts
36− where
37− t = Var.Raw ("_Tuple" ++ show (length ts))
47+tupleOf types =
48+ let name = Var.Raw ("_Tuple" ++ show (length types))
49+ in
50+ App (Type name) types
51+
3852
3953instance (Var.ToString var, Pretty var) => Pretty (Type var) where
4054 pretty tipe =
4155 case tipe of
42− Lambda _ _ -> P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
56+ Lambda _ _ ->
57+ P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
4358 where
4459 t:ts = map prettyLambda (collectLambdas tipe)
45− prettyLambda t = case t of
46− Lambda _ _ -> P.parens (pretty t)
47− _ -> pretty t
60+ prettyLambda t =
61+ case t of
62+ Lambda _ _ -> P.parens (pretty t)
63+ _ -> pretty t
4864
49− Var x -> P.text x
65+ Var x ->
66+ P.text x
5067
5168 Type var ->
52− let v = Var.toString var in
53− P.text (if v == "_Tuple0" then "()" else v)
69+ let v = Var.toString var
70+ in
71+ P.text (if v == "_Tuple0" then "()" else v)
5472
5573 App f args ->
5674 case (f,args) of
5775 (Type name, _)
5876 | Help.isTuple (Var.toString name) ->
59− P.parens . P.sep . P.punctuate P.comma $ map pretty args
77+ P.parens (P.sep (P.punctuate P.comma (map pretty args)))
6078
61− _ -> P.hang (pretty f) 2 (P.sep $ map prettyParens args)
79+ _ -> P.hang (pretty f) 2 (P.sep (map prettyParens args))
6280
6381 Record _ _ ->
6482 case flattenRecord tipe of
@@ -84,20 +102,26 @@ instance (Var.ToString var, Pretty var) => Pretty (Type var) where
84102 P.text field <+> P.text ":" <+> pretty tipe
85103
86104 Aliased name t ->
87− let t' = pretty t in
88− if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
89− then t'
90− else pretty name
105+ let t' = pretty t
106+ in
107+ if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
108+ then t'
109+ else pretty name
91110
92111
93112collectLambdas :: Type var -> [Type var]
94113collectLambdas tipe =
95114 case tipe of
96− Lambda arg body -> arg : collectLambdas body
97− _ -> [tipe]
115+ Lambda arg body ->
116+ arg : collectLambdas body
117+
118+ _ ->
119+ [tipe]
120+
98121
99122prettyParens :: (Var.ToString var, Pretty var) => Type var -> Doc
100−prettyParens tipe = parensIf (needed tipe) (pretty tipe)
123+prettyParens tipe =
124+ parensIf (needed tipe) (pretty tipe)
101125 where
102126 needed t =
103127 case t of
@@ -105,26 +129,37 @@ prettyParens tipe = parensIf (needed tipe) (pretty tipe)
105129
106130 Lambda _ _ -> True
107131
108− App (Type name) _ | Help.isTuple (Var.toString name) -> False
132+ App (Type name) _
133+ | Help.isTuple (Var.toString name) ->
134+ False
135+
109136 App t' [] -> needed t'
137+
110138 App _ _ -> True
111139
112140 _ -> False
113141
142+
114143flattenRecord :: Type var -> ( [(String, Type var)], Maybe String )
115144flattenRecord tipe =
116− case tipe of
117− Var x -> ([], Just x)
145+ case tipe of
146+ Var x ->
147+ ([], Just x)
148+
149+ Record fields Nothing ->
150+ (fields, Nothing)
118151
119− Record fields Nothing -> (fields, Nothing)
152+ Record fields (Just ext) ->
153+ let (fields',ext') = flattenRecord ext
154+ in
155+ (fields' ++ fields, ext')
120156
121− Record fields (Just ext) ->
122− let (fields',ext') = flattenRecord ext
123− in (fields' ++ fields, ext')
157+ Aliased _ tipe' ->
158+ flattenRecord tipe'
124159
125− Aliased _ tipe' -> flattenRecord tipe'
160+ _ ->
161+ error "Trying to flatten ill-formed record."
126162
127− _ -> error "Trying to flatten ill-formed record."
128163
129164instance Binary var => Binary (Type var) where
130165 put tipe =