@@ -23,12 +23,14 @@ mistakes :: [D.ValidDecl] -> [Doc]
23mistakes decls =
23mistakes decls =
25 [ infiniteTypeAliases decls
25 [ infiniteTypeAliases decls
26− , illFormedTypes decls
26+ , illFormedTypeDecls decls
27 , map P.text (duplicateTypeDeclarations decls)
27 , map P.text (duplicateTypeDeclarations decls)
28 , map P.text (duplicateValues decls)
28 , map P.text (duplicateValues decls)
32dups :: Ord a => [a] -> [a]
34dups :: Ord a => [a] -> [a]
33dups names =
35dups names =
34 List.sort names
36 List.sort names
@@ -97,82 +99,118 @@ dupCtorError name =
97 ++ " something should be renamed or moved to a different module."
99 ++ " something should be renamed or moved to a different module."
102+-- FREE TYPE VARIABLES IN TYPE DECLARATIONS
100−illFormedTypes :: [D.ValidDecl] -> [Doc]
104+illFormedTypeDecls :: [D.ValidDecl] -> [Doc]
105+illFormedTypeDecls decls =
101−illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
106+ map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
103− aliases = [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe) <- decls ]
109+ [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe) <- decls ]
104− adts = [ (decl, tvars, concatMap snd ctors) | decl@(D.Datatype _ tvars ctors) <- decls ]
112+ [ (decl, tvars, concatMap snd ctors) | decl@(D.Datatype _ tvars ctors) <- decls ]
106− freeVars tipe =
114+ freeVars tipe =
107− case tipe of
115+ case tipe of
108− T.Lambda t1 t2 -> Set.union (freeVars t1) (freeVars t2)
117+ Set.union (freeVars t1) (freeVars t2)
109− T.Var x -> Set.singleton x
120+ Set.singleton x
110− T.Type _ -> Set.empty
123+ Set.empty
111− T.App t ts -> Set.unions (map freeVars (t:ts))
126+ Set.unions (map freeVars (t:ts))
112− T.Record fields ext -> Set.unions (ext' : map (freeVars . snd) fields)
128+ T.Record fields ext ->
113− where ext' = maybe Set.empty freeVars ext
129+ let ext' = maybe Set.empty freeVars ext
114− T.Aliased _ t -> freeVars t
130+ in
115−
131+ Set.unions (ext' : map (freeVars . snd) fields)
116− undeclared tvars tipes = Set.difference used declared
118− used = Set.unions (map freeVars tipes)
119− declared = Set.fromList tvars
121− isIllFormed (decl, tvars, tipes) =
122− let unbound = undeclared tvars tipes in
123− if Set.null unbound then Nothing
124− else Just (decl, Set.toList unbound)
126− report (decl, tvars) =
127− P.vcat [ P.text $ "Error: type variable" ++ listing ++ " unbound in:"
129− , nest 4 (pretty decl) ]
133− [tvar] -> " " ++ quote tvar ++ " is"
134− _ -> "s" ++ addCommas (map ((++) " ") (addAnd (map quote tvars))) ++ " are"
137− | length xs < 3 = concat xs
138− | otherwise = List.intercalate "," xs
141− | length xs < 2 = xs
142− | otherwise = zipWith (++) (replicate (length xs - 1) "" ++ ["and "]) xs
144− quote tvar = "'" ++ tvar ++ "'"
136+ undeclared tvars tipes =
137+ Set.difference used declared
139+ used = Set.unions (map freeVars tipes)
140+ declared = Set.fromList tvars
142+ isIllFormed (decl, tvars, tipes) =
143+ let unbound = undeclared tvars tipes in
146+ else Just (decl, Set.toList unbound)
148+ report (decl, tvars) =
149+ P.vcat [ P.text $ "Error: type variable" ++ listing ++ " unbound in:"
151+ , nest 4 (pretty decl) ]
155+ [tvar] -> " " ++ quote tvar ++ " is"
156+ _ -> "s" ++ addCommas (map ((++) " ") (addAnd (map quote tvars))) ++ " are"
159+ | length xs < 3 = concat xs
160+ | otherwise = List.intercalate "," xs
163+ | length xs < 2 = xs
164+ | otherwise = zipWith (++) (replicate (length xs - 1) "" ++ ["and "]) xs
166+ quote tvar = "'" ++ tvar ++ "'"
169+-- INFINITE TYPE ALIASES
147infiniteTypeAliases :: [D.ValidDecl] -> [Doc]
171infiniteTypeAliases :: [D.ValidDecl] -> [Doc]
148infiniteTypeAliases decls =
172infiniteTypeAliases decls =
173+ [ report name tvars tipe
149− [ report name tvars tipe | D.TypeAlias name tvars tipe <- decls
174+ | D.TypeAlias name tvars tipe <- decls
150− , infiniteType name tipe ]
175+ , infiniteType name tipe
152− infiniteType :: String -> T.Type Var.Raw -> Bool
178+ infiniteType :: String -> T.Type Var.Raw -> Bool
153− infiniteType name tipe =
179+ infiniteType name tipe =
154− let infinite = infiniteType name in
180+ let infinite = infiniteType name in
155− case tipe of
181+ case tipe of
156− T.Lambda a b -> infinite a || infinite b
183+ infinite a || infinite b
157− T.Var _ -> False
185+ T.Var _ ->
158− T.Type (Var.Raw name') -> name == name'
188+ T.Type (Var.Raw name') ->
159− T.App t ts -> any infinite (t:ts)
192+ any infinite (t:ts)
194+ T.Record fields _ ->
160− T.Record fields _ -> any (infinite . snd) fields
195+ any (infinite . snd) fields
161− T.Aliased _ t -> infinite t
197+ T.Aliased _ t ->
163− indented :: D.ValidDecl -> Doc
200+ indented :: D.ValidDecl -> Doc
164− indented decl = P.text "\n " <> pretty decl <> P.text "\n"
202+ P.text "\n " <> pretty decl <> P.text "\n"
166− report name args tipe =
204+ report name args tipe =
168− [ P.text $ eightyCharLines 0 msg1
206+ [ P.text $ eightyCharLines 0 msg1
169− , indented $ D.TypeAlias name args tipe
207+ , indented $ D.TypeAlias name args tipe
170− , P.text $ eightyCharLines 0 Setup.typeAliasErrorSegue
208+ , P.text $ eightyCharLines 0 Setup.typeAliasErrorSegue
171− , indented $ D.Datatype name args [(name,[tipe])]
209+ , indented $ D.Datatype name args [(name,[tipe])]
172− , P.text $ eightyCharLines 0 Setup.typeAliasErrorExplanation ++ "\n"
210+ , P.text $ eightyCharLines 0 Setup.typeAliasErrorExplanation ++ "\n"
176− "Type alias '" ++ name ++ "' is an infinite type. " ++
214+ "Type alias '" ++ name ++ "' is an infinite type. " ++
177− "Notice that it appears in its own definition, so when \
215+ "Notice that it appears in its own definition, so when \
178− \you expand it, it just keeps getting bigger:"
216+ \you expand it, it just keeps getting bigger:"