2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[PatSyntax]{Abstract Haskell syntax---patterns}
7 #include "HsVersions.h"
13 irrefutablePat, irrefutablePats,
15 patsAreAllCons, isConPat,
16 patsAreAllLits, isLitPat,
23 -- IMPORT_DELOOPER(IdLoop)
24 import HsBasic ( HsLit )
25 import HsExpr ( HsExpr )
26 import BasicTypes ( Fixity )
29 import Id ( SYN_IE(Id), dataConTyCon, GenId )
30 import Maybes ( maybeToBool )
31 import Outputable ( PprStyle(..), userStyle, interppSP,
32 interpp'SP, ifPprShowAll, Outputable(..)
35 import TyCon ( maybeTyConSingleCon )
36 import PprType ( GenType )
37 import CmdLineOpts ( opt_PprUserLength )
38 #if __GLASGOW_HASKELL__ >= 202
43 Patterns come in distinct before- and after-typechecking flavo(u)rs.
46 = WildPatIn -- wild card
47 | VarPatIn name -- variable
48 | LitPatIn HsLit -- literal
49 | LazyPatIn (InPat name) -- lazy pattern
50 | AsPatIn name -- as pattern
52 | ConPatIn name -- constructed type
54 | ConOpPatIn (InPat name)
56 Fixity -- c.f. OpApp in HsExpr
59 | NPlusKPatIn name -- n+k pattern
62 -- We preserve prefix negation and parenthesis for the precedence parser.
64 | NegPatIn (InPat name) -- negated pattern
65 | ParPatIn (InPat name) -- parenthesised pattern
67 | ListPatIn [InPat name] -- syntactic list
68 -- must have >= 1 elements
69 | TuplePatIn [InPat name] -- tuple
71 | RecPatIn name -- record
72 [(name, InPat name, Bool)] -- True <=> source used punning
74 data OutPat tyvar uvar id
75 = WildPat (GenType tyvar uvar) -- wild card
77 | VarPat id -- variable (type is in the Id)
79 | LazyPat (OutPat tyvar uvar id) -- lazy pattern
81 | AsPat id -- as pattern
82 (OutPat tyvar uvar id)
84 | ConPat Id -- Constructor is always an Id
85 (GenType tyvar uvar) -- the type of the pattern
86 [OutPat tyvar uvar id]
88 | ConOpPat (OutPat tyvar uvar id) -- just a special case...
90 (OutPat tyvar uvar id)
92 | ListPat -- syntactic list
93 (GenType tyvar uvar) -- the type of the elements
94 [OutPat tyvar uvar id]
96 | TuplePat [OutPat tyvar uvar id] -- tuple
97 -- UnitPat is TuplePat []
99 | RecPat Id -- record constructor
100 (GenType tyvar uvar) -- the type of the pattern
101 [(Id, OutPat tyvar uvar id, Bool)] -- True <=> source used punning
103 | LitPat -- Used for *non-overloaded* literal patterns:
104 -- Int#, Char#, Int, Char, String, etc.
106 (GenType tyvar uvar) -- type of pattern
108 | NPat -- Used for *overloaded* literal patterns
109 HsLit -- the literal is retained so that
110 -- the desugarer can readily identify
111 -- equations with identical literal-patterns
112 (GenType tyvar uvar) -- type of pattern, t
113 (HsExpr tyvar uvar id (OutPat tyvar uvar id))
114 -- of type t -> Bool; detects match
117 HsLit -- Same reason as for LitPat
118 -- (This could be an Integer, but then
119 -- it's harder to partitionEqnsByLit
120 -- in the desugarer.)
121 (GenType tyvar uvar) -- Type of pattern, t
122 (HsExpr tyvar uvar id (OutPat tyvar uvar id)) -- Of type t -> Bool; detects match
123 (HsExpr tyvar uvar id (OutPat tyvar uvar id)) -- Of type t -> t; subtracts k
125 | DictPat -- Used when destructing Dictionaries with an explicit case
126 [id] -- superclass dicts
130 Now name in Inpat is not need to be in NAmedThing to be Outputable.
131 Needed by ../deSugar/Check.lhs
136 instance (Outputable name) => Outputable (InPat name) where
139 pprInPat :: (Outputable name) => PprStyle -> InPat name -> Doc
141 pprInPat sty (WildPatIn) = char '_'
142 pprInPat sty (VarPatIn var) = ppr sty var
143 pprInPat sty (LitPatIn s) = ppr sty s
144 pprInPat sty (LazyPatIn pat) = (<>) (char '~') (ppr sty pat)
145 pprInPat sty (AsPatIn name pat)
146 = parens (hcat [ppr sty name, char '@', ppr sty pat])
148 pprInPat sty (ConPatIn c pats)
152 hsep [ppr sty c, interppSP sty pats] -- ParPats put in the parens
154 pprInPat sty (ConOpPatIn pat1 op fixity pat2)
155 = hsep [ppr sty pat1, ppr sty op, ppr sty pat2] -- ParPats put in parens
157 -- ToDo: use pprSym to print op (but this involves fiddling various
158 -- contexts & I'm lazy...); *PatIns are *rarely* printed anyway... (WDP)
160 pprInPat sty (NegPatIn pat)
162 pp_pat = pprInPat sty pat
170 pprInPat sty (ParPatIn pat)
171 = parens (pprInPat sty pat)
173 pprInPat sty (ListPatIn pats)
174 = brackets (interpp'SP sty pats)
175 pprInPat sty (TuplePatIn pats)
176 = parens (interpp'SP sty pats)
177 pprInPat sty (NPlusKPatIn n k)
178 = parens (hcat [ppr sty n, char '+', ppr sty k])
180 pprInPat sty (RecPatIn con rpats)
181 = hsep [ppr sty con, braces (hsep (punctuate comma (map (pp_rpat sty) rpats)))]
183 pp_rpat sty (v, _, True) | userStyle sty = ppr (PprForUser opt_PprUserLength) v
184 pp_rpat sty (v, p, _) = hsep [ppr sty v, char '=', ppr sty p]
188 instance (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar, Outputable id)
189 => Outputable (OutPat tyvar uvar id) where
194 pprOutPat sty (WildPat ty) = char '_'
195 pprOutPat sty (VarPat var) = ppr sty var
196 pprOutPat sty (LazyPat pat) = hcat [char '~', ppr sty pat]
197 pprOutPat sty (AsPat name pat)
198 = parens (hcat [ppr sty name, char '@', ppr sty pat])
200 pprOutPat sty (ConPat name ty [])
201 = (<>) (ppr sty name)
202 (ifPprShowAll sty (pprConPatTy sty ty))
204 pprOutPat sty (ConPat name ty pats)
205 = hcat [parens (hcat [ppr sty name, space, interppSP sty pats]),
206 ifPprShowAll sty (pprConPatTy sty ty) ]
208 pprOutPat sty (ConOpPat pat1 op pat2 ty)
209 = parens (hcat [ppr sty pat1, space, ppr sty op, space, ppr sty pat2])
211 pprOutPat sty (ListPat ty pats)
212 = brackets (interpp'SP sty pats)
213 pprOutPat sty (TuplePat pats)
214 = parens (interpp'SP sty pats)
216 pprOutPat sty (RecPat con ty rpats)
217 = hcat [ppr sty con, braces (hsep (punctuate comma (map (pp_rpat sty) rpats)))]
219 pp_rpat sty (v, _, True) | userStyle sty = ppr (PprForUser opt_PprUserLength) v
220 pp_rpat sty (v, p, _) = hsep [ppr sty v, char '=', ppr sty p]
222 pprOutPat sty (LitPat l ty) = ppr sty l -- ToDo: print more
223 pprOutPat sty (NPat l ty e) = ppr sty l -- ToDo: print more
224 pprOutPat sty (NPlusKPat n k ty e1 e2) -- ToDo: print more
225 = parens (hcat [ppr sty n, char '+', ppr sty k])
227 pprOutPat sty (DictPat dicts methods)
228 = parens (sep [ptext SLIT("{-dict-}"),
229 brackets (interpp'SP sty dicts),
230 brackets (interpp'SP sty methods)])
233 = parens (ppr sty ty)
236 %************************************************************************
238 %* predicates for checking things about pattern-lists in EquationInfo *
240 %************************************************************************
241 \subsection[Pat-list-predicates]{Look for interesting things in patterns}
243 Unlike in the Wadler chapter, where patterns are either ``variables''
244 or ``constructors,'' here we distinguish between:
247 Patterns that cannot fail to match: variables, wildcards, and lazy
250 These are the irrefutable patterns; the two other categories
251 are refutable patterns.
254 A non-literal constructor pattern (see next category).
256 \item[literal patterns:]
257 At least the numeric ones may be overloaded.
260 A pattern is in {\em exactly one} of the above three categories; `as'
261 patterns are treated specially, of course.
263 The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
265 irrefutablePats :: [OutPat a b c] -> Bool
266 irrefutablePats pat_list = all irrefutablePat pat_list
268 irrefutablePat (AsPat _ pat) = irrefutablePat pat
269 irrefutablePat (WildPat _) = True
270 irrefutablePat (VarPat _) = True
271 irrefutablePat (LazyPat _) = True
272 irrefutablePat (DictPat ds ms) = (length ds + length ms) <= 1
273 irrefutablePat other = False
275 failureFreePat :: OutPat a b c -> Bool
277 failureFreePat (WildPat _) = True
278 failureFreePat (VarPat _) = True
279 failureFreePat (LazyPat _) = True
280 failureFreePat (AsPat _ pat) = failureFreePat pat
281 failureFreePat (ConPat con tys pats) = only_con con && all failureFreePat pats
282 failureFreePat (ConOpPat pat1 con pat2 _) = only_con con && failureFreePat pat1 && failureFreePat pat1
283 failureFreePat (RecPat con _ fields) = only_con con && and [ failureFreePat pat | (_,pat,_) <- fields ]
284 failureFreePat (ListPat _ _) = False
285 failureFreePat (TuplePat pats) = all failureFreePat pats
286 failureFreePat (DictPat _ _) = True
287 failureFreePat other_pat = False -- Literals, NPat
289 only_con con = maybeToBool (maybeTyConSingleCon (dataConTyCon con))
293 patsAreAllCons :: [OutPat a b c] -> Bool
294 patsAreAllCons pat_list = all isConPat pat_list
296 isConPat (AsPat _ pat) = isConPat pat
297 isConPat (ConPat _ _ _) = True
298 isConPat (ConOpPat _ _ _ _) = True
299 isConPat (ListPat _ _) = True
300 isConPat (TuplePat _) = True
301 isConPat (RecPat _ _ _) = True
302 isConPat (DictPat ds ms) = (length ds + length ms) > 1
303 isConPat other = False
305 patsAreAllLits :: [OutPat a b c] -> Bool
306 patsAreAllLits pat_list = all isLitPat pat_list
308 isLitPat (AsPat _ pat) = isLitPat pat
309 isLitPat (LitPat _ _) = True
310 isLitPat (NPat _ _ _) = True
311 isLitPat (NPlusKPat _ _ _ _ _) = True
312 isLitPat other = False
315 This function @collectPatBinders@ works with the ``collectBinders''
316 functions for @HsBinds@, etc. The order in which the binders are
317 collected is important; see @HsBinds.lhs@.
319 collectPatBinders :: InPat a -> [a]
321 collectPatBinders WildPatIn = []
322 collectPatBinders (VarPatIn var) = [var]
323 collectPatBinders (LitPatIn _) = []
324 collectPatBinders (LazyPatIn pat) = collectPatBinders pat
325 collectPatBinders (AsPatIn a pat) = a : collectPatBinders pat
326 collectPatBinders (NPlusKPatIn n _) = [n]
327 collectPatBinders (ConPatIn c pats) = concat (map collectPatBinders pats)
328 collectPatBinders (ConOpPatIn p1 c f p2) = collectPatBinders p1 ++ collectPatBinders p2
329 collectPatBinders (NegPatIn pat) = collectPatBinders pat
330 collectPatBinders (ParPatIn pat) = collectPatBinders pat
331 collectPatBinders (ListPatIn pats) = concat (map collectPatBinders pats)
332 collectPatBinders (TuplePatIn pats) = concat (map collectPatBinders pats)
333 collectPatBinders (RecPatIn c fields) = concat (map (\ (f,pat,_) -> collectPatBinders pat) fields)