2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[PatSyntax]{Abstract Haskell syntax---patterns}
8 Pat(..), InPat, OutPat, LPat,
10 HsConDetails(..), hsConArgs,
12 mkPrefixConPat, mkCharLitPat, mkNilPat,
15 patsAreAllCons, isConPat, isSigPat,
16 patsAreAllLits, isLitPat,
17 collectPatBinders, collectPatsBinders,
18 collectLocatedPatBinders, collectLocatedPatsBinders,
19 collectSigTysFromPat, collectSigTysFromPats
22 #include "HsVersions.h"
25 import {-# SOURCE #-} HsExpr ( HsExpr )
28 import HsLit ( HsLit(HsCharPrim), HsOverLit )
29 import HsTypes ( LHsType, SyntaxName, PostTcType )
30 import BasicTypes ( Boxity, tupleParens )
32 import TysWiredIn ( nilDataCon, charDataCon, charTy )
34 import DataCon ( DataCon )
37 import SrcLoc ( Located(..), unLoc, noLoc )
42 type InPat id = LPat id -- No 'Out' constructors
43 type OutPat id = LPat id -- No 'In' constructors
45 type LPat id = Located (Pat id)
48 = ------------ Simple patterns ---------------
49 WildPat PostTcType -- Wild card
50 | VarPat id -- Variable
51 | LazyPat (LPat id) -- Lazy pattern
52 | AsPat (Located id) (LPat id) -- As pattern
53 | ParPat (LPat id) -- Parenthesised pattern
55 ------------ Lists, tuples, arrays ---------------
56 | ListPat [LPat id] -- Syntactic list
57 PostTcType -- The type of the elements
59 | TuplePat [LPat id] -- Tuple
60 Boxity -- UnitPat is TuplePat []
62 | PArrPat [LPat id] -- Syntactic parallel array
63 PostTcType -- The type of the elements
65 ------------ Constructor patterns ---------------
66 | ConPatIn (Located id)
67 (HsConDetails id (LPat id))
70 (HsConDetails id (LPat id))
71 Type -- The type of the pattern
72 [TyVar] -- Existentially bound type variables
73 [id] -- Ditto dictionaries
75 ------------ Literal and n+k patterns ---------------
76 | LitPat HsLit -- Used for *non-overloaded* literal patterns:
77 -- Int#, Char#, Int, Char, String, etc.
79 | NPatIn HsOverLit -- Always positive
80 (Maybe SyntaxName) -- Just (Name of 'negate') for negative
81 -- patterns, Nothing otherwise
83 | NPatOut HsLit -- Used for literal patterns where there's an equality function to call
84 -- The literal is retained so that the desugarer can readily identify
85 -- equations with identical literal-patterns
86 -- Always HsInteger, HsRat or HsString.
87 -- Always HsInteger, HsRat or HsString.
88 -- *Unlike* NPatIn, for negative literals, the
89 -- literal is acutally negative!
90 Type -- Type of pattern, t
91 (HsExpr id) -- Of type t -> Bool; detects match
93 | NPlusKPatIn (Located id) -- n+k pattern
94 HsOverLit -- It'll always be an HsIntegral
95 SyntaxName -- Name of '-' (see RnEnv.lookupSyntaxName)
97 | NPlusKPatOut (Located id)
99 (HsExpr id) -- Of type t -> Bool; detects match
100 (HsExpr id) -- Of type t -> t; subtracts k
103 ------------ Generics ---------------
104 | TypePat (LHsType id) -- Type pattern for generic definitions
105 -- e.g f{| a+b |} = ...
106 -- These show up only in class declarations,
107 -- and should be a top-level pattern
109 ------------ Pattern type signatures ---------------
110 | SigPatIn (LPat id) -- Pattern with a type signature
113 | SigPatOut (LPat id) -- Pattern p
114 Type -- Type, t, of the whole pattern
115 (HsExpr id) -- Coercion function,
116 -- of type t -> typeof(p)
118 ------------ Dictionary patterns (translation only) ---------------
119 | DictPat -- Used when destructing Dictionaries with an explicit case
120 [id] -- superclass dicts
124 HsConDetails is use both for patterns and for data type declarations
127 data HsConDetails id arg
128 = PrefixCon [arg] -- C p1 p2 p3
129 | RecCon [(Located id, arg)] -- C { x = p1, y = p2 }
130 | InfixCon arg arg -- p1 `C` p2
132 hsConArgs :: HsConDetails id arg -> [arg]
133 hsConArgs (PrefixCon ps) = ps
134 hsConArgs (RecCon fs) = map snd fs
135 hsConArgs (InfixCon p1 p2) = [p1,p2]
139 %************************************************************************
143 %************************************************************************
146 instance (OutputableBndr name) => Outputable (Pat name) where
149 pprPat :: (OutputableBndr name) => Pat name -> SDoc
151 pprPat (VarPat var) -- Print with type info if -dppr-debug is on
152 = getPprStyle $ \ sty ->
153 if debugStyle sty then
154 parens (pprBndr LambdaBind var) -- Could pass the site to pprPat
155 -- but is it worth it?
159 pprPat (WildPat _) = char '_'
160 pprPat (LazyPat pat) = char '~' <> ppr pat
161 pprPat (AsPat name pat) = parens (hcat [ppr name, char '@', ppr pat])
162 pprPat (ParPat pat) = parens (ppr pat)
164 pprPat (ListPat pats _) = brackets (interpp'SP pats)
165 pprPat (PArrPat pats _) = pabrackets (interpp'SP pats)
166 pprPat (TuplePat pats bx) = tupleParens bx (interpp'SP pats)
168 pprPat (ConPatIn c details) = pprConPat c details
169 pprPat (ConPatOut c details _ _ _) = pprConPat c details
171 pprPat (LitPat s) = ppr s
172 pprPat (NPatIn l _) = ppr l
173 pprPat (NPatOut l _ _) = ppr l
174 pprPat (NPlusKPatIn n k _) = hcat [ppr n, char '+', ppr k]
175 pprPat (NPlusKPatOut n k _ _) = hcat [ppr n, char '+', integer k]
177 pprPat (TypePat ty) = ptext SLIT("{|") <> ppr ty <> ptext SLIT("|}")
179 pprPat (SigPatIn pat ty) = ppr pat <+> dcolon <+> ppr ty
180 pprPat (SigPatOut pat ty _) = ppr pat <+> dcolon <+> ppr ty
182 pprPat (DictPat dicts methods)
183 = parens (sep [ptext SLIT("{-dict-}"),
184 brackets (interpp'SP dicts),
185 brackets (interpp'SP methods)])
189 pprConPat con (PrefixCon pats) = ppr con <+> interppSP pats -- inner ParPats supply the necessary parens.
190 pprConPat con (InfixCon pat1 pat2) = hsep [ppr pat1, ppr con, ppr pat2] -- ParPats put in parens
191 -- ToDo: use pprSym to print op (but this involves fiddling various
192 -- contexts & I'm lazy...); *PatIns are *rarely* printed anyway... (WDP)
193 pprConPat con (RecCon rpats)
194 = ppr con <+> braces (hsep (punctuate comma (map (pp_rpat) rpats)))
196 pp_rpat (v, p) = hsep [ppr v, char '=', ppr p]
199 -- add parallel array brackets around a document
201 pabrackets :: SDoc -> SDoc
202 pabrackets p = ptext SLIT("[:") <> p <> ptext SLIT(":]")
206 %************************************************************************
210 %************************************************************************
213 mkPrefixConPat :: DataCon -> [OutPat id] -> Type -> OutPat id
214 -- Make a vanilla Prefix constructor pattern
215 mkPrefixConPat dc pats ty = noLoc $ ConPatOut dc (PrefixCon pats) ty [] []
217 mkNilPat :: Type -> OutPat id
218 mkNilPat ty = mkPrefixConPat nilDataCon [] ty
220 mkCharLitPat :: Char -> OutPat id
221 mkCharLitPat c = mkPrefixConPat charDataCon [noLoc $ LitPat (HsCharPrim c)] charTy
225 %************************************************************************
227 %* Predicates for checking things about pattern-lists in EquationInfo *
229 %************************************************************************
231 \subsection[Pat-list-predicates]{Look for interesting things in patterns}
233 Unlike in the Wadler chapter, where patterns are either ``variables''
234 or ``constructors,'' here we distinguish between:
237 Patterns that cannot fail to match: variables, wildcards, and lazy
240 These are the irrefutable patterns; the two other categories
241 are refutable patterns.
244 A non-literal constructor pattern (see next category).
246 \item[literal patterns:]
247 At least the numeric ones may be overloaded.
250 A pattern is in {\em exactly one} of the above three categories; `as'
251 patterns are treated specially, of course.
253 The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
255 isWildPat (WildPat _) = True
256 isWildPat other = False
258 patsAreAllCons :: [Pat id] -> Bool
259 patsAreAllCons pat_list = all isConPat pat_list
261 isConPat (AsPat _ pat) = isConPat (unLoc pat)
262 isConPat (ConPatIn _ _) = True
263 isConPat (ConPatOut _ _ _ _ _) = True
264 isConPat (ListPat _ _) = True
265 isConPat (PArrPat _ _) = True
266 isConPat (TuplePat _ _) = True
267 isConPat (DictPat ds ms) = (length ds + length ms) > 1
268 isConPat other = False
270 isSigPat (SigPatIn _ _) = True
271 isSigPat (SigPatOut _ _ _) = True
272 isSigPat other = False
274 patsAreAllLits :: [Pat id] -> Bool
275 patsAreAllLits pat_list = all isLitPat pat_list
277 isLitPat (AsPat _ pat) = isLitPat (unLoc pat)
278 isLitPat (LitPat _) = True
279 isLitPat (NPatIn _ _) = True
280 isLitPat (NPatOut _ _ _) = True
281 isLitPat (NPlusKPatIn _ _ _) = True
282 isLitPat (NPlusKPatOut _ _ _ _) = True
283 isLitPat other = False
286 %************************************************************************
288 %* Gathering stuff out of patterns
290 %************************************************************************
292 This function @collectPatBinders@ works with the ``collectBinders''
293 functions for @HsBinds@, etc. The order in which the binders are
294 collected is important; see @HsBinds.lhs@.
296 It collects the bounds *value* variables in renamed patterns; type variables
300 collectPatBinders :: LPat a -> [a]
301 collectPatBinders pat = map unLoc (collectLocatedPatBinders pat)
303 collectLocatedPatBinders :: LPat a -> [Located a]
304 collectLocatedPatBinders pat = collectl pat []
306 collectPatsBinders :: [LPat a] -> [a]
307 collectPatsBinders pats = map unLoc (collectLocatedPatsBinders pats)
309 collectLocatedPatsBinders :: [LPat a] -> [Located a]
310 collectLocatedPatsBinders pats = foldr collectl [] pats
312 collectl (L l (VarPat var)) bndrs = L l var : bndrs
313 collectl pat bndrs = collect (unLoc pat) bndrs
315 collect (WildPat _) bndrs = bndrs
316 collect (LazyPat pat) bndrs = collectl pat bndrs
317 collect (AsPat a pat) bndrs = a : collectl pat bndrs
318 collect (ParPat pat) bndrs = collectl pat bndrs
320 collect (ListPat pats _) bndrs = foldr collectl bndrs pats
321 collect (PArrPat pats _) bndrs = foldr collectl bndrs pats
322 collect (TuplePat pats _) bndrs = foldr collectl bndrs pats
324 collect (ConPatIn c ps) bndrs = foldr collectl bndrs (hsConArgs ps)
325 collect (ConPatOut c ps _ _ ds) bndrs = map noLoc ds
326 ++ foldr collectl bndrs (hsConArgs ps)
328 collect (LitPat _) bndrs = bndrs
329 collect (NPatIn _ _) bndrs = bndrs
330 collect (NPatOut _ _ _) bndrs = bndrs
332 collect (NPlusKPatIn n _ _) bndrs = n : bndrs
333 collect (NPlusKPatOut n _ _ _) bndrs = n : bndrs
335 collect (SigPatIn pat _) bndrs = collectl pat bndrs
336 collect (SigPatOut pat _ _) bndrs = collectl pat bndrs
337 collect (TypePat ty) bndrs = bndrs
338 collect (DictPat ids1 ids2) bndrs = map noLoc ids1 ++ map noLoc ids2
343 collectSigTysFromPats :: [InPat name] -> [LHsType name]
344 collectSigTysFromPats pats = foldr collect_lpat [] pats
346 collectSigTysFromPat :: InPat name -> [LHsType name]
347 collectSigTysFromPat pat = collect_lpat pat []
349 collect_lpat pat acc = collect_pat (unLoc pat) acc
351 collect_pat (SigPatIn pat ty) acc = collect_lpat pat (ty:acc)
352 collect_pat (TypePat ty) acc = ty:acc
354 collect_pat (LazyPat pat) acc = collect_lpat pat acc
355 collect_pat (AsPat a pat) acc = collect_lpat pat acc
356 collect_pat (ParPat pat) acc = collect_lpat pat acc
357 collect_pat (ListPat pats _) acc = foldr collect_lpat acc pats
358 collect_pat (PArrPat pats _) acc = foldr collect_lpat acc pats
359 collect_pat (TuplePat pats _) acc = foldr collect_lpat acc pats
360 collect_pat (ConPatIn c ps) acc = foldr collect_lpat acc (hsConArgs ps)
361 collect_pat other acc = acc -- Literals, vars, wildcard