[project @ 1997-05-19 00:12:10 by sof]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsPat.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[PatSyntax]{Abstract Haskell syntax---patterns}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module HsPat (
10         InPat(..),
11         OutPat(..),
12
13         irrefutablePat, irrefutablePats,
14         failureFreePat,
15         patsAreAllCons, isConPat,
16         patsAreAllLits, isLitPat,
17         collectPatBinders
18     ) where
19
20 IMP_Ubiq()
21
22 -- friends:
23 import HsBasic                  ( HsLit, Fixity )
24 IMPORT_DELOOPER(IdLoop)
25 IMPORT_DELOOPER(HsLoop)         ( HsExpr )
26
27
28 -- others:
29 import Id               --( dataConTyCon, GenId )
30 import Maybes           ( maybeToBool )
31 import Outputable       --( interppSP, interpp'SP, ifPprShowAll )
32 import PprStyle         ( PprStyle(..), userStyle )
33 import Pretty
34 import TyCon            ( maybeTyConSingleCon )
35 import PprType          ( GenType )
36 #if __GLASGOW_HASKELL__ >= 202
37 import Name
38 #endif
39 \end{code}
40
41 Patterns come in distinct before- and after-typechecking flavo(u)rs.
42 \begin{code}
43 data InPat name
44   = WildPatIn                           -- wild card
45   | VarPatIn        name                -- variable
46   | LitPatIn        HsLit               -- literal
47   | LazyPatIn       (InPat name)        -- lazy pattern
48   | AsPatIn         name                -- as pattern
49                     (InPat name)
50   | ConPatIn        name                -- constructed type
51                     [InPat name]
52   | ConOpPatIn      (InPat name)
53                     name
54                     Fixity              -- c.f. OpApp in HsExpr
55                     (InPat name)
56
57   | NPlusKPatIn     name                --  n+k pattern
58                     HsLit
59
60   -- We preserve prefix negation and parenthesis for the precedence parser.
61
62   | NegPatIn        (InPat name)        -- negated pattern
63   | ParPatIn        (InPat name)        -- parenthesised pattern
64
65   | ListPatIn       [InPat name]        -- syntactic list
66                                         -- must have >= 1 elements
67   | TuplePatIn      [InPat name]        -- tuple
68
69   | RecPatIn        name                -- record
70                     [(name, InPat name, Bool)]  -- True <=> source used punning
71
72 data OutPat tyvar uvar id
73   = WildPat         (GenType tyvar uvar)        -- wild card
74
75   | VarPat          id                          -- variable (type is in the Id)
76
77   | LazyPat         (OutPat tyvar uvar id)      -- lazy pattern
78
79   | AsPat           id                          -- as pattern
80                     (OutPat tyvar uvar id)
81
82   | ConPat          Id                          -- Constructor is always an Id
83                     (GenType tyvar uvar)        -- the type of the pattern
84                     [OutPat tyvar uvar id]
85
86   | ConOpPat        (OutPat tyvar uvar id)      -- just a special case...
87                     Id
88                     (OutPat tyvar uvar id)
89                     (GenType tyvar uvar)
90   | ListPat                                     -- syntactic list
91                     (GenType tyvar uvar)        -- the type of the elements
92                     [OutPat tyvar uvar id]
93
94   | TuplePat        [OutPat tyvar uvar id]      -- tuple
95                                                 -- UnitPat is TuplePat []
96
97   | RecPat          Id                          -- record constructor
98                     (GenType tyvar uvar)        -- the type of the pattern
99                     [(Id, OutPat tyvar uvar id, Bool)]  -- True <=> source used punning
100
101   | LitPat          -- Used for *non-overloaded* literal patterns:
102                     -- Int#, Char#, Int, Char, String, etc.
103                     HsLit
104                     (GenType tyvar uvar)        -- type of pattern
105
106   | NPat            -- Used for *overloaded* literal patterns
107                     HsLit                       -- the literal is retained so that
108                                                 -- the desugarer can readily identify
109                                                 -- equations with identical literal-patterns
110                     (GenType tyvar uvar)        -- type of pattern, t
111                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))
112                                                 -- of type t -> Bool; detects match
113
114   | NPlusKPat       id
115                     HsLit                       -- Same reason as for LitPat
116                                                 -- (This could be an Integer, but then
117                                                 -- it's harder to partitionEqnsByLit
118                                                 -- in the desugarer.)
119                     (GenType tyvar uvar)        -- Type of pattern, t
120                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))       -- Of type t -> Bool; detects match
121                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))       -- Of type t -> t; subtracts k
122
123   | DictPat         -- Used when destructing Dictionaries with an explicit case
124                     [id]                        -- superclass dicts
125                     [id]                        -- methods
126 \end{code}
127
128 \begin{code}
129 instance (Outputable name, NamedThing name) => Outputable (InPat name) where
130     ppr = pprInPat
131
132 pprInPat :: (Outputable name, NamedThing name) => PprStyle -> InPat name -> Doc
133
134 pprInPat sty (WildPatIn)        = char '_'
135 pprInPat sty (VarPatIn var)     = ppr sty var
136 pprInPat sty (LitPatIn s)       = ppr sty s
137 pprInPat sty (LazyPatIn pat)    = (<>) (char '~') (ppr sty pat)
138 pprInPat sty (AsPatIn name pat)
139     = parens (hcat [ppr sty name, char '@', ppr sty pat])
140
141 pprInPat sty (ConPatIn c pats)
142  = if null pats then
143       ppr sty c
144    else
145       hsep [ppr sty c, interppSP sty pats] -- ParPats put in the parens
146
147 pprInPat sty (ConOpPatIn pat1 op fixity pat2)
148  = hsep [ppr sty pat1, ppr sty op, ppr sty pat2] -- ParPats put in parens
149
150         -- ToDo: use pprSym to print op (but this involves fiddling various
151         -- contexts & I'm lazy...); *PatIns are *rarely* printed anyway... (WDP)
152
153 pprInPat sty (NegPatIn pat)
154   = let
155         pp_pat = pprInPat sty pat
156     in
157     (<>) (char '-') (
158     case pat of
159       LitPatIn _ -> pp_pat
160       _          -> parens pp_pat
161     )
162
163 pprInPat sty (ParPatIn pat)
164   = parens (pprInPat sty pat)
165
166 pprInPat sty (ListPatIn pats)
167   = brackets (interpp'SP sty pats)
168 pprInPat sty (TuplePatIn pats)
169   = parens (interpp'SP sty pats)
170 pprInPat sty (NPlusKPatIn n k)
171   = parens (hcat [ppr sty n, char '+', ppr sty k])
172
173 pprInPat sty (RecPatIn con rpats)
174   = hsep [ppr sty con, braces (hsep (punctuate comma (map (pp_rpat sty) rpats)))]
175   where
176     pp_rpat sty (v, _, True) | userStyle sty = ppr PprForUser v
177     pp_rpat sty (v, p, _)                    = hsep [ppr sty v, char '=', ppr sty p]
178 \end{code}
179
180 \begin{code}
181 instance (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar, Outputable id)
182        => Outputable (OutPat tyvar uvar id) where
183     ppr = pprOutPat
184 \end{code}
185
186 \begin{code}
187 pprOutPat sty (WildPat ty)      = char '_'
188 pprOutPat sty (VarPat var)      = ppr sty var
189 pprOutPat sty (LazyPat pat)     = hcat [char '~', ppr sty pat]
190 pprOutPat sty (AsPat name pat)
191   = parens (hcat [ppr sty name, char '@', ppr sty pat])
192
193 pprOutPat sty (ConPat name ty [])
194   = (<>) (ppr sty name)
195         (ifPprShowAll sty (pprConPatTy sty ty))
196
197 pprOutPat sty (ConPat name ty pats)
198   = hcat [parens (hcat [ppr sty name, space, interppSP sty pats]),
199                ifPprShowAll sty (pprConPatTy sty ty) ]
200
201 pprOutPat sty (ConOpPat pat1 op pat2 ty)
202   = parens (hcat [ppr sty pat1, space, ppr sty op, space, ppr sty pat2])
203
204 pprOutPat sty (ListPat ty pats)
205   = brackets (interpp'SP sty pats)
206 pprOutPat sty (TuplePat pats)
207   = parens (interpp'SP sty pats)
208
209 pprOutPat sty (RecPat con ty rpats)
210   = hcat [ppr sty con, braces (hsep (punctuate comma (map (pp_rpat sty) rpats)))]
211   where
212     pp_rpat sty (v, _, True) | userStyle sty = ppr PprForUser v
213     pp_rpat sty (v, p, _)                    = hsep [ppr sty v, char '=', ppr sty p]
214
215 pprOutPat sty (LitPat l ty)     = ppr sty l     -- ToDo: print more
216 pprOutPat sty (NPat   l ty e)   = ppr sty l     -- ToDo: print more
217 pprOutPat sty (NPlusKPat n k ty e1 e2)          -- ToDo: print more
218   = parens (hcat [ppr sty n, char '+', ppr sty k])
219
220 pprOutPat sty (DictPat dicts methods)
221  = parens (sep [ptext SLIT("{-dict-}"),
222                   brackets (interpp'SP sty dicts),
223                   brackets (interpp'SP sty methods)])
224
225 pprConPatTy sty ty
226  = parens (ppr sty ty)
227 \end{code}
228
229 %************************************************************************
230 %*                                                                      *
231 %* predicates for checking things about pattern-lists in EquationInfo   *
232 %*                                                                      *
233 %************************************************************************
234 \subsection[Pat-list-predicates]{Look for interesting things in patterns}
235
236 Unlike in the Wadler chapter, where patterns are either ``variables''
237 or ``constructors,'' here we distinguish between:
238 \begin{description}
239 \item[unfailable:]
240 Patterns that cannot fail to match: variables, wildcards, and lazy
241 patterns.
242
243 These are the irrefutable patterns; the two other categories
244 are refutable patterns.
245
246 \item[constructor:]
247 A non-literal constructor pattern (see next category).
248
249 \item[literal patterns:]
250 At least the numeric ones may be overloaded.
251 \end{description}
252
253 A pattern is in {\em exactly one} of the above three categories; `as'
254 patterns are treated specially, of course.
255
256 The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
257 \begin{code}
258 irrefutablePats :: [OutPat a b c] -> Bool
259 irrefutablePats pat_list = all irrefutablePat pat_list
260
261 irrefutablePat (AsPat   _ pat)  = irrefutablePat pat
262 irrefutablePat (WildPat _)      = True
263 irrefutablePat (VarPat  _)      = True
264 irrefutablePat (LazyPat _)      = True
265 irrefutablePat (DictPat ds ms)  = (length ds + length ms) <= 1
266 irrefutablePat other            = False
267
268 failureFreePat :: OutPat a b c -> Bool
269
270 failureFreePat (WildPat _)                = True
271 failureFreePat (VarPat _)                 = True
272 failureFreePat (LazyPat _)                = True
273 failureFreePat (AsPat _ pat)              = failureFreePat pat
274 failureFreePat (ConPat con tys pats)      = only_con con && all failureFreePat pats
275 failureFreePat (ConOpPat pat1 con pat2 _) = only_con con && failureFreePat pat1 && failureFreePat pat1
276 failureFreePat (RecPat con _ fields)      = only_con con && and [ failureFreePat pat | (_,pat,_) <- fields ]
277 failureFreePat (ListPat _ _)              = False
278 failureFreePat (TuplePat pats)            = all failureFreePat pats
279 failureFreePat (DictPat _ _)              = True
280 failureFreePat other_pat                  = False   -- Literals, NPat
281
282 only_con con = maybeToBool (maybeTyConSingleCon (dataConTyCon con))
283 \end{code}
284
285 \begin{code}
286 patsAreAllCons :: [OutPat a b c] -> Bool
287 patsAreAllCons pat_list = all isConPat pat_list
288
289 isConPat (AsPat _ pat)          = isConPat pat
290 isConPat (ConPat _ _ _)         = True
291 isConPat (ConOpPat _ _ _ _)     = True
292 isConPat (ListPat _ _)          = True
293 isConPat (TuplePat _)           = True
294 isConPat (RecPat _ _ _)         = True
295 isConPat (DictPat ds ms)        = (length ds + length ms) > 1
296 isConPat other                  = False
297
298 patsAreAllLits :: [OutPat a b c] -> Bool
299 patsAreAllLits pat_list = all isLitPat pat_list
300
301 isLitPat (AsPat _ pat)         = isLitPat pat
302 isLitPat (LitPat _ _)          = True
303 isLitPat (NPat   _ _ _)        = True
304 isLitPat (NPlusKPat _ _ _ _ _) = True
305 isLitPat other                 = False
306 \end{code}
307
308 This function @collectPatBinders@ works with the ``collectBinders''
309 functions for @HsBinds@, etc.  The order in which the binders are
310 collected is important; see @HsBinds.lhs@.
311 \begin{code}
312 collectPatBinders :: InPat a -> [a]
313
314 collectPatBinders WildPatIn              = []
315 collectPatBinders (VarPatIn var)         = [var]
316 collectPatBinders (LitPatIn _)           = []
317 collectPatBinders (LazyPatIn pat)        = collectPatBinders pat
318 collectPatBinders (AsPatIn a pat)        = a : collectPatBinders pat
319 collectPatBinders (NPlusKPatIn n _)      = [n]
320 collectPatBinders (ConPatIn c pats)      = concat (map collectPatBinders pats)
321 collectPatBinders (ConOpPatIn p1 c f p2) = collectPatBinders p1 ++ collectPatBinders p2
322 collectPatBinders (NegPatIn  pat)        = collectPatBinders pat
323 collectPatBinders (ParPatIn  pat)        = collectPatBinders pat
324 collectPatBinders (ListPatIn pats)       = concat (map collectPatBinders pats)
325 collectPatBinders (TuplePatIn pats)      = concat (map collectPatBinders pats)
326 collectPatBinders (RecPatIn c fields)    = concat (map (\ (f,pat,_) -> collectPatBinders pat) fields)
327 \end{code}