[project @ 2002-09-13 15:02:25 by simonpj]
[ghc-hetmet.git] / ghc / compiler / deSugar / Check.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1997-1998
3 %
4 % Author: Juan J. Quintela    <quintela@krilin.dc.fi.udc.es>
5 \section{Module @Check@ in @deSugar@}
6
7 \begin{code}
8
9
10 module Check ( check , ExhaustivePat ) where
11
12
13 import HsSyn            
14 import TcHsSyn          ( TypecheckedPat, hsPatType )
15 import TcType           ( tcTyConAppTyCon )
16 import DsUtils          ( EquationInfo(..), MatchResult(..), EqnSet, 
17                           CanItFail(..),  tidyLitPat, tidyNPat, 
18                         )
19 import Id               ( idType )
20 import DataCon          ( DataCon, dataConTyCon, dataConOrigArgTys, dataConFieldLabels )
21 import Name             ( Name, mkInternalName, getOccName, isDataSymOcc, getName, mkVarOcc )
22 import TysWiredIn
23 import PrelNames        ( unboundKey )
24 import TyCon            ( tyConDataCons, tupleTyConBoxity, isTupleTyCon )
25 import BasicTypes       ( Boxity(..) )
26 import SrcLoc           ( noSrcLoc )
27 import UniqSet
28 import Util             ( takeList, splitAtList, notNull )
29 import Outputable
30 import FastString
31
32 #include "HsVersions.h"
33 \end{code}
34
35 This module performs checks about if one list of equations are:
36 \begin{itemize}
37 \item Overlapped
38 \item Non exhaustive
39 \end{itemize}
40 To discover that we go through the list of equations in a tree-like fashion.
41
42 If you like theory, a similar algorithm is described in:
43 \begin{quotation}
44         {\em Two Techniques for Compiling Lazy Pattern Matching},
45         Luc Maranguet,
46         INRIA Rocquencourt (RR-2385, 1994)
47 \end{quotation}
48 The algorithm is based on the first technique, but there are some differences:
49 \begin{itemize}
50 \item We don't generate code
51 \item We have constructors and literals (not only literals as in the 
52           article)
53 \item We don't use directions, we must select the columns from 
54           left-to-right
55 \end{itemize}
56 (By the way the second technique is really similar to the one used in 
57  @Match.lhs@ to generate code)
58
59 This function takes the equations of a pattern and returns:
60 \begin{itemize}
61 \item The patterns that are not recognized
62 \item The equations that are not overlapped
63 \end{itemize}
64 It simplify the patterns and then call @check'@ (the same semantics), and it 
65 needs to reconstruct the patterns again ....
66
67 The problem appear with things like:
68 \begin{verbatim}
69   f [x,y]   = ....
70   f (x:xs)  = .....
71 \end{verbatim}
72 We want to put the two patterns with the same syntax, (prefix form) and 
73 then all the constructors are equal:
74 \begin{verbatim}
75   f (: x (: y []))   = ....
76   f (: x xs)         = .....
77 \end{verbatim}
78 (more about that in @simplify_eqns@)
79
80 We would prefer to have a @WarningPat@ of type @String@, but Strings and the 
81 Pretty Printer are not friends.
82
83 We use @InPat@ in @WarningPat@ instead of @OutPat@
84 because we need to print the 
85 warning messages in the same way they are introduced, i.e. if the user 
86 wrote:
87 \begin{verbatim}
88         f [x,y] = ..
89 \end{verbatim}
90 He don't want a warning message written:
91 \begin{verbatim}
92         f (: x (: y [])) ........
93 \end{verbatim}
94 Then we need to use InPats.
95 \begin{quotation}
96      Juan Quintela 5 JUL 1998\\
97           User-friendliness and compiler writers are no friends.
98 \end{quotation}
99 \begin{code}
100
101 type WarningPat = InPat Name
102 type ExhaustivePat = ([WarningPat], [(Name, [HsLit])])
103
104
105 check :: [EquationInfo] -> ([ExhaustivePat],EqnSet)
106 check qs = (untidy_warns, incomplete)
107       where
108         (warns, incomplete) = check' (simplify_eqns qs)
109         untidy_warns = map untidy_exhaustive warns 
110
111 untidy_exhaustive :: ExhaustivePat -> ExhaustivePat
112 untidy_exhaustive ([pat], messages) = 
113                   ([untidy_no_pars pat], map untidy_message messages)
114 untidy_exhaustive (pats, messages) = 
115                   (map untidy_pars pats, map untidy_message messages)
116
117 untidy_message :: (Name, [HsLit]) -> (Name, [HsLit])
118 untidy_message (string, lits) = (string, map untidy_lit lits)
119 \end{code}
120
121 The function @untidy@ does the reverse work of the @simplify_pat@ funcion.
122
123 \begin{code}
124
125 type NeedPars = Bool 
126
127 untidy_no_pars :: WarningPat -> WarningPat
128 untidy_no_pars p = untidy False p
129
130 untidy_pars :: WarningPat -> WarningPat
131 untidy_pars p = untidy True p
132
133 untidy :: NeedPars -> WarningPat -> WarningPat
134 untidy _ p@(WildPat _)   = p
135 untidy _ p@(VarPat name) = p
136 untidy _ (LitPat lit)    = LitPat (untidy_lit lit)
137 untidy _ p@(ConPatIn name (PrefixCon [])) = p
138 untidy b (ConPatIn name ps)     = pars b (ConPatIn name (untidy_con ps))
139 untidy _ (ListPat pats ty)      = ListPat (map untidy_no_pars pats) ty
140 untidy _ (TuplePat pats boxed)  = TuplePat (map untidy_no_pars pats) boxed
141 untidy _ (PArrPat _ _)          = panic "Check.untidy: Shouldn't get a parallel array here!"
142 untidy _ (SigPatIn _ _)         = panic "Check.untidy: SigPat"
143
144 untidy_con (PrefixCon pats) = PrefixCon (map untidy_pars pats) 
145 untidy_con (InfixCon p1 p2) = InfixCon  (untidy_pars p1) (untidy_pars p2)
146 untidy_con (RecCon bs)      = RecCon    [(f,untidy_pars p) | (f,p) <- bs]
147
148 pars :: NeedPars -> WarningPat -> WarningPat
149 pars True p = ParPat p
150 pars _    p = p
151
152 untidy_lit :: HsLit -> HsLit
153 untidy_lit (HsCharPrim c) = HsChar c
154 untidy_lit lit            = lit
155 \end{code}
156
157 This equation is the same that check, the only difference is that the
158 boring work is done, that work needs to be done only once, this is
159 the reason top have two functions, check is the external interface,
160 @check'@ is called recursively.
161
162 There are several cases:
163
164 \begin{itemize} 
165 \item There are no equations: Everything is OK. 
166 \item There are only one equation, that can fail, and all the patterns are
167       variables. Then that equation is used and the same equation is 
168       non-exhaustive.
169 \item All the patterns are variables, and the match can fail, there are 
170       more equations then the results is the result of the rest of equations 
171       and this equation is used also.
172
173 \item The general case, if all the patterns are variables (here the match 
174       can't fail) then the result is that this equation is used and this 
175       equation doesn't generate non-exhaustive cases.
176
177 \item In the general case, there can exist literals ,constructors or only 
178       vars in the first column, we actuate in consequence.
179
180 \end{itemize}
181
182
183 \begin{code}
184
185 check' :: [EquationInfo] -> ([ExhaustivePat],EqnSet)  
186 check' []                                              = ([([],[])],emptyUniqSet)
187
188 check' [EqnInfo n ctx ps (MatchResult CanFail _)] 
189    | all_vars ps  = ([(takeList ps (repeat new_wild_pat),[])],  unitUniqSet n)
190
191 check' qs@((EqnInfo n ctx ps (MatchResult CanFail _)):rs)
192    | all_vars ps  = (pats,  addOneToUniqSet indexs n)
193   where
194     (pats,indexs) = check' rs
195
196 check' qs@((EqnInfo n ctx ps result):_) 
197    | all_vars ps  = ([],  unitUniqSet n)
198 --   | nplusk       = panic "Check.check': Work in progress: nplusk"
199 --   | npat         = panic "Check.check': Work in progress: npat ?????"
200    | literals     = split_by_literals qs
201    | constructors = split_by_constructor qs
202    | only_vars    = first_column_only_vars qs
203    | otherwise    = pprPanic "Check.check': Not implemented :-(" (ppr first_pats)
204   where
205      -- Note: RecPats will have been simplified to ConPats
206      --       at this stage.
207     first_pats   = ASSERT2( okGroup qs, pprGroup qs ) map firstPat qs
208     constructors = any is_con first_pats
209     literals     = any is_lit first_pats
210     only_vars    = all is_var first_pats
211 --    npat         = or (map is_npat qs)
212 --    nplusk       = or (map is_nplusk qs)
213 \end{code}
214
215 Here begins the code to deal with literals, we need to split the matrix
216 in different matrix beginning by each literal and a last matrix with the 
217 rest of values.
218
219 \begin{code}
220 split_by_literals :: [EquationInfo] -> ([ExhaustivePat],EqnSet)
221 split_by_literals qs = process_literals used_lits qs
222            where
223              used_lits = get_used_lits qs
224 \end{code}
225
226 @process_explicit_literals@ is a function that process each literal that appears 
227 in the column of the matrix. 
228
229 \begin{code}
230 process_explicit_literals :: [HsLit] -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
231 process_explicit_literals lits qs = (concat pats, unionManyUniqSets indexs)
232     where                  
233       pats_indexs   = map (\x -> construct_literal_matrix x qs) lits
234       (pats,indexs) = unzip pats_indexs 
235
236 \end{code}
237
238
239 @process_literals@ calls @process_explicit_literals@ to deal with the literals 
240 that appears in the matrix and deal also with the rest of the cases. It 
241 must be one Variable to be complete.
242
243 \begin{code}
244
245 process_literals :: [HsLit] -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
246 process_literals used_lits qs 
247   | null default_eqns  = ([make_row_vars used_lits (head qs)]++pats,indexs)
248   | otherwise          = (pats_default,indexs_default)
249      where
250        (pats,indexs)   = process_explicit_literals used_lits qs
251        default_eqns    = ASSERT2( okGroup qs, pprGroup qs ) 
252                          map remove_var (filter (is_var . firstPat) qs)
253        (pats',indexs') = check' default_eqns 
254        pats_default    = [(new_wild_pat:ps,constraints) | (ps,constraints) <- (pats')] ++ pats 
255        indexs_default  = unionUniqSets indexs' indexs
256 \end{code}
257
258 Here we have selected the literal and we will select all the equations that 
259 begins for that literal and create a new matrix.
260
261 \begin{code}
262 construct_literal_matrix :: HsLit -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
263 construct_literal_matrix lit qs =
264     (map (\ (xs,ys) -> (new_lit:xs,ys)) pats,indexs) 
265   where
266     (pats,indexs) = (check' (remove_first_column_lit lit qs)) 
267     new_lit = LitPat lit 
268
269 remove_first_column_lit :: HsLit
270                         -> [EquationInfo] 
271                         -> [EquationInfo]
272 remove_first_column_lit lit qs
273   = ASSERT2( okGroup qs, pprGroup qs ) 
274     map shift_pat (filter (is_var_lit lit . firstPat) qs)
275   where
276      shift_pat (EqnInfo n ctx []     result) =  panic "Check.shift_var: no patterns"
277      shift_pat (EqnInfo n ctx (_:ps) result) =  EqnInfo n ctx ps result
278
279 \end{code}
280
281 This function splits the equations @qs@ in groups that deal with the 
282 same constructor.
283
284 \begin{code}
285
286 split_by_constructor :: [EquationInfo] -> ([ExhaustivePat],EqnSet)
287
288 split_by_constructor qs 
289   | notNull unused_cons = need_default_case used_cons unused_cons qs 
290   | otherwise           = no_need_default_case used_cons qs 
291                        where 
292                           used_cons   = get_used_cons qs 
293                           unused_cons = get_unused_cons used_cons 
294
295 \end{code}
296
297 The first column of the patterns matrix only have vars, then there is 
298 nothing to do.
299
300 \begin{code}
301 first_column_only_vars :: [EquationInfo] -> ([ExhaustivePat],EqnSet)
302 first_column_only_vars qs = (map (\ (xs,ys) -> (new_wild_pat:xs,ys)) pats,indexs)
303                           where
304                             (pats,indexs) = check' (map remove_var qs)
305        
306 \end{code}
307
308 This equation takes a matrix of patterns and split the equations by 
309 constructor, using all the constructors that appears in the first column 
310 of the pattern matching.
311
312 We can need a default clause or not ...., it depends if we used all the 
313 constructors or not explicitly. The reasoning is similar to @process_literals@,
314 the difference is that here the default case is not always needed.
315
316 \begin{code}
317 no_need_default_case :: [TypecheckedPat] -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
318 no_need_default_case cons qs = (concat pats, unionManyUniqSets indexs)
319     where                  
320       pats_indexs   = map (\x -> construct_matrix x qs) cons
321       (pats,indexs) = unzip pats_indexs 
322
323 need_default_case :: [TypecheckedPat] -> [DataCon] -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
324 need_default_case used_cons unused_cons qs 
325   | null default_eqns  = (pats_default_no_eqns,indexs)
326   | otherwise          = (pats_default,indexs_default)
327      where
328        (pats,indexs)   = no_need_default_case used_cons qs
329        default_eqns    = ASSERT2( okGroup qs, pprGroup qs ) map remove_var (filter (is_var . firstPat) qs)
330        (pats',indexs') = check' default_eqns 
331        pats_default    = [(make_whole_con c:ps,constraints) | 
332                           c <- unused_cons, (ps,constraints) <- pats'] ++ pats
333        new_wilds       = make_row_vars_for_constructor (head qs)
334        pats_default_no_eqns =  [(make_whole_con c:new_wilds,[]) | c <- unused_cons] ++ pats
335        indexs_default  = unionUniqSets indexs' indexs
336
337 construct_matrix :: TypecheckedPat -> [EquationInfo] -> ([ExhaustivePat],EqnSet)
338 construct_matrix con qs =
339     (map (make_con con) pats,indexs) 
340   where
341     (pats,indexs) = (check' (remove_first_column con qs)) 
342 \end{code}
343
344 Here remove first column is more difficult that with literals due to the fact 
345 that constructors can have arguments.
346
347 For instance, the matrix
348 \begin{verbatim}
349  (: x xs) y
350  z        y
351 \end{verbatim}
352 is transformed in:
353 \begin{verbatim}
354  x xs y
355  _ _  y
356 \end{verbatim}
357
358 \begin{code}
359 remove_first_column :: TypecheckedPat                -- Constructor 
360                     -> [EquationInfo] 
361                     -> [EquationInfo]
362 remove_first_column (ConPatOut con (PrefixCon con_pats) _ _ _) qs
363   = ASSERT2( okGroup qs, pprGroup qs ) 
364     map shift_var (filter (is_var_con con . firstPat) qs)
365   where
366      new_wilds = [WildPat (hsPatType arg_pat) | arg_pat <- con_pats]
367      shift_var (EqnInfo n ctx (ConPatOut _ (PrefixCon ps') _ _ _:ps) result) = 
368                 EqnInfo n ctx (ps'++ps)               result 
369      shift_var (EqnInfo n ctx (WildPat _     :ps)     result) = 
370                 EqnInfo n ctx (new_wilds ++   ps)     result
371      shift_var _ = panic "Check.Shift_var:No done"
372
373 make_row_vars :: [HsLit] -> EquationInfo -> ExhaustivePat
374 make_row_vars used_lits (EqnInfo _ _ pats _ ) = 
375    (VarPat new_var:takeList (tail pats) (repeat new_wild_pat),[(new_var,used_lits)])
376   where new_var = hash_x
377
378 hash_x = mkInternalName unboundKey {- doesn't matter much -}
379                      (mkVarOcc FSLIT("#x"))
380                      noSrcLoc
381
382 make_row_vars_for_constructor :: EquationInfo -> [WarningPat]
383 make_row_vars_for_constructor (EqnInfo _ _ pats _ ) = takeList (tail pats) (repeat new_wild_pat)
384
385 compare_cons :: TypecheckedPat -> TypecheckedPat -> Bool
386 compare_cons (ConPatOut id1 _ _ _ _) (ConPatOut id2 _ _ _ _) = id1 == id2  
387
388 remove_dups :: [TypecheckedPat] -> [TypecheckedPat]
389 remove_dups []     = []
390 remove_dups (x:xs) | or (map (\y -> compare_cons x y) xs) = remove_dups  xs
391                    | otherwise                            = x : remove_dups xs
392
393 get_used_cons :: [EquationInfo] -> [TypecheckedPat]
394 get_used_cons qs = remove_dups [con | (EqnInfo _ _ (con@(ConPatOut _ _ _ _ _):_) _) <- qs ]
395
396 remove_dups' :: [HsLit] -> [HsLit] 
397 remove_dups' []                   = []
398 remove_dups' (x:xs) | x `elem` xs = remove_dups' xs
399                     | otherwise   = x : remove_dups' xs 
400
401
402 get_used_lits :: [EquationInfo] -> [HsLit]
403 get_used_lits qs = remove_dups' all_literals
404                  where
405                    all_literals = get_used_lits' qs
406
407 get_used_lits' :: [EquationInfo] -> [HsLit]
408 get_used_lits' [] = []
409 get_used_lits' ((EqnInfo _ _ ((LitPat lit):_) _):qs) = 
410                lit : get_used_lits qs
411 get_used_lits' ((EqnInfo _ _ ((NPatOut lit _ _):_) _):qs) = 
412                lit : get_used_lits qs
413 get_used_lits' (q:qs)                                  =       
414                get_used_lits qs
415
416 get_unused_cons :: [TypecheckedPat] -> [DataCon]
417 get_unused_cons used_cons = unused_cons
418      where
419        (ConPatOut _ _ ty _ _) = head used_cons
420        ty_con                 = tcTyConAppTyCon ty              -- Newtype observable
421        all_cons               = tyConDataCons ty_con
422        used_cons_as_id        = map (\ (ConPatOut d _ _ _ _) -> d) used_cons
423        unused_cons            = uniqSetToList
424                  (mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id) 
425
426 all_vars :: [TypecheckedPat] -> Bool
427 all_vars []              = True
428 all_vars (WildPat _:ps)  = all_vars ps
429 all_vars _               = False
430
431 remove_var :: EquationInfo -> EquationInfo
432 remove_var (EqnInfo n ctx (WildPat _:ps) result) = EqnInfo n ctx ps result
433 remove_var _                                     =
434          panic "Check.remove_var: equation does not begin with a variable"
435
436 -----------------------
437 eqnPats :: EquationInfo -> [TypecheckedPat]
438 eqnPats (EqnInfo _ _ ps _) = ps
439
440 firstPat :: EquationInfo -> TypecheckedPat
441 firstPat eqn_info = head (eqnPats eqn_info)
442
443 okGroup :: [EquationInfo] -> Bool
444 -- True if all equations have at least one pattern, and
445 -- all have the same number of patterns
446 okGroup [] = True
447 okGroup (e:es) = n_pats > 0 && and [length (eqnPats e) == n_pats | e <- es]
448                where
449                  n_pats = length (eqnPats e)
450
451 -- Half-baked print
452 pprGroup es = vcat (map pprEqnInfo es)
453 pprEqnInfo e = ppr (eqnPats e)
454
455 is_con :: TypecheckedPat -> Bool
456 is_con (ConPatOut _ _ _ _ _) = True
457 is_con _                     = False
458
459 is_lit :: TypecheckedPat -> Bool
460 is_lit (LitPat _)      = True
461 is_lit (NPatOut _ _ _) = True
462 is_lit _               = False
463
464 is_npat :: TypecheckedPat -> Bool
465 is_npat (NPatOut _ _ _) = True
466 is_npat _               = False
467
468 is_nplusk :: TypecheckedPat -> Bool
469 is_nplusk (NPlusKPatOut _ _ _ _) = True
470 is_nplusk _                      = False
471
472 is_var :: TypecheckedPat -> Bool
473 is_var (WildPat _) = True
474 is_var _           = False
475
476 is_var_con :: DataCon -> TypecheckedPat -> Bool
477 is_var_con con (WildPat _)                        = True
478 is_var_con con (ConPatOut id _ _ _ _) | id == con = True
479 is_var_con con _                                  = False
480
481 is_var_lit :: HsLit -> TypecheckedPat -> Bool
482 is_var_lit lit (WildPat _)                      = True
483 is_var_lit lit (LitPat lit')      | lit == lit' = True
484 is_var_lit lit (NPatOut lit' _ _) | lit == lit' = True
485 is_var_lit lit _                                = False
486 \end{code}
487
488 The difference beteewn @make_con@ and @make_whole_con@ is that
489 @make_wole_con@ creates a new constructor with all their arguments, and
490 @make_con@ takes a list of argumntes, creates the contructor getting their
491 arguments from the list. See where \fbox{\ ???\ } are used for details.
492
493 We need to reconstruct the patterns (make the constructors infix and
494 similar) at the same time that we create the constructors.
495
496 You can tell tuple constructors using
497 \begin{verbatim}
498         Id.isTupleCon
499 \end{verbatim}
500 You can see if one constructor is infix with this clearer code :-))))))))))
501 \begin{verbatim}
502         Lex.isLexConSym (Name.occNameString (Name.getOccName con))
503 \end{verbatim}
504
505        Rather clumsy but it works. (Simon Peyton Jones)
506
507
508 We don't mind the @nilDataCon@ because it doesn't change the way to
509 print the messsage, we are searching only for things like: @[1,2,3]@,
510 not @x:xs@ ....
511
512 In @reconstruct_pat@ we want to ``undo'' the work
513 that we have done in @simplify_pat@.
514 In particular:
515 \begin{tabular}{lll}
516         @((,) x y)@   & returns to be & @(x, y)@
517 \\      @((:) x xs)@  & returns to be & @(x:xs)@
518 \\      @(x:(...:[])@ & returns to be & @[x,...]@
519 \end{tabular}
520 %
521 The difficult case is the third one becouse we need to follow all the
522 contructors until the @[]@ to know that we need to use the second case,
523 not the second. \fbox{\ ???\ }
524 %
525 \begin{code}
526 isInfixCon con = isDataSymOcc (getOccName con)
527
528 is_nil (ConPatIn con (PrefixCon [])) = con == getName nilDataCon
529 is_nil _                             = False
530
531 is_list (ListPat _ _) = True
532 is_list _             = False
533
534 return_list id q = id == consDataCon && (is_nil q || is_list q) 
535
536 make_list p q | is_nil q    = ListPat [p] placeHolderType
537 make_list p (ListPat ps ty) = ListPat (p:ps) ty
538 make_list _ _               = panic "Check.make_list: Invalid argument"
539
540 make_con :: TypecheckedPat -> ExhaustivePat -> ExhaustivePat           
541 make_con (ConPatOut id _ _ _ _) (p:q:ps, constraints) 
542      | return_list id q = (make_list p q : ps, constraints)
543      | isInfixCon id    = (ConPatIn (getName id) (InfixCon p q) : ps, constraints) 
544
545 make_con (ConPatOut id (PrefixCon pats) _ _ _) (ps, constraints) 
546       | isTupleTyCon tc  = (TuplePat pats_con (tupleTyConBoxity tc) : rest_pats, constraints) 
547       | isPArrFakeCon id = (PArrPat pats_con placeHolderType        : rest_pats, constraints) 
548       | otherwise        = (ConPatIn name (PrefixCon pats_con)      : rest_pats, constraints)
549     where 
550         name                  = getName id
551         (pats_con, rest_pats) = splitAtList pats ps
552         tc                    = dataConTyCon id
553
554 -- reconstruct parallel array pattern
555 --
556 -- * don't check for the type only; we need to make sure that we are really
557 --   dealing with one of the fake constructors and not with the real
558 --   representation 
559
560 make_whole_con :: DataCon -> WarningPat
561 make_whole_con con | isInfixCon con = ConPatIn name (InfixCon new_wild_pat new_wild_pat)
562                    | otherwise      = ConPatIn name (PrefixCon pats)
563                 where 
564                   name   = getName con
565                   pats   = [new_wild_pat | t <- dataConOrigArgTys con]
566
567 new_wild_pat :: WarningPat
568 new_wild_pat = WildPat placeHolderType
569 \end{code}
570
571 This equation makes the same thing as @tidy@ in @Match.lhs@, the
572 difference is that here we can do all the tidy in one place and in the
573 @Match@ tidy it must be done one column each time due to bookkeeping 
574 constraints.
575
576 \begin{code}
577
578 simplify_eqns :: [EquationInfo] -> [EquationInfo]
579 simplify_eqns []                               = []
580 simplify_eqns ((EqnInfo n ctx pats result):qs) = 
581  (EqnInfo n ctx pats' result) : simplify_eqns qs
582  where
583   pats' = map simplify_pat pats
584
585 simplify_pat :: TypecheckedPat -> TypecheckedPat  
586
587 simplify_pat pat@(WildPat gt) = pat
588 simplify_pat (VarPat id)      = WildPat (idType id) 
589
590 simplify_pat (ParPat p)          = simplify_pat p
591 simplify_pat (LazyPat p)         = simplify_pat p
592 simplify_pat (AsPat id p)        = simplify_pat p
593 simplify_pat (SigPatOut p ty fn) = simplify_pat p       -- I'm not sure this is right
594
595 simplify_pat (ConPatOut id ps ty tvs dicts) = ConPatOut id (simplify_con id ps) ty tvs dicts
596
597 simplify_pat (ListPat ps ty) = foldr (\ x y -> mkPrefixConPat consDataCon [x,y] list_ty)
598                                      (mkNilPat list_ty)
599                                      (map simplify_pat ps)
600                              where list_ty = mkListTy ty
601
602 -- introduce fake parallel array constructors to be able to handle parallel
603 -- arrays with the existing machinery for constructor pattern
604 --
605 simplify_pat (PArrPat ps ty)
606   = ConPatOut (parrFakeCon arity)
607               (PrefixCon (map simplify_pat ps)) 
608               (mkPArrTy ty) [] [] 
609   where
610     arity = length ps
611
612 simplify_pat (TuplePat ps boxity)
613   = ConPatOut (tupleCon boxity arity)
614               (PrefixCon (map simplify_pat ps))
615               (mkTupleTy boxity arity (map hsPatType ps)) [] []
616   where
617     arity = length ps
618
619 simplify_pat pat@(LitPat lit) = tidyLitPat lit pat
620
621 -- unpack string patterns fully, so we can see when they overlap with
622 -- each other, or even explicit lists of Chars.
623 simplify_pat pat@(NPatOut (HsString s) _ _) = 
624    foldr (\c pat -> ConPatOut consDataCon (PrefixCon [mk_char_lit c,pat]) stringTy [] [])
625          (ConPatOut nilDataCon (PrefixCon []) stringTy [] []) (unpackIntFS s)
626   where
627     mk_char_lit c = ConPatOut charDataCon (PrefixCon [LitPat (HsCharPrim c)]) 
628                               charTy [] [] 
629
630 simplify_pat pat@(NPatOut lit lit_ty hsexpr) = tidyNPat lit lit_ty pat
631
632 simplify_pat (NPlusKPatOut id hslit hsexpr1 hsexpr2)
633    = WildPat (idType id)
634
635 simplify_pat (DictPat dicts methods)
636   = case num_of_d_and_ms of
637        0 -> simplify_pat (TuplePat [] Boxed) 
638        1 -> simplify_pat (head dict_and_method_pats) 
639        _ -> simplify_pat (TuplePat dict_and_method_pats Boxed)
640     where
641        num_of_d_and_ms   = length dicts + length methods
642        dict_and_method_pats = map VarPat (dicts ++ methods)
643
644 -----------------
645 simplify_con con (PrefixCon ps)   = PrefixCon (map simplify_pat ps)
646 simplify_con con (InfixCon p1 p2) = PrefixCon [simplify_pat p1, simplify_pat p2]
647 simplify_con con (RecCon fs)      
648   | null fs   = PrefixCon [wild_pat | t <- dataConOrigArgTys con]
649                 -- Special case for null patterns; maybe not a record at all
650   | otherwise = PrefixCon (map (simplify_pat.snd) all_pats)
651   where
652      -- pad out all the missing fields with WildPats.
653     field_pats = map (\ f -> (getName f, wild_pat))
654                      (dataConFieldLabels con)
655     all_pats = foldr (\ (id,p) acc -> insertNm (getName id) p acc)
656                      field_pats fs
657        
658     insertNm nm p [] = [(nm,p)]
659     insertNm nm p (x@(n,_):xs)
660       | nm == n    = (nm,p):xs
661       | otherwise  = x : insertNm nm p xs
662
663     wild_pat = WildPat (panic "Check.simplify_con")
664 \end{code}