048b9933f1fe744e2fa54fa0651348f03ba905c0
[ghc-hetmet.git] / ghc / compiler / typecheck / TcGenDeriv.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[TcGenDeriv]{Generating derived instance declarations}
5
6 This module is nominally ``subordinate'' to @TcDeriv@, which is the
7 ``official'' interface to deriving-related things.
8
9 This is where we do all the grimy bindings' generation.
10
11 \begin{code}
12 module TcGenDeriv (
13         gen_Bounded_binds,
14         gen_Enum_binds,
15         gen_Eval_binds,
16         gen_Eq_binds,
17         gen_Ix_binds,
18         gen_Ord_binds,
19         gen_Read_binds,
20         gen_Show_binds,
21         gen_tag_n_con_monobind,
22
23         con2tag_RDR, tag2con_RDR, maxtag_RDR,
24
25         TagThingWanted(..)
26     ) where
27
28 #include "HsVersions.h"
29
30 import HsSyn            ( InPat(..), HsExpr(..), MonoBinds(..), GRHS(..), 
31                           Match(..), GRHSsAndBinds(..), Stmt(..), HsLit(..),
32                           HsBinds(..), DoOrListComp(..),
33                           unguardedRHS
34                         )
35 import RdrHsSyn         ( RdrName(..), varUnqual, mkOpApp,
36                           RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat
37                         )
38 import BasicTypes       ( IfaceFlavour(..), RecFlag(..) )
39 import FieldLabel       ( fieldLabelName )
40 import Id               ( GenId, isNullaryDataCon, dataConTag,
41                           dataConRawArgTys, fIRST_TAG,
42                           isDataCon, DataCon, ConTag,
43                           dataConFieldLabels, Id )
44 import Maybes           ( maybeToBool )
45 import Name             ( getOccString, getOccName, getSrcLoc, occNameString, 
46                           modAndOcc, OccName, Name )
47
48 import PrimOp           ( PrimOp(..) )
49 import PrelInfo         -- Lots of RdrNames
50 import SrcLoc           ( mkGeneratedSrcLoc, SrcLoc )
51 import TyCon            ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
52 import Type             ( isUnpointedType, isUnboxedType, Type )
53 import TysPrim          ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
54                           floatPrimTy, doublePrimTy
55                         )
56 import Util             ( mapAccumL, zipEqual, zipWithEqual,
57                           zipWith3Equal, nOfThem, panic, assertPanic )
58
59 import List             ( partition, intersperse )
60 \end{code}
61
62 %************************************************************************
63 %*                                                                      *
64 \subsection{Generating code, by derivable class}
65 %*                                                                      *
66 %************************************************************************
67
68 %************************************************************************
69 %*                                                                      *
70 \subsubsection{Generating @Eq@ instance declarations}
71 %*                                                                      *
72 %************************************************************************
73
74 Here are the heuristics for the code we generate for @Eq@:
75 \begin{itemize}
76 \item
77   Let's assume we have a data type with some (possibly zero) nullary
78   data constructors and some ordinary, non-nullary ones (the rest,
79   also possibly zero of them).  Here's an example, with both \tr{N}ullary
80   and \tr{O}rdinary data cons.
81 \begin{verbatim}
82 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
83 \end{verbatim}
84
85 \item
86   For the ordinary constructors (if any), we emit clauses to do The
87   Usual Thing, e.g.,:
88
89 \begin{verbatim}
90 (==) (O1 a1 b1)    (O1 a2 b2)    = a1 == a2 && b1 == b2
91 (==) (O2 a1)       (O2 a2)       = a1 == a2
92 (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2
93 \end{verbatim}
94
95   Note: if we're comparing unboxed things, e.g., if \tr{a1} and
96   \tr{a2} are \tr{Float#}s, then we have to generate
97 \begin{verbatim}
98 case (a1 `eqFloat#` a2) of
99   r -> r
100 \end{verbatim}
101   for that particular test.
102
103 \item
104   If there are any nullary constructors, we emit a catch-all clause of
105   the form:
106
107 \begin{verbatim}
108 (==) a b  = case (con2tag_Foo a) of { a# ->
109             case (con2tag_Foo b) of { b# ->
110             case (a# ==# b#)     of {
111               r -> r
112             }}}
113 \end{verbatim}
114
115   If there aren't any nullary constructors, we emit a simpler
116   catch-all:
117 \begin{verbatim}
118 (==) a b  = False
119 \end{verbatim}
120
121 \item
122   For the @(/=)@ method, we normally just use the default method.
123
124   If the type is an enumeration type, we could/may/should? generate
125   special code that calls @con2tag_Foo@, much like for @(==)@ shown
126   above.
127
128 \item
129   We thought about doing this: If we're also deriving @Ord@ for this
130   tycon, we generate:
131 \begin{verbatim}
132 instance ... Eq (Foo ...) where
133   (==) a b  = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
134   (/=) a b  = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
135 \begin{verbatim}
136   However, that requires that \tr{Ord <whatever>} was put in the context
137   for the instance decl, which it probably wasn't, so the decls
138   produced don't get through the typechecker.
139 \end{itemize}
140
141
142 deriveEq :: RdrName                             -- Class
143          -> RdrName                             -- Type constructor
144          -> [ (RdrName, [RdrType]) ]    -- Constructors
145          -> (RdrContext,                -- Context for the inst decl
146              [RdrBind],                 -- Binds in the inst decl
147              [RdrBind])                 -- Extra value bindings outside
148
149 deriveEq clas tycon constrs 
150   = (context, [eq_bind, ne_bind], [])
151   where
152     context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
153
154     ne_bind = mkBind 
155     (nullary_cons, non_nullary_cons) = partition is_nullary constrs
156     is_nullary (_, args) = null args
157
158 \begin{code}
159 gen_Eq_binds :: TyCon -> RdrNameMonoBinds
160
161 gen_Eq_binds tycon
162   = let
163         tycon_loc = getSrcLoc tycon
164         (nullary_cons, nonnullary_cons)
165            | isNewTyCon tycon = ([], tyConDataCons tycon)
166            | otherwise        = partition isNullaryDataCon (tyConDataCons tycon)
167
168         rest
169           = if (null nullary_cons) then
170                 case maybeTyConSingleCon tycon of
171                   Just _ -> []
172                   Nothing -> -- if cons don't match, then False
173                      [([a_Pat, b_Pat], false_Expr)]
174             else -- calc. and compare the tags
175                  [([a_Pat, b_Pat],
176                     untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
177                       (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR true_Expr false_Expr))]
178     in
179     mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
180             `AndMonoBinds`
181     mk_easy_FunMonoBind tycon_loc ne_RDR [a_Pat, b_Pat] [] (
182         HsApp (HsVar not_RDR) (HsPar (mk_easy_App eq_RDR [a_RDR, b_RDR])))
183   where
184     ------------------------------------------------------------------
185     pats_etc data_con
186       = let
187             con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
188             con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
189
190             data_con_RDR = qual_orig_name data_con
191             con_arity   = length tys_needed
192             as_needed   = take con_arity as_RDRs
193             bs_needed   = take con_arity bs_RDRs
194             tys_needed  = dataConRawArgTys data_con
195         in
196         ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
197       where
198         nested_eq_expr []  [] [] = true_Expr
199         nested_eq_expr tys as bs
200           = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
201           where
202             nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
203 \end{code}
204
205 %************************************************************************
206 %*                                                                      *
207 \subsubsection{Generating @Ord@ instance declarations}
208 %*                                                                      *
209 %************************************************************************
210
211 For a derived @Ord@, we concentrate our attentions on @compare@
212 \begin{verbatim}
213 compare :: a -> a -> Ordering
214 data Ordering = LT | EQ | GT deriving ()
215 \end{verbatim}
216
217 We will use the same example data type as above:
218 \begin{verbatim}
219 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
220 \end{verbatim}
221
222 \begin{itemize}
223 \item
224   We do all the other @Ord@ methods with calls to @compare@:
225 \begin{verbatim}
226 instance ... (Ord <wurble> <wurble>) where
227     a <  b  = case (compare a b) of { LT -> True;  EQ -> False; GT -> False }
228     a <= b  = case (compare a b) of { LT -> True;  EQ -> True;  GT -> False }
229     a >= b  = case (compare a b) of { LT -> False; EQ -> True;  GT -> True  }
230     a >  b  = case (compare a b) of { LT -> False; EQ -> False; GT -> True  }
231
232     max a b = case (compare a b) of { LT -> b; EQ -> a;  GT -> a }
233     min a b = case (compare a b) of { LT -> a; EQ -> b;  GT -> b }
234
235     -- compare to come...
236 \end{verbatim}
237
238 \item
239   @compare@ always has two parts.  First, we use the compared
240   data-constructors' tags to deal with the case of different
241   constructors:
242 \begin{verbatim}
243 compare a b = case (con2tag_Foo a) of { a# ->
244               case (con2tag_Foo b) of { b# ->
245               case (a# ==# b#)     of {
246                True  -> cmp_eq a b
247                False -> case (a# <# b#) of
248                          True  -> _LT
249                          False -> _GT
250               }}}
251   where
252     cmp_eq = ... to come ...
253 \end{verbatim}
254
255 \item
256   We are only left with the ``help'' function @cmp_eq@, to deal with
257   comparing data constructors with the same tag.
258
259   For the ordinary constructors (if any), we emit the sorta-obvious
260   compare-style stuff; for our example:
261 \begin{verbatim}
262 cmp_eq (O1 a1 b1) (O1 a2 b2)
263   = case (compare a1 a2) of { LT -> LT; EQ -> compare b1 b2; GT -> GT }
264
265 cmp_eq (O2 a1) (O2 a2)
266   = compare a1 a2
267
268 cmp_eq (O3 a1 b1 c1) (O3 a2 b2 c2)
269   = case (compare a1 a2) of {
270       LT -> LT;
271       GT -> GT;
272       EQ -> case compare b1 b2 of {
273               LT -> LT;
274               GT -> GT;
275               EQ -> compare c1 c2
276             }
277     }
278 \end{verbatim}
279
280   Again, we must be careful about unboxed comparisons.  For example,
281   if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
282   generate:
283
284 \begin{verbatim}
285 cmp_eq lt eq gt (O2 a1) (O2 a2)
286   = compareInt# a1 a2
287   -- or maybe the unfolded equivalent
288 \end{verbatim}
289
290 \item
291   For the remaining nullary constructors, we already know that the
292   tags are equal so:
293 \begin{verbatim}
294 cmp_eq _ _ = EQ
295 \end{verbatim}
296 \end{itemize}
297
298 If there is only one constructor in the Data Type we don't need the WildCard Pattern. 
299 JJQC-30-Nov-1997
300
301 \begin{code}
302 gen_Ord_binds :: TyCon -> RdrNameMonoBinds
303
304 gen_Ord_binds tycon
305   = defaulted `AndMonoBinds` compare
306   where
307     tycon_loc = getSrcLoc tycon
308     --------------------------------------------------------------------
309     compare = mk_easy_FunMonoBind tycon_loc compare_RDR
310                 [a_Pat, b_Pat]
311                 [cmp_eq]
312             (if maybeToBool (maybeTyConSingleCon tycon) then
313                 cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
314              else
315                 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
316                   (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR
317                         -- True case; they are equal
318                         -- If an enumeration type we are done; else
319                         -- recursively compare their components
320                     (if isEnumerationTyCon tycon then
321                         eqTag_Expr
322                      else
323                         cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
324                     )
325                         -- False case; they aren't equal
326                         -- So we need to do a less-than comparison on the tags
327                     (cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
328
329     tycon_data_cons = tyConDataCons tycon
330     (nullary_cons, nonnullary_cons)
331        | isNewTyCon tycon = ([], tyConDataCons tycon)
332        | otherwise        = partition isNullaryDataCon tycon_data_cons
333
334     cmp_eq =
335        mk_FunMonoBind tycon_loc 
336                       cmp_eq_RDR 
337                       (if null nonnullary_cons && (length nullary_cons == 1) then
338                            -- catch this specially to avoid warnings
339                            -- about overlapping patterns from the desugarer.
340                           let 
341                            data_con     = head nullary_cons
342                            data_con_RDR = qual_orig_name data_con
343                            pat          = ConPatIn data_con_RDR []
344                           in
345                           [([pat,pat], eqTag_Expr)]
346                        else
347                           map pats_etc nonnullary_cons ++
348                           -- leave out wildcards to silence desugarer.
349                           (if length tycon_data_cons == 1 then
350                               []
351                            else
352                               [([WildPatIn, WildPatIn], default_rhs)]))
353       where
354         pats_etc data_con
355           = ([con1_pat, con2_pat],
356              nested_compare_expr tys_needed as_needed bs_needed)
357           where
358             con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
359             con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
360
361             data_con_RDR = qual_orig_name data_con
362             con_arity   = length tys_needed
363             as_needed   = take con_arity as_RDRs
364             bs_needed   = take con_arity bs_RDRs
365             tys_needed  = dataConRawArgTys data_con
366
367             nested_compare_expr [ty] [a] [b]
368               = careful_compare_Case ty ltTag_Expr eqTag_Expr gtTag_Expr (HsVar a) (HsVar b)
369
370             nested_compare_expr (ty:tys) (a:as) (b:bs)
371               = let eq_expr = nested_compare_expr tys as bs
372                 in  careful_compare_Case ty ltTag_Expr eq_expr gtTag_Expr (HsVar a) (HsVar b)
373
374         default_rhs | null nullary_cons = impossible_Expr       -- Keep desugarer from complaining about
375                                                                 -- inexhaustive patterns
376                     | otherwise         = eqTag_Expr            -- Some nullary constructors;
377                                                                 -- Tags are equal, no args => return EQ
378     --------------------------------------------------------------------
379
380 defaulted = foldr1 AndMonoBinds [lt, le, ge, gt, max_, min_]
381
382 lt = mk_easy_FunMonoBind mkGeneratedSrcLoc lt_RDR [a_Pat, b_Pat] [] (
383             compare_Case true_Expr  false_Expr false_Expr a_Expr b_Expr)
384 le = mk_easy_FunMonoBind mkGeneratedSrcLoc le_RDR [a_Pat, b_Pat] [] (
385             compare_Case true_Expr  true_Expr  false_Expr a_Expr b_Expr)
386 ge = mk_easy_FunMonoBind mkGeneratedSrcLoc ge_RDR [a_Pat, b_Pat] [] (
387             compare_Case false_Expr true_Expr  true_Expr  a_Expr b_Expr)
388 gt = mk_easy_FunMonoBind mkGeneratedSrcLoc gt_RDR [a_Pat, b_Pat] [] (
389             compare_Case false_Expr false_Expr true_Expr  a_Expr b_Expr)
390
391 max_ = mk_easy_FunMonoBind mkGeneratedSrcLoc max_RDR [a_Pat, b_Pat] [] (
392             compare_Case b_Expr a_Expr a_Expr a_Expr b_Expr)
393 min_ = mk_easy_FunMonoBind mkGeneratedSrcLoc min_RDR [a_Pat, b_Pat] [] (
394             compare_Case a_Expr b_Expr b_Expr a_Expr b_Expr)
395 \end{code}
396
397 %************************************************************************
398 %*                                                                      *
399 \subsubsection{Generating @Enum@ instance declarations}
400 %*                                                                      *
401 %************************************************************************
402
403 @Enum@ can only be derived for enumeration types.  For a type
404 \begin{verbatim}
405 data Foo ... = N1 | N2 | ... | Nn
406 \end{verbatim}
407
408 we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
409 @maxtag_Foo@ variable (all generated by @gen_tag_n_con_binds@).
410
411 \begin{verbatim}
412 instance ... Enum (Foo ...) where
413     toEnum i = tag2con_Foo i
414
415     enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
416
417     -- or, really...
418     enumFrom a
419       = case con2tag_Foo a of
420           a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)
421
422    enumFromThen a b
423      = map tag2con_Foo [con2tag_Foo a, con2tag_Foo b .. maxtag_Foo]
424
425     -- or, really...
426     enumFromThen a b
427       = case con2tag_Foo a of { a# ->
428         case con2tag_Foo b of { b# ->
429         map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
430         }}
431 \end{verbatim}
432
433 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
434
435 \begin{code}
436 gen_Enum_binds :: TyCon -> RdrNameMonoBinds
437
438 gen_Enum_binds tycon
439   = to_enum             `AndMonoBinds`
440     enum_from           `AndMonoBinds`
441     enum_from_then      `AndMonoBinds`
442     from_enum
443   where
444     tycon_loc = getSrcLoc tycon
445
446     to_enum
447       = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
448         mk_easy_App (tag2con_RDR tycon) [a_RDR]
449
450     enum_from
451       = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
452           untag_Expr tycon [(a_RDR, ah_RDR)] $
453           HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
454             HsPar (enum_from_to_Expr
455                     (mk_easy_App mkInt_RDR [ah_RDR])
456                     (HsVar (maxtag_RDR tycon)))
457
458     enum_from_then
459       = mk_easy_FunMonoBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] [] $
460           untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
461           HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
462             HsPar (enum_from_then_to_Expr
463                     (mk_easy_App mkInt_RDR [ah_RDR])
464                     (mk_easy_App mkInt_RDR [bh_RDR])
465                     (HsVar (maxtag_RDR tycon)))
466
467     from_enum
468       = mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
469           untag_Expr tycon [(a_RDR, ah_RDR)] $
470           (mk_easy_App mkInt_RDR [ah_RDR])
471 \end{code}
472
473 %************************************************************************
474 %*                                                                      *
475 \subsubsection{Generating @Eval@ instance declarations}
476 %*                                                                      *
477 %************************************************************************
478
479 \begin{code}
480 gen_Eval_binds tycon = EmptyMonoBinds
481 \end{code}
482
483 %************************************************************************
484 %*                                                                      *
485 \subsubsection{Generating @Bounded@ instance declarations}
486 %*                                                                      *
487 %************************************************************************
488
489 \begin{code}
490 gen_Bounded_binds tycon
491   = if isEnumerationTyCon tycon then
492         min_bound_enum `AndMonoBinds` max_bound_enum
493     else
494         ASSERT(length data_cons == 1)
495         min_bound_1con `AndMonoBinds` max_bound_1con
496   where
497     data_cons = tyConDataCons tycon
498     tycon_loc = getSrcLoc tycon
499
500     ----- enum-flavored: ---------------------------
501     min_bound_enum = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] (HsVar data_con_1_RDR)
502     max_bound_enum = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] (HsVar data_con_N_RDR)
503
504     data_con_1    = head data_cons
505     data_con_N    = last data_cons
506     data_con_1_RDR = qual_orig_name data_con_1
507     data_con_N_RDR = qual_orig_name data_con_N
508
509     ----- single-constructor-flavored: -------------
510     arity          = argFieldCount data_con_1
511
512     min_bound_1con = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] $
513                      mk_easy_App data_con_1_RDR (nOfThem arity minBound_RDR)
514     max_bound_1con = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] $
515                      mk_easy_App data_con_1_RDR (nOfThem arity maxBound_RDR)
516 \end{code}
517
518 %************************************************************************
519 %*                                                                      *
520 \subsubsection{Generating @Ix@ instance declarations}
521 %*                                                                      *
522 %************************************************************************
523
524 Deriving @Ix@ is only possible for enumeration types and
525 single-constructor types.  We deal with them in turn.
526
527 For an enumeration type, e.g.,
528 \begin{verbatim}
529     data Foo ... = N1 | N2 | ... | Nn
530 \end{verbatim}
531 things go not too differently from @Enum@:
532 \begin{verbatim}
533 instance ... Ix (Foo ...) where
534     range (a, b)
535       = map tag2con_Foo [con2tag_Foo a .. con2tag_Foo b]
536
537     -- or, really...
538     range (a, b)
539       = case (con2tag_Foo a) of { a# ->
540         case (con2tag_Foo b) of { b# ->
541         map tag2con_Foo (enumFromTo (I# a#) (I# b#))
542         }}
543
544     index c@(a, b) d
545       = if inRange c d
546         then case (con2tag_Foo d -# con2tag_Foo a) of
547                r# -> I# r#
548         else error "Ix.Foo.index: out of range"
549
550     inRange (a, b) c
551       = let
552             p_tag = con2tag_Foo c
553         in
554         p_tag >= con2tag_Foo a && p_tag <= con2tag_Foo b
555
556     -- or, really...
557     inRange (a, b) c
558       = case (con2tag_Foo a)   of { a_tag ->
559         case (con2tag_Foo b)   of { b_tag ->
560         case (con2tag_Foo c)   of { c_tag ->
561         if (c_tag >=# a_tag) then
562           c_tag <=# b_tag
563         else
564           False
565         }}}
566 \end{verbatim}
567 (modulo suitable case-ification to handle the unboxed tags)
568
569 For a single-constructor type (NB: this includes all tuples), e.g.,
570 \begin{verbatim}
571     data Foo ... = MkFoo a b Int Double c c
572 \end{verbatim}
573 we follow the scheme given in Figure~19 of the Haskell~1.2 report
574 (p.~147).
575
576 \begin{code}
577 gen_Ix_binds :: TyCon -> RdrNameMonoBinds
578
579 gen_Ix_binds tycon
580   = if isEnumerationTyCon tycon
581     then enum_ixes
582     else single_con_ixes
583   where
584     tycon_str = getOccString tycon
585     tycon_loc = getSrcLoc tycon
586
587     --------------------------------------------------------------
588     enum_ixes = enum_range `AndMonoBinds`
589                 enum_index `AndMonoBinds` enum_inRange
590
591     enum_range
592       = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [a_Pat, b_Pat]] [] $
593           untag_Expr tycon [(a_RDR, ah_RDR)] $
594           untag_Expr tycon [(b_RDR, bh_RDR)] $
595           HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
596               HsPar (enum_from_to_Expr
597                         (mk_easy_App mkInt_RDR [ah_RDR])
598                         (mk_easy_App mkInt_RDR [bh_RDR]))
599
600     enum_index
601       = mk_easy_FunMonoBind tycon_loc index_RDR [AsPatIn c_RDR (TuplePatIn [a_Pat, b_Pat]), d_Pat] [] (
602         HsIf (HsPar (mk_easy_App inRange_RDR [c_RDR, d_RDR])) (
603            untag_Expr tycon [(a_RDR, ah_RDR)] (
604            untag_Expr tycon [(d_RDR, dh_RDR)] (
605            let
606                 grhs = unguardedRHS (mk_easy_App mkInt_RDR [c_RDR]) tycon_loc
607            in
608            HsCase
609              (genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
610              [PatMatch (VarPatIn c_RDR)
611                                 (GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
612              tycon_loc
613            ))
614         ) {-else-} (
615            HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ ("Ix."++tycon_str++".index: out of range\n"))))
616         )
617         tycon_loc)
618
619     enum_inRange
620       = mk_easy_FunMonoBind tycon_loc inRange_RDR [TuplePatIn [a_Pat, b_Pat], c_Pat] [] (
621           untag_Expr tycon [(a_RDR, ah_RDR)] (
622           untag_Expr tycon [(b_RDR, bh_RDR)] (
623           untag_Expr tycon [(c_RDR, ch_RDR)] (
624           HsIf (genOpApp (HsVar ch_RDR) geH_RDR (HsVar ah_RDR)) (
625              (genOpApp (HsVar ch_RDR) leH_RDR (HsVar bh_RDR))
626           ) {-else-} (
627              false_Expr
628           ) tycon_loc))))
629
630     --------------------------------------------------------------
631     single_con_ixes 
632       = single_con_range `AndMonoBinds`
633         single_con_index `AndMonoBinds`
634         single_con_inRange
635
636     data_con
637       = case maybeTyConSingleCon tycon of -- just checking...
638           Nothing -> panic "get_Ix_binds"
639           Just dc -> if (any isUnpointedType (dataConRawArgTys dc)) then
640                          error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
641                      else
642                          dc
643
644     con_arity    = argFieldCount data_con
645     data_con_RDR = qual_orig_name data_con
646
647     as_needed = take con_arity as_RDRs
648     bs_needed = take con_arity bs_RDRs
649     cs_needed = take con_arity cs_RDRs
650
651     con_pat  xs  = ConPatIn data_con_RDR (map VarPatIn xs)
652     con_expr     = mk_easy_App data_con_RDR cs_needed
653
654     --------------------------------------------------------------
655     single_con_range
656       = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed]] [] $
657         HsDo ListComp stmts tycon_loc
658       where
659         stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
660                 ++
661                 [ReturnStmt con_expr]
662
663         mk_qual a b c = BindStmt (VarPatIn c)
664                                  (HsApp (HsVar range_RDR) (ExplicitTuple [HsVar a, HsVar b]))
665                                  tycon_loc
666
667     ----------------
668     single_con_index
669       = mk_easy_FunMonoBind tycon_loc index_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed], con_pat cs_needed] [range_size] (
670         foldl mk_index (HsLit (HsInt 0)) (zip3 as_needed bs_needed cs_needed))
671       where
672         mk_index multiply_by (l, u, i)
673           = genOpApp (
674                 (HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [HsVar l, HsVar u])) (HsVar i))
675            ) plus_RDR (
676                 genOpApp (
677                     (HsApp (HsVar rangeSize_RDR) (ExplicitTuple [HsVar l, HsVar u]))
678                 ) times_RDR multiply_by
679            )
680
681         range_size
682           = mk_easy_FunMonoBind tycon_loc rangeSize_RDR [TuplePatIn [a_Pat, b_Pat]] [] (
683                 genOpApp (
684                     (HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [a_Expr, b_Expr])) b_Expr)
685                 ) plus_RDR (HsLit (HsInt 1)))
686
687     ------------------
688     single_con_inRange
689       = mk_easy_FunMonoBind tycon_loc inRange_RDR 
690                            [TuplePatIn [con_pat as_needed, con_pat bs_needed], con_pat cs_needed]
691                            [] (
692           foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
693       where
694         in_range a b c = HsApp (HsApp (HsVar inRange_RDR) (ExplicitTuple [HsVar a, HsVar b])) (HsVar c)
695 \end{code}
696
697 %************************************************************************
698 %*                                                                      *
699 \subsubsection{Generating @Read@ instance declarations}
700 %*                                                                      *
701 %************************************************************************
702
703 Ignoring all the infix-ery mumbo jumbo (ToDo)
704
705 \begin{code}
706 gen_Read_binds :: TyCon -> RdrNameMonoBinds
707
708 gen_Read_binds tycon
709   = reads_prec `AndMonoBinds` read_list
710   where
711     tycon_loc = getSrcLoc tycon
712     -----------------------------------------------------------------------
713     read_list = mk_easy_FunMonoBind tycon_loc readList_RDR [] []
714                   (HsApp (HsVar readList___RDR) (HsPar (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 0)))))
715     -----------------------------------------------------------------------
716     reads_prec
717       = let
718             read_con_comprehensions
719               = map read_con (tyConDataCons tycon)
720         in
721         mk_easy_FunMonoBind tycon_loc readsPrec_RDR [a_Pat, b_Pat] [] (
722               foldr1 append_Expr read_con_comprehensions
723         )
724       where
725         read_con data_con   -- note: "b" is the string being "read"
726           = let
727                 data_con_RDR = qual_orig_name data_con
728                 data_con_str= occNameString (getOccName data_con)
729                 con_arity   = argFieldCount data_con
730                 con_expr    = mk_easy_App data_con_RDR as_needed
731                 nullary_con = con_arity == 0
732                 labels      = dataConFieldLabels data_con
733                 lab_fields  = length labels
734
735                 as_needed   = take con_arity as_RDRs
736                 bs_needed   
737                  | lab_fields == 0 = take con_arity bs_RDRs
738                  | otherwise       = take (4*lab_fields + 1) bs_RDRs
739                                        -- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
740                 con_qual
741                   = BindStmt
742                           (TuplePatIn [LitPatIn (HsString data_con_str), d_Pat])
743                           (HsApp (HsVar lex_RDR) c_Expr)
744                           tycon_loc
745
746                 str_qual str res draw_from
747                   = BindStmt
748                        (TuplePatIn [LitPatIn (HsString str), VarPatIn res])
749                        (HsApp (HsVar lex_RDR) draw_from)
750                        tycon_loc
751   
752                 read_label f
753                   = let nm = occNameString (getOccName (fieldLabelName f))
754                     in 
755                         [str_qual nm, str_qual SLIT("=")] 
756                             -- There might be spaces between the label and '='
757
758                 field_quals
759                   | lab_fields == 0 =
760                      snd (mapAccumL mk_qual 
761                                     d_Expr 
762                                     (zipWithEqual "as_needed" 
763                                                   (\ con_field draw_from -> (mk_read_qual con_field,
764                                                                              draw_from))
765                                                   as_needed bs_needed))
766                   | otherwise =
767                      snd $
768                      mapAccumL mk_qual d_Expr
769                         (zipEqual "bs_needed"        
770                            ((str_qual (SLIT("{")):
771                              concat (
772                              intersperse ([str_qual (_CONS_ ',' _NIL_)]) $
773                              zipWithEqual 
774                                 "field_quals"
775                                 (\ as b -> as ++ [b])
776                                     -- The labels
777                                 (map read_label labels)
778                                     -- The fields
779                                 (map mk_read_qual as_needed))) ++ [str_qual (SLIT("}"))])
780                             bs_needed)
781
782                 mk_qual draw_from (f, str_left)
783                   = (HsVar str_left,    -- what to draw from down the line...
784                      f str_left draw_from)
785
786                 mk_read_qual con_field res draw_from =
787                   BindStmt
788                    (TuplePatIn [VarPatIn con_field, VarPatIn res])
789                    (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 10))) draw_from)
790                    tycon_loc
791
792                 result_expr = ExplicitTuple [con_expr, if null bs_needed 
793                                                        then d_Expr 
794                                                        else HsVar (last bs_needed)]
795
796                 stmts = con_qual:field_quals ++ [ReturnStmt result_expr]
797                 
798                 read_paren_arg
799                   = if nullary_con then -- must be False (parens are surely optional)
800                        false_Expr
801                     else -- parens depend on precedence...
802                        HsPar (genOpApp a_Expr gt_RDR (HsLit (HsInt 9)))
803             in
804             HsApp (
805               readParen_Expr read_paren_arg $ HsPar $
806                  HsLam (mk_easy_Match tycon_loc [c_Pat] [] $
807                         HsDo ListComp stmts tycon_loc)
808               ) (HsVar b_RDR)
809
810 \end{code}
811
812 %************************************************************************
813 %*                                                                      *
814 \subsubsection{Generating @Show@ instance declarations}
815 %*                                                                      *
816 %************************************************************************
817
818 Ignoring all the infix-ery mumbo jumbo (ToDo)
819
820 \begin{code}
821 gen_Show_binds :: TyCon -> RdrNameMonoBinds
822
823 gen_Show_binds tycon
824   = shows_prec `AndMonoBinds` show_list
825   where
826     tycon_loc = getSrcLoc tycon
827     -----------------------------------------------------------------------
828     show_list = mk_easy_FunMonoBind tycon_loc showList_RDR [] []
829                   (HsApp (HsVar showList___RDR) (HsPar (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 0)))))
830     -----------------------------------------------------------------------
831     shows_prec
832       = mk_FunMonoBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
833       where
834         pats_etc data_con
835           = let
836                 data_con_RDR = qual_orig_name data_con
837                 con_arity    = argFieldCount data_con
838                 bs_needed    = take con_arity bs_RDRs
839                 con_pat      = ConPatIn data_con_RDR (map VarPatIn bs_needed)
840                 nullary_con  = con_arity == 0
841                 labels       = dataConFieldLabels data_con
842                 lab_fields   = length labels
843
844                 show_con
845                   = let nm = occNameString (getOccName data_con)
846                         space_ocurly_maybe
847                           | nullary_con     = _NIL_
848                           | lab_fields == 0 = SLIT(" ")
849                           | otherwise       = SLIT("{")
850
851                     in
852                         mk_showString_app (nm _APPEND_ space_ocurly_maybe)
853
854                 show_all con fs
855                   = let
856                         ccurly_maybe 
857                           | lab_fields > 0  = [mk_showString_app (SLIT("}"))]
858                           | otherwise       = []
859                     in
860                         con:fs ++ ccurly_maybe
861
862                 show_thingies = show_all show_con real_show_thingies_with_labs
863                 
864                 show_label l 
865                   = let nm = occNameString (getOccName (fieldLabelName l)) 
866                     in
867                         mk_showString_app (nm _APPEND_ SLIT("="))
868
869                 mk_showString_app str = HsApp (HsVar showString_RDR)
870                                               (HsLit (HsString str))
871
872                 real_show_thingies =
873                      [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
874                      | b <- bs_needed ]
875
876                 real_show_thingies_with_labs
877                  | lab_fields == 0 = intersperse (HsVar showSpace_RDR) real_show_thingies
878                  | otherwise       = --Assumption: no of fields == no of labelled fields 
879                                      --            (and in same order)
880                     concat $
881                     intersperse ([mk_showString_app (_CONS_ ',' _NIL_)]) $ -- Using SLIT()s containing ,s spells trouble.
882                     zipWithEqual "gen_Show_binds"
883                                  (\ a b -> [a,b])
884                                  (map show_label labels) 
885                                  real_show_thingies
886                                
887
888             in
889             if nullary_con then  -- skip the showParen junk...
890                 ASSERT(null bs_needed)
891                 ([a_Pat, con_pat], show_con)
892             else
893                 ([a_Pat, con_pat],
894                     showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt 10))))
895                                    (HsPar (nested_compose_Expr show_thingies)))
896 \end{code}
897
898 %************************************************************************
899 %*                                                                      *
900 \subsection{Generating extra binds (@con2tag@ and @tag2con@)}
901 %*                                                                      *
902 %************************************************************************
903
904 \begin{verbatim}
905 data Foo ... = ...
906
907 con2tag_Foo :: Foo ... -> Int#
908 tag2con_Foo :: Int -> Foo ...   -- easier if Int, not Int#
909 maxtag_Foo  :: Int              -- ditto (NB: not unboxed)
910 \end{verbatim}
911
912 The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
913 fiddling around.
914
915 \begin{code}
916 data TagThingWanted
917   = GenCon2Tag | GenTag2Con | GenMaxTag
918
919 gen_tag_n_con_monobind
920     :: (RdrName,            -- (proto)Name for the thing in question
921         TyCon,              -- tycon in question
922         TagThingWanted)
923     -> RdrNameMonoBinds
924
925 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
926   = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon))
927   where
928     mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
929
930     mk_stuff var
931       = ASSERT(isDataCon var)
932         ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
933       where
934         pat    = ConPatIn var_RDR (nOfThem (argFieldCount var) WildPatIn)
935         var_RDR = qual_orig_name var
936
937 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
938   = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon) ++ 
939                                                              [([WildPatIn], impossible_Expr)])
940   where
941     mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
942
943     mk_stuff var
944       = ASSERT(isDataCon var)
945         ([lit_pat], HsVar var_RDR)
946       where
947         lit_pat = ConPatIn mkInt_RDR [LitPatIn (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG)))]
948         var_RDR  = qual_orig_name var
949
950 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
951   = mk_easy_FunMonoBind (getSrcLoc tycon) 
952                 rdr_name [] [] (HsApp (HsVar mkInt_RDR) (HsLit (HsIntPrim max_tag)))
953   where
954     max_tag =  case (tyConDataCons tycon) of
955                  data_cons -> toInteger ((length data_cons) - fIRST_TAG)
956
957 \end{code}
958
959 %************************************************************************
960 %*                                                                      *
961 \subsection{Utility bits for generating bindings}
962 %*                                                                      *
963 %************************************************************************
964
965 @mk_easy_FunMonoBind fun pats binds expr@ generates:
966 \begin{verbatim}
967     fun pat1 pat2 ... patN = expr where binds
968 \end{verbatim}
969
970 @mk_FunMonoBind fun [([p1a, p1b, ...], e1), ...]@ is for
971 multi-clause definitions; it generates:
972 \begin{verbatim}
973     fun p1a p1b ... p1N = e1
974     fun p2a p2b ... p2N = e2
975     ...
976     fun pMa pMb ... pMN = eM
977 \end{verbatim}
978
979 \begin{code}
980 mk_easy_FunMonoBind :: SrcLoc -> RdrName -> [RdrNamePat]
981                     -> [RdrNameMonoBinds] -> RdrNameHsExpr
982                     -> RdrNameMonoBinds
983
984 mk_easy_FunMonoBind loc fun pats binds expr
985   = FunMonoBind fun False{-not infix-} [mk_easy_Match loc pats binds expr] loc
986
987 mk_easy_Match loc pats binds expr
988   = mk_match loc pats expr (mkbind binds)
989   where
990     mkbind [] = EmptyBinds
991     mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] Recursive
992         -- The renamer expects everything in its input to be a
993         -- "recursive" MonoBinds, and it is its job to sort things out
994         -- from there.
995
996 mk_FunMonoBind  :: SrcLoc -> RdrName
997                 -> [([RdrNamePat], RdrNameHsExpr)]
998                 -> RdrNameMonoBinds
999
1000 mk_FunMonoBind loc fun [] = panic "TcGenDeriv:mk_FunMonoBind"
1001 mk_FunMonoBind loc fun pats_and_exprs
1002   = FunMonoBind fun False{-not infix-}
1003                 [ mk_match loc p e EmptyBinds | (p,e) <-pats_and_exprs ]
1004                 loc
1005
1006 mk_match loc pats expr binds
1007   = foldr PatMatch
1008           (GRHSMatch (GRHSsAndBindsIn (unguardedRHS expr loc) binds))
1009           (map paren pats)
1010   where
1011     paren p@(VarPatIn _) = p
1012     paren other_p        = ParPatIn other_p
1013 \end{code}
1014
1015 \begin{code}
1016 mk_easy_App f xs = foldl HsApp (HsVar f) (map HsVar xs)
1017 \end{code}
1018
1019 ToDo: Better SrcLocs.
1020
1021 \begin{code}
1022 compare_Case, cmp_eq_Expr ::
1023           RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1024           -> RdrNameHsExpr -> RdrNameHsExpr
1025           -> RdrNameHsExpr
1026 compare_gen_Case ::
1027           RdrName
1028           -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1029           -> RdrNameHsExpr -> RdrNameHsExpr
1030           -> RdrNameHsExpr
1031 careful_compare_Case :: -- checks for primitive types...
1032           Type
1033           -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1034           -> RdrNameHsExpr -> RdrNameHsExpr
1035           -> RdrNameHsExpr
1036
1037 compare_Case = compare_gen_Case compare_RDR
1038 cmp_eq_Expr = compare_gen_Case cmp_eq_RDR
1039
1040 compare_gen_Case fun lt eq gt a b
1041   = HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
1042       [PatMatch (ConPatIn ltTag_RDR [])
1043           (GRHSMatch (GRHSsAndBindsIn (unguardedRHS lt mkGeneratedSrcLoc) EmptyBinds)),
1044
1045        PatMatch (ConPatIn eqTag_RDR [])
1046           (GRHSMatch (GRHSsAndBindsIn (unguardedRHS eq mkGeneratedSrcLoc) EmptyBinds)),
1047
1048        PatMatch (ConPatIn gtTag_RDR [])
1049           (GRHSMatch (GRHSsAndBindsIn (unguardedRHS gt mkGeneratedSrcLoc) EmptyBinds))]
1050        mkGeneratedSrcLoc
1051
1052 careful_compare_Case ty lt eq gt a b
1053   = if not (isUnboxedType ty) then
1054        compare_gen_Case compare_RDR lt eq gt a b
1055
1056     else -- we have to do something special for primitive things...
1057        HsIf (genOpApp a relevant_eq_op b)
1058             eq
1059             (HsIf (genOpApp a relevant_lt_op b) lt gt mkGeneratedSrcLoc)
1060             mkGeneratedSrcLoc
1061   where
1062     relevant_eq_op = assoc_ty_id eq_op_tbl ty
1063     relevant_lt_op = assoc_ty_id lt_op_tbl ty
1064
1065 assoc_ty_id tyids ty 
1066   = if null res then panic "assoc_ty"
1067     else head res
1068   where
1069     res = [id | (ty',id) <- tyids, ty == ty']
1070
1071 eq_op_tbl =
1072     [(charPrimTy,       eqH_Char_RDR)
1073     ,(intPrimTy,        eqH_Int_RDR)
1074     ,(wordPrimTy,       eqH_Word_RDR)
1075     ,(addrPrimTy,       eqH_Addr_RDR)
1076     ,(floatPrimTy,      eqH_Float_RDR)
1077     ,(doublePrimTy,     eqH_Double_RDR)
1078     ]
1079
1080 lt_op_tbl =
1081     [(charPrimTy,       ltH_Char_RDR)
1082     ,(intPrimTy,        ltH_Int_RDR)
1083     ,(wordPrimTy,       ltH_Word_RDR)
1084     ,(addrPrimTy,       ltH_Addr_RDR)
1085     ,(floatPrimTy,      ltH_Float_RDR)
1086     ,(doublePrimTy,     ltH_Double_RDR)
1087     ]
1088
1089 -----------------------------------------------------------------------
1090
1091 and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1092
1093 and_Expr    a b = genOpApp a and_RDR    b
1094 append_Expr a b = genOpApp a append_RDR b
1095
1096 -----------------------------------------------------------------------
1097
1098 eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1099 eq_Expr ty a b
1100   = if not (isUnboxedType ty) then
1101        genOpApp a eq_RDR  b
1102     else -- we have to do something special for primitive things...
1103        genOpApp a relevant_eq_op b
1104   where
1105     relevant_eq_op = assoc_ty_id eq_op_tbl ty
1106 \end{code}
1107
1108 \begin{code}
1109 argFieldCount :: Id -> Int      -- Works on data and newtype constructors
1110 argFieldCount con = length (dataConRawArgTys con)
1111 \end{code}
1112
1113 \begin{code}
1114 untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
1115 untag_Expr tycon [] expr = expr
1116 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
1117   = HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
1118       [PatMatch (VarPatIn put_tag_here)
1119                         (GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
1120       mkGeneratedSrcLoc
1121   where
1122     grhs = unguardedRHS (untag_Expr tycon more expr) mkGeneratedSrcLoc
1123
1124 cmp_tags_Expr :: RdrName                -- Comparison op
1125              -> RdrName -> RdrName      -- Things to compare
1126              -> RdrNameHsExpr           -- What to return if true
1127              -> RdrNameHsExpr           -- What to return if false
1128              -> RdrNameHsExpr
1129
1130 cmp_tags_Expr op a b true_case false_case
1131   = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case mkGeneratedSrcLoc
1132
1133 enum_from_to_Expr
1134         :: RdrNameHsExpr -> RdrNameHsExpr
1135         -> RdrNameHsExpr
1136 enum_from_then_to_Expr
1137         :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1138         -> RdrNameHsExpr
1139
1140 enum_from_to_Expr      f   t2 = HsApp (HsApp (HsVar enumFromTo_RDR) f) t2
1141 enum_from_then_to_Expr f t t2 = HsApp (HsApp (HsApp (HsVar enumFromThenTo_RDR) f) t) t2
1142
1143 showParen_Expr, readParen_Expr
1144         :: RdrNameHsExpr -> RdrNameHsExpr
1145         -> RdrNameHsExpr
1146
1147 showParen_Expr e1 e2 = HsApp (HsApp (HsVar showParen_RDR) e1) e2
1148 readParen_Expr e1 e2 = HsApp (HsApp (HsVar readParen_RDR) e1) e2
1149
1150 nested_compose_Expr :: [RdrNameHsExpr] -> RdrNameHsExpr
1151
1152 nested_compose_Expr [e] = parenify e
1153 nested_compose_Expr (e:es)
1154   = HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
1155
1156 -- impossible_Expr is used in case RHSs that should never happen.
1157 -- We generate these to keep the desugarer from complaining that they *might* happen!
1158 impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ "Urk! in TcGenDeriv")))
1159
1160 parenify e@(HsVar _) = e
1161 parenify e           = HsPar e
1162
1163 -- genOpApp wraps brackets round the operator application, so that the
1164 -- renamer won't subsequently try to re-associate it. 
1165 -- For some reason the renamer doesn't reassociate it right, and I can't
1166 -- be bothered to find out why just now.
1167
1168 genOpApp e1 op e2 = mkOpApp e1 op e2
1169 \end{code}
1170
1171 \begin{code}
1172 qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n HiFile }
1173
1174 a_RDR           = varUnqual SLIT("a")
1175 b_RDR           = varUnqual SLIT("b")
1176 c_RDR           = varUnqual SLIT("c")
1177 d_RDR           = varUnqual SLIT("d")
1178 ah_RDR          = varUnqual SLIT("a#")
1179 bh_RDR          = varUnqual SLIT("b#")
1180 ch_RDR          = varUnqual SLIT("c#")
1181 dh_RDR          = varUnqual SLIT("d#")
1182 cmp_eq_RDR      = varUnqual SLIT("cmp_eq")
1183 rangeSize_RDR   = varUnqual SLIT("rangeSize")
1184
1185 as_RDRs         = [ varUnqual (_PK_ ("a"++show i)) | i <- [(1::Int) .. ] ]
1186 bs_RDRs         = [ varUnqual (_PK_ ("b"++show i)) | i <- [(1::Int) .. ] ]
1187 cs_RDRs         = [ varUnqual (_PK_ ("c"++show i)) | i <- [(1::Int) .. ] ]
1188
1189 a_Expr          = HsVar a_RDR
1190 b_Expr          = HsVar b_RDR
1191 c_Expr          = HsVar c_RDR
1192 d_Expr          = HsVar d_RDR
1193 ltTag_Expr      = HsVar ltTag_RDR
1194 eqTag_Expr      = HsVar eqTag_RDR
1195 gtTag_Expr      = HsVar gtTag_RDR
1196 false_Expr      = HsVar false_RDR
1197 true_Expr       = HsVar true_RDR
1198
1199 con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
1200
1201 a_Pat           = VarPatIn a_RDR
1202 b_Pat           = VarPatIn b_RDR
1203 c_Pat           = VarPatIn c_RDR
1204 d_Pat           = VarPatIn d_RDR
1205
1206 con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
1207
1208 con2tag_RDR tycon = varUnqual (SLIT("con2tag_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
1209 tag2con_RDR tycon = varUnqual (SLIT("tag2con_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
1210 maxtag_RDR tycon  = varUnqual (SLIT("maxtag_")  _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
1211 \end{code}