152d082050ee212ca89fa7329acec8c118c68278
[ghc-hetmet.git] / ghc / compiler / deSugar / MatchCon.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[MatchCon]{Pattern-matching constructors}
5
6 \begin{code}
7 module MatchCon ( matchConFamily ) where
8
9 #include "HsVersions.h"
10
11 import {-# SOURCE #-} Match     ( match )
12
13 import HsSyn            ( OutPat(..), HsLit, HsExpr )
14 import DsHsSyn          ( outPatType )
15
16 import DsMonad
17 import DsUtils
18
19 import Id               ( GenId{-instances-}, Id )
20 import Util             ( panic, assertPanic )
21 \end{code}
22
23 We are confronted with the first column of patterns in a set of
24 equations, all beginning with constructors from one ``family'' (e.g.,
25 @[]@ and @:@ make up the @List@ ``family'').  We want to generate the
26 alternatives for a @Case@ expression.  There are several choices:
27 \begin{enumerate}
28 \item
29 Generate an alternative for every constructor in the family, whether
30 they are used in this set of equations or not; this is what the Wadler
31 chapter does.
32 \begin{description}
33 \item[Advantages:]
34 (a)~Simple.  (b)~It may also be that large sparsely-used constructor
35 families are mainly handled by the code for literals.
36 \item[Disadvantages:]
37 (a)~Not practical for large sparsely-used constructor families, e.g.,
38 the ASCII character set.  (b)~Have to look up a list of what
39 constructors make up the whole family.
40 \end{description}
41
42 \item
43 Generate an alternative for each constructor used, then add a default
44 alternative in case some constructors in the family weren't used.
45 \begin{description}
46 \item[Advantages:]
47 (a)~Alternatives aren't generated for unused constructors.  (b)~The
48 STG is quite happy with defaults.  (c)~No lookup in an environment needed.
49 \item[Disadvantages:]
50 (a)~A spurious default alternative may be generated.
51 \end{description}
52
53 \item
54 ``Do it right:'' generate an alternative for each constructor used,
55 and add a default alternative if all constructors in the family
56 weren't used.
57 \begin{description}
58 \item[Advantages:]
59 (a)~You will get cases with only one alternative (and no default),
60 which should be amenable to optimisation.  Tuples are a common example.
61 \item[Disadvantages:]
62 (b)~Have to look up constructor families in TDE (as above).
63 \end{description}
64 \end{enumerate}
65
66 We are implementing the ``do-it-right'' option for now.  The arguments
67 to @matchConFamily@ are the same as to @match@; the extra @Int@
68 returned is the number of constructors in the family.
69
70 The function @matchConFamily@ is concerned with this
71 have-we-used-all-the-constructors? question; the local function
72 @match_cons_used@ does all the real work.
73 \begin{code}
74 matchConFamily :: [Id]
75                -> [EquationInfo]
76                -> DsM MatchResult
77
78 matchConFamily (var:vars) eqns_info
79   = match_cons_used vars eqns_info `thenDs` \ alts ->
80     mkCoAlgCaseMatchResult var alts
81 \end{code}
82
83 And here is the local function that does all the work.  It is
84 more-or-less the @matchCon@/@matchClause@ functions on page~94 in
85 Wadler's chapter in SLPJ.
86 \begin{code}
87 match_cons_used _ [{- no more eqns -}] = returnDs []
88
89 match_cons_used vars eqns_info@(EqnInfo n ctx (ConPat data_con _ arg_pats : ps1) _ : eqns)
90   = let
91         (eqns_for_this_con, eqns_not_for_this_con)       = splitByCon eqns_info
92     in
93     -- Go ahead and do the recursive call to make the alts
94     -- for the other ConPats in this con family...
95     match_cons_used vars eqns_not_for_this_con            `thenDs` \ rest_of_alts ->
96
97     -- Make new vars for the con arguments; avoid new locals where possible
98     selectMatchVars arg_pats                               `thenDs` \ new_vars ->
99
100     -- Now do the business to make the alt for _this_ ConPat ...
101     match (new_vars++vars)
102           (map shift_con_pat eqns_for_this_con)            `thenDs` \ match_result ->
103
104     returnDs (
105         (data_con, new_vars, match_result)
106         : rest_of_alts
107     )
108   where
109     splitByCon :: [EquationInfo] -> ([EquationInfo], [EquationInfo])
110     splitByCon [] = ([],[])
111     splitByCon (info@(EqnInfo _ _ (pat : _) _) : rest)
112         = case pat of
113                 ConPat n _ _ | n == data_con -> (info:rest_yes, rest_no)
114                 other_pat                    -> (rest_yes,      info:rest_no)
115         where
116           (rest_yes, rest_no) = splitByCon rest
117
118     shift_con_pat :: EquationInfo -> EquationInfo
119     shift_con_pat (EqnInfo n ctx (ConPat _ _ pats': pats) match_result)
120       = EqnInfo n ctx (pats' ++ pats) match_result
121     shift_con_pat (EqnInfo n ctx (WildPat _: pats) match_result) -- Will only happen in shadow
122       = EqnInfo n ctx ([WildPat (outPatType arg_pat) | arg_pat <- arg_pats] ++ pats) match_result
123     shift_con_pat other = panic "matchConFamily:match_cons_used:shift_con_pat"
124 \end{code}
125
126 Note on @shift_con_pats@ just above: does what the list comprehension in
127 @matchClause@ (SLPJ, p.~94) does, except things are trickier in real
128 life.  Works for @ConPats@, and we want it to fail catastrophically
129 for anything else (which a list comprehension wouldn't).
130 Cf.~@shift_lit_pats@ in @MatchLits@.