HsPat.lhs 11.8 KB
Newer Older
1
%
2
% (c) The University of Glasgow 2006
3
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4
5
6
7
8
%
\section[PatSyntax]{Abstract Haskell syntax---patterns}

\begin{code}
module HsPat (
9
	Pat(..), InPat, OutPat, LPat, 
10
11
	
	HsConDetails(..), hsConArgs,
12
	HsRecField(..), mkRecField,
13

14
	mkPrefixConPat, mkCharLitPat, mkNilPat, mkCoPat,
15

simonpj@microsoft.com's avatar
simonpj@microsoft.com committed
16
17
	isBangHsBind,	
	patsAreAllCons, isConPat, isSigPat, isWildPat,
18
	patsAreAllLits,	isLitPat, isIrrefutableHsPat
19
20
    ) where

21
#include "HsVersions.h"
22

23

24
import {-# SOURCE #-} HsExpr		( SyntaxExpr )
sof's avatar
sof committed
25

26
-- friends:
27
28
29
30
31
import HsBinds
import HsLit
import HsTypes
import HsDoc
import BasicTypes
32
-- others:
33
import PprCore		( {- instance OutputableBndr TyVar -} )
34
35
36
37
import TysWiredIn
import Var
import DataCon
import TyCon
38
import Outputable	
39
40
import Type
import SrcLoc
41
42
\end{code}

43

44
\begin{code}
45
46
47
48
type InPat id  = LPat id	-- No 'Out' constructors
type OutPat id = LPat id	-- No 'In' constructors

type LPat id = Located (Pat id)
49
50
51
52
53

data Pat id
  =	------------ Simple patterns ---------------
    WildPat	PostTcType		-- Wild card
  | VarPat	id			-- Variable
54
55
  | VarPatOut	id (DictBinds id)	-- Used only for overloaded Ids; the 
					-- bindings give its overloaded instances
56
57
58
  | LazyPat	(LPat id)		-- Lazy pattern
  | AsPat	(Located id) (LPat id)  -- As pattern
  | ParPat      (LPat id)		-- Parenthesised pattern
simonpj@microsoft.com's avatar
simonpj@microsoft.com committed
59
  | BangPat	(LPat id)		-- Bang patterng
60
61

	------------ Lists, tuples, arrays ---------------
62
  | ListPat	[LPat id]		-- Syntactic list
63
64
		PostTcType		-- The type of the elements
   	    	    
65
  | TuplePat	[LPat id]		-- Tuple
66
		Boxity			-- UnitPat is TuplePat []
67
68
69
70
71
72
73
74
75
76
77
78
		PostTcType
	-- You might think that the PostTcType was redundant, but it's essential
	--	data T a where
	--	  T1 :: Int -> T Int
	--	f :: (T a, a) -> Int
	--	f (T1 x, z) = z
	-- When desugaring, we must generate
	--	f = /\a. \v::a.  case v of (t::T a, w::a) ->
	--			 case t of (T1 (x::Int)) -> 
	-- Note the (w::a), NOT (w::Int), because we have not yet
	-- refined 'a' to Int.  So we must know that the second component
	-- of the tuple is of type 'a' not Int.  See selectMatchVar
79

80
  | PArrPat	[LPat id]		-- Syntactic parallel array
81
82
83
		PostTcType		-- The type of the elements

	------------ Constructor patterns ---------------
84
85
  | ConPatIn	(Located id)
		(HsConDetails id (LPat id))
86

87
88
89
90
91
92
93
94
95
  | ConPatOut {
	pat_con   :: Located DataCon,
	pat_tvs   :: [TyVar],		-- Existentially bound type variables
					--   including any bound coercion variables
	pat_dicts :: [id],		-- Ditto dictionaries
	pat_binds :: DictBinds id,	-- Bindings involving those dictionaries
	pat_args  :: HsConDetails id (LPat id),
	pat_ty	  :: Type   		-- The type of the pattern
    }
96
97
98
99

	------------ Literal and n+k patterns ---------------
  | LitPat	    HsLit		-- Used for *non-overloaded* literal patterns:
					-- Int#, Char#, Int, Char, String, etc.
100

101
  | NPat	    (HsOverLit id)		-- ALWAYS positive
102
103
104
105
		    (Maybe (SyntaxExpr id))	-- Just (Name of 'negate') for negative
						-- patterns, Nothing otherwise
		    (SyntaxExpr id)		-- Equality checker, of type t->t->Bool
		    PostTcType			-- Type of the pattern
106

107
108
109
110
  | NPlusKPat	    (Located id)	-- n+k pattern
		    (HsOverLit id)	-- It'll always be an HsIntegral
		    (SyntaxExpr id)	-- (>=) function, of type t->t->Bool
		    (SyntaxExpr id)	-- Name of '-' (see RnEnv.lookupSyntaxName)
111

112
	------------ Generics ---------------
113
  | TypePat	    (LHsType id)	-- Type pattern for generic definitions
114
                                        -- e.g  f{| a+b |} = ...
115
                                        -- These show up only in class declarations,
116
117
                                        -- and should be a top-level pattern

118
	------------ Pattern type signatures ---------------
119
120
  | SigPatIn	    (LPat id)		-- Pattern with a type signature
		    (LHsType id)
121

122
123
  | SigPatOut	    (LPat id)		-- Pattern with a type signature
		    Type
124
125

	------------ Dictionary patterns (translation only) ---------------
126
  | DictPat	    -- Used when destructing Dictionaries with an explicit case
chak@cse.unsw.edu.au.'s avatar
chak@cse.unsw.edu.au. committed
127
128
		    [id]		-- Superclass dicts
		    [id]		-- Methods
129
130

	------------ Pattern coercions (translation only) ---------------
131
  | CoPat 	HsWrapper		-- If co::t1 -> t2, p::t2, 
132
					-- then (CoPat co p) :: t1
chak@cse.unsw.edu.au.'s avatar
chak@cse.unsw.edu.au. committed
133
		(Pat id)		-- Why not LPat?  Ans: existing locn will do
134
	    	Type			-- Type of whole pattern, t1
chak@cse.unsw.edu.au.'s avatar
chak@cse.unsw.edu.au. committed
135
136
	-- During desugaring a (CoPat co pat) turns into a cast with 'co' on 
	-- the scrutinee, followed by a match on 'pat'
137
138
\end{code}

139
140
141
142
HsConDetails is use both for patterns and for data type declarations

\begin{code}
data HsConDetails id arg
143
144
145
146
147
148
149
150
151
152
153
  = PrefixCon [arg]               -- C p1 p2 p3
  | RecCon    [HsRecField id arg] -- C { x = p1, y = p2 }
  | InfixCon  arg arg		  -- p1 `C` p2

data HsRecField id arg = HsRecField {
	hsRecFieldId  :: Located id,
	hsRecFieldArg :: arg,
	hsRecFieldDoc :: Maybe (LHsDoc id)
}

mkRecField id arg = HsRecField id arg Nothing
154
155
156

hsConArgs :: HsConDetails id arg -> [arg]
hsConArgs (PrefixCon ps)   = ps
157
hsConArgs (RecCon fs)      = map hsRecFieldArg fs
158
159
160
hsConArgs (InfixCon p1 p2) = [p1,p2]
\end{code}

161

162
163
164
165
166
%************************************************************************
%*									*
%* 		Printing patterns
%*									*
%************************************************************************
167

168
\begin{code}
169
170
171
instance (OutputableBndr name) => Outputable (Pat name) where
    ppr = pprPat

172
173
pprPatBndr :: OutputableBndr name => name -> SDoc
pprPatBndr var		  	-- Print with type info if -dppr-debug is on
174
175
176
177
178
179
  = getPprStyle $ \ sty ->
    if debugStyle sty then
	parens (pprBndr LambdaBind var)		-- Could pass the site to pprPat
						-- but is it worth it?
    else
	ppr var
180

181
pprPat :: (OutputableBndr name) => Pat name -> SDoc
simonpj@microsoft.com's avatar
simonpj@microsoft.com committed
182
183
184
185
186
187
188
pprPat (VarPat var)  	  = pprPatBndr var
pprPat (VarPatOut var bs) = parens (pprPatBndr var <+> braces (ppr bs))
pprPat (WildPat _)	  = char '_'
pprPat (LazyPat pat)      = char '~' <> ppr pat
pprPat (BangPat pat)      = char '!' <> ppr pat
pprPat (AsPat name pat)   = parens (hcat [ppr name, char '@', ppr pat])
pprPat (ParPat pat)	  = parens (ppr pat)
189
190
191
pprPat (ListPat pats _)     = brackets (interpp'SP pats)
pprPat (PArrPat pats _)     = pabrackets (interpp'SP pats)
pprPat (TuplePat pats bx _) = tupleParens bx (interpp'SP pats)
192

193
pprPat (ConPatIn con details) = pprUserCon con details
194
195
pprPat (ConPatOut { pat_con = con, pat_tvs = tvs, pat_dicts = dicts, 
		    pat_binds = binds, pat_args = details })
196
197
198
199
200
201
  = getPprStyle $ \ sty ->	-- Tiresome; in TcBinds.tcRhs we print out a 
    if debugStyle sty then 	-- typechecked Pat in an error message, 
				-- and we want to make sure it prints nicely
	ppr con <+> sep [ hsep (map pprPatBndr tvs) <+> hsep (map pprPatBndr dicts),
		   	  pprLHsBinds binds, pprConArgs details]
    else pprUserCon con details
202
203

pprPat (LitPat s)	      = ppr s
204
205
pprPat (NPat l Nothing  _ _)  = ppr l
pprPat (NPat l (Just _) _ _)  = char '-' <> ppr l
206
pprPat (NPlusKPat n k _ _)    = hcat [ppr n, char '+', ppr k]
207
pprPat (TypePat ty)	      = ptext SLIT("{|") <> ppr ty <> ptext SLIT("|}")
208
pprPat (CoPat co pat _)	      = parens (pprHsWrapper (ppr pat) co)
209
210
211
212
213
pprPat (SigPatIn pat ty)      = ppr pat <+> dcolon <+> ppr ty
pprPat (SigPatOut pat ty)     = ppr pat <+> dcolon <+> ppr ty
pprPat (DictPat ds ms)	      = parens (sep [ptext SLIT("{-dict-}"),
					     brackets (interpp'SP ds),
					     brackets (interpp'SP ms)])
214

215
216
pprUserCon c (InfixCon p1 p2) = ppr p1 <+> ppr c <+> ppr p2
pprUserCon c details          = ppr c <+> pprConArgs details
217

218
219
220
221
pprConArgs (PrefixCon pats) = interppSP pats
pprConArgs (InfixCon p1 p2) = interppSP [p1,p2]
pprConArgs (RecCon rpats)   = braces (hsep (punctuate comma (map (pp_rpat) rpats)))
			    where
222
223
			      pp_rpat (HsRecField v p _d) = 
                                hsep [ppr v, char '=', ppr p]
chak's avatar
chak committed
224
225
226
227
228

-- add parallel array brackets around a document
--
pabrackets   :: SDoc -> SDoc
pabrackets p  = ptext SLIT("[:") <> p <> ptext SLIT(":]")
229
230
231
232

instance (OutputableBndr id, Outputable arg) =>
         Outputable (HsRecField id arg) where
    ppr (HsRecField n ty doc) = ppr n <+> dcolon <+> ppr ty <+> ppr_mbDoc doc
233
234
\end{code}

235

236
237
238
239
240
%************************************************************************
%*									*
%* 		Building patterns
%*									*
%************************************************************************
241

242
243
244
\begin{code}
mkPrefixConPat :: DataCon -> [OutPat id] -> Type -> OutPat id
-- Make a vanilla Prefix constructor pattern
245
246
247
248
mkPrefixConPat dc pats ty 
  = noLoc $ ConPatOut { pat_con = noLoc dc, pat_tvs = [], pat_dicts = [],
			pat_binds = emptyLHsBinds, pat_args = PrefixCon pats, 
			pat_ty = ty }
249

250
251
mkNilPat :: Type -> OutPat id
mkNilPat ty = mkPrefixConPat nilDataCon [] ty
252

253
254
mkCharLitPat :: Char -> OutPat id
mkCharLitPat c = mkPrefixConPat charDataCon [noLoc $ LitPat (HsCharPrim c)] charTy
255

256
mkCoPat :: HsWrapper -> OutPat id -> Type -> OutPat id
257
mkCoPat co lpat@(L loc pat) ty
258
  | isIdHsWrapper co = lpat
259
  | otherwise = L loc (CoPat co pat ty)
260
261
\end{code}

262

263
264
%************************************************************************
%*									*
265
%* Predicates for checking things about pattern-lists in EquationInfo	*
266
267
%*									*
%************************************************************************
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
\subsection[Pat-list-predicates]{Look for interesting things in patterns}

Unlike in the Wadler chapter, where patterns are either ``variables''
or ``constructors,'' here we distinguish between:
\begin{description}
\item[unfailable:]
Patterns that cannot fail to match: variables, wildcards, and lazy
patterns.

These are the irrefutable patterns; the two other categories
are refutable patterns.

\item[constructor:]
A non-literal constructor pattern (see next category).

\item[literal patterns:]
At least the numeric ones may be overloaded.
\end{description}

A pattern is in {\em exactly one} of the above three categories; `as'
patterns are treated specially, of course.

291
292
The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
\begin{code}
293
294
295
isWildPat (WildPat _) = True
isWildPat other	      = False

296
patsAreAllCons :: [Pat id] -> Bool
297
298
patsAreAllCons pat_list = all isConPat pat_list

299
300
301
302
303
304
305
306
isConPat (AsPat _ pat)	 = isConPat (unLoc pat)
isConPat (ConPatIn {})	 = True
isConPat (ConPatOut {})  = True
isConPat (ListPat {})	 = True
isConPat (PArrPat {})	 = True
isConPat (TuplePat {})	 = True
isConPat (DictPat ds ms) = (length ds + length ms) > 1
isConPat other		 = False
307

308
309
310
isSigPat (SigPatIn _ _)  = True
isSigPat (SigPatOut _ _) = True
isSigPat other		 = False
311

312
patsAreAllLits :: [Pat id] -> Bool
313
314
patsAreAllLits pat_list = all isLitPat pat_list

315
isLitPat (AsPat _ pat)	        = isLitPat (unLoc pat)
316
isLitPat (LitPat _)	        = True
317
318
isLitPat (NPat _ _ _ _)	        = True
isLitPat (NPlusKPat _ _ _ _)    = True
319
isLitPat other		        = False
320

simonpj@microsoft.com's avatar
simonpj@microsoft.com committed
321
322
323
324
325
isBangHsBind :: HsBind id -> Bool
-- In this module because HsPat is above HsBinds in the import graph
isBangHsBind (PatBind { pat_lhs = L _ (BangPat p) }) = True
isBangHsBind bind				     = False

326
327
isIrrefutableHsPat :: LPat id -> Bool
-- This function returns False if it's in doubt; specifically
328
-- on a ConPatIn it doesn't know the size of the constructor family
329
330
331
332
333
334
-- But if it returns True, the pattern is definitely irrefutable
isIrrefutableHsPat pat
  = go pat
  where
    go (L _ pat)	 = go1 pat

335
336
337
338
    go1 (WildPat _)         = True
    go1 (VarPat _)          = True
    go1 (VarPatOut _ _)     = True
    go1 (LazyPat pat)       = True
simonpj@microsoft.com's avatar
simonpj@microsoft.com committed
339
    go1 (BangPat pat)       = go pat
340
    go1 (CoPat _ pat _)     = go1 pat
341
342
343
344
345
346
347
    go1 (ParPat pat)        = go pat
    go1 (AsPat _ pat)       = go pat
    go1 (SigPatIn pat _)    = go pat
    go1 (SigPatOut pat _)   = go pat
    go1 (TuplePat pats _ _) = all go pats
    go1 (ListPat pats _)    = False
    go1 (PArrPat pats _)    = False	-- ?
348
349

    go1 (ConPatIn _ _) = False	-- Conservative
350
    go1 (ConPatOut{ pat_con = L _ con, pat_args = details }) 
351
352
353
354
355
356
357
358
359
	=  isProductTyCon (dataConTyCon con)
	&& all go (hsConArgs details)

    go1 (LitPat _) 	   = False
    go1 (NPat _ _ _ _)	   = False
    go1 (NPlusKPat _ _ _ _) = False

    go1 (TypePat _)   = panic "isIrrefutableHsPat: type pattern"
    go1 (DictPat _ _) = panic "isIrrefutableHsPat: type pattern"
360
361
\end{code}