2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[TcGenDeriv]{Generating derived instance declarations}
6 This module is nominally ``subordinate'' to @TcDeriv@, which is the
7 ``official'' interface to deriving-related things.
9 This is where we do all the grimy bindings' generation.
20 gen_tag_n_con_monobind,
22 con2tag_RDR, tag2con_RDR, maxtag_RDR,
27 #include "HsVersions.h"
29 import HsSyn ( InPat(..), HsExpr(..), MonoBinds(..),
30 Match(..), GRHSs(..), Stmt(..), HsLit(..),
31 HsBinds(..), StmtCtxt(..), HsType(..),
32 unguardedRHS, mkSimpleMatch
34 import RdrHsSyn ( mkOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat )
35 import RdrName ( RdrName, mkSrcUnqual )
36 import RnMonad ( Fixities )
37 import BasicTypes ( RecFlag(..), Fixity(..), FixityDirection(..)
38 , maxPrecedence, defaultFixity
40 import FieldLabel ( fieldLabelName )
41 import DataCon ( isNullaryDataCon, dataConTag,
42 dataConRawArgTys, fIRST_TAG,
45 import Name ( getOccString, getOccName, getSrcLoc, occNameString,
46 occNameUserString, nameRdrName, varName,
47 OccName, Name, NamedThing(..), NameSpace,
48 isDataSymOcc, isSymOcc
51 import PrimOp ( PrimOp(..) )
52 import PrelInfo -- Lots of RdrNames
53 import SrcLoc ( mkGeneratedSrcLoc, SrcLoc )
54 import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
55 maybeTyConSingleCon, tyConFamilySize
57 import Type ( isUnLiftedType, isUnboxedType, Type )
58 import TysPrim ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
59 floatPrimTy, doublePrimTy
61 import Util ( mapAccumL, zipEqual, zipWithEqual,
62 zipWith3Equal, nOfThem, assocDefault )
63 import Panic ( panic, assertPanic )
64 import Maybes ( maybeToBool )
66 import List ( partition, intersperse )
67 import Char ( isAlpha )
70 %************************************************************************
72 \subsection{Generating code, by derivable class}
74 %************************************************************************
76 %************************************************************************
78 \subsubsection{Generating @Eq@ instance declarations}
80 %************************************************************************
82 Here are the heuristics for the code we generate for @Eq@:
85 Let's assume we have a data type with some (possibly zero) nullary
86 data constructors and some ordinary, non-nullary ones (the rest,
87 also possibly zero of them). Here's an example, with both \tr{N}ullary
88 and \tr{O}rdinary data cons.
90 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
94 For the ordinary constructors (if any), we emit clauses to do The
98 (==) (O1 a1 b1) (O1 a2 b2) = a1 == a2 && b1 == b2
99 (==) (O2 a1) (O2 a2) = a1 == a2
100 (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2
103 Note: if we're comparing unboxed things, e.g., if \tr{a1} and
104 \tr{a2} are \tr{Float#}s, then we have to generate
106 case (a1 `eqFloat#` a2) of
109 for that particular test.
112 If there are any nullary constructors, we emit a catch-all clause of
116 (==) a b = case (con2tag_Foo a) of { a# ->
117 case (con2tag_Foo b) of { b# ->
118 case (a# ==# b#) of {
123 If there aren't any nullary constructors, we emit a simpler
130 For the @(/=)@ method, we normally just use the default method.
132 If the type is an enumeration type, we could/may/should? generate
133 special code that calls @con2tag_Foo@, much like for @(==)@ shown
137 We thought about doing this: If we're also deriving @Ord@ for this
140 instance ... Eq (Foo ...) where
141 (==) a b = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
142 (/=) a b = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
144 However, that requires that \tr{Ord <whatever>} was put in the context
145 for the instance decl, which it probably wasn't, so the decls
146 produced don't get through the typechecker.
150 deriveEq :: RdrName -- Class
151 -> RdrName -- Type constructor
152 -> [ (RdrName, [RdrType]) ] -- Constructors
153 -> (RdrContext, -- Context for the inst decl
154 [RdrBind], -- Binds in the inst decl
155 [RdrBind]) -- Extra value bindings outside
157 deriveEq clas tycon constrs
158 = (context, [eq_bind, ne_bind], [])
160 context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
163 (nullary_cons, non_nullary_cons) = partition is_nullary constrs
164 is_nullary (_, args) = null args
167 gen_Eq_binds :: TyCon -> RdrNameMonoBinds
171 tycon_loc = getSrcLoc tycon
172 (nullary_cons, nonnullary_cons)
173 | isNewTyCon tycon = ([], tyConDataCons tycon)
174 | otherwise = partition isNullaryDataCon (tyConDataCons tycon)
177 = if (null nullary_cons) then
178 case maybeTyConSingleCon tycon of
180 Nothing -> -- if cons don't match, then False
181 [([wildPat, wildPat], false_Expr)]
182 else -- calc. and compare the tags
184 untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
185 (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR true_Expr false_Expr))]
187 mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
189 mk_easy_FunMonoBind tycon_loc ne_RDR [a_Pat, b_Pat] [] (
190 HsApp (HsVar not_RDR) (HsPar (mk_easy_App eq_RDR [a_RDR, b_RDR])))
192 ------------------------------------------------------------------
195 con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
196 con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
198 data_con_RDR = qual_orig_name data_con
199 con_arity = length tys_needed
200 as_needed = take con_arity as_RDRs
201 bs_needed = take con_arity bs_RDRs
202 tys_needed = dataConRawArgTys data_con
204 ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
206 nested_eq_expr [] [] [] = true_Expr
207 nested_eq_expr tys as bs
208 = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
210 nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
213 %************************************************************************
215 \subsubsection{Generating @Ord@ instance declarations}
217 %************************************************************************
219 For a derived @Ord@, we concentrate our attentions on @compare@
221 compare :: a -> a -> Ordering
222 data Ordering = LT | EQ | GT deriving ()
225 We will use the same example data type as above:
227 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
232 We do all the other @Ord@ methods with calls to @compare@:
234 instance ... (Ord <wurble> <wurble>) where
235 a < b = case (compare a b) of { LT -> True; EQ -> False; GT -> False }
236 a <= b = case (compare a b) of { LT -> True; EQ -> True; GT -> False }
237 a >= b = case (compare a b) of { LT -> False; EQ -> True; GT -> True }
238 a > b = case (compare a b) of { LT -> False; EQ -> False; GT -> True }
240 max a b = case (compare a b) of { LT -> b; EQ -> a; GT -> a }
241 min a b = case (compare a b) of { LT -> a; EQ -> b; GT -> b }
243 -- compare to come...
247 @compare@ always has two parts. First, we use the compared
248 data-constructors' tags to deal with the case of different
251 compare a b = case (con2tag_Foo a) of { a# ->
252 case (con2tag_Foo b) of { b# ->
253 case (a# ==# b#) of {
255 False -> case (a# <# b#) of
260 cmp_eq = ... to come ...
264 We are only left with the ``help'' function @cmp_eq@, to deal with
265 comparing data constructors with the same tag.
267 For the ordinary constructors (if any), we emit the sorta-obvious
268 compare-style stuff; for our example:
270 cmp_eq (O1 a1 b1) (O1 a2 b2)
271 = case (compare a1 a2) of { LT -> LT; EQ -> compare b1 b2; GT -> GT }
273 cmp_eq (O2 a1) (O2 a2)
276 cmp_eq (O3 a1 b1 c1) (O3 a2 b2 c2)
277 = case (compare a1 a2) of {
280 EQ -> case compare b1 b2 of {
288 Again, we must be careful about unboxed comparisons. For example,
289 if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
293 cmp_eq lt eq gt (O2 a1) (O2 a2)
295 -- or maybe the unfolded equivalent
299 For the remaining nullary constructors, we already know that the
306 If there is only one constructor in the Data Type we don't need the WildCard Pattern.
310 gen_Ord_binds :: TyCon -> RdrNameMonoBinds
313 = compare -- `AndMonoBinds` compare
314 -- The default declaration in PrelBase handles this
316 tycon_loc = getSrcLoc tycon
317 --------------------------------------------------------------------
318 compare = mk_easy_FunMonoBind tycon_loc compare_RDR
321 (if maybeToBool (maybeTyConSingleCon tycon) then
323 -- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
324 -- Wierd. Was: case (cmp a b) of { LT -> LT; EQ -> EQ; GT -> GT }
326 cmp_eq_Expr a_Expr b_Expr
328 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
329 (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR
330 -- True case; they are equal
331 -- If an enumeration type we are done; else
332 -- recursively compare their components
333 (if isEnumerationTyCon tycon then
336 -- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
338 cmp_eq_Expr a_Expr b_Expr
340 -- False case; they aren't equal
341 -- So we need to do a less-than comparison on the tags
342 (cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
344 tycon_data_cons = tyConDataCons tycon
345 (nullary_cons, nonnullary_cons)
346 | isNewTyCon tycon = ([], tyConDataCons tycon)
347 | otherwise = partition isNullaryDataCon tycon_data_cons
350 mk_FunMonoBind tycon_loc
352 (if null nonnullary_cons && (length nullary_cons == 1) then
353 -- catch this specially to avoid warnings
354 -- about overlapping patterns from the desugarer.
356 data_con = head nullary_cons
357 data_con_RDR = qual_orig_name data_con
358 pat = ConPatIn data_con_RDR []
360 [([pat,pat], eqTag_Expr)]
362 map pats_etc nonnullary_cons ++
363 -- leave out wildcards to silence desugarer.
364 (if length tycon_data_cons == 1 then
367 [([WildPatIn, WildPatIn], default_rhs)]))
370 = ([con1_pat, con2_pat],
371 nested_compare_expr tys_needed as_needed bs_needed)
373 con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
374 con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
376 data_con_RDR = qual_orig_name data_con
377 con_arity = length tys_needed
378 as_needed = take con_arity as_RDRs
379 bs_needed = take con_arity bs_RDRs
380 tys_needed = dataConRawArgTys data_con
382 nested_compare_expr [ty] [a] [b]
383 = careful_compare_Case ty ltTag_Expr eqTag_Expr gtTag_Expr (HsVar a) (HsVar b)
385 nested_compare_expr (ty:tys) (a:as) (b:bs)
386 = let eq_expr = nested_compare_expr tys as bs
387 in careful_compare_Case ty ltTag_Expr eq_expr gtTag_Expr (HsVar a) (HsVar b)
389 default_rhs | null nullary_cons = impossible_Expr -- Keep desugarer from complaining about
390 -- inexhaustive patterns
391 | otherwise = eqTag_Expr -- Some nullary constructors;
392 -- Tags are equal, no args => return EQ
393 --------------------------------------------------------------------
395 {- Not necessary: the default decls in PrelBase handle these
397 defaulted = foldr1 AndMonoBinds [lt, le, ge, gt, max_, min_]
399 lt = mk_easy_FunMonoBind mkGeneratedSrcLoc lt_RDR [a_Pat, b_Pat] [] (
400 compare_Case true_Expr false_Expr false_Expr a_Expr b_Expr)
401 le = mk_easy_FunMonoBind mkGeneratedSrcLoc le_RDR [a_Pat, b_Pat] [] (
402 compare_Case true_Expr true_Expr false_Expr a_Expr b_Expr)
403 ge = mk_easy_FunMonoBind mkGeneratedSrcLoc ge_RDR [a_Pat, b_Pat] [] (
404 compare_Case false_Expr true_Expr true_Expr a_Expr b_Expr)
405 gt = mk_easy_FunMonoBind mkGeneratedSrcLoc gt_RDR [a_Pat, b_Pat] [] (
406 compare_Case false_Expr false_Expr true_Expr a_Expr b_Expr)
408 max_ = mk_easy_FunMonoBind mkGeneratedSrcLoc max_RDR [a_Pat, b_Pat] [] (
409 compare_Case b_Expr a_Expr a_Expr a_Expr b_Expr)
410 min_ = mk_easy_FunMonoBind mkGeneratedSrcLoc min_RDR [a_Pat, b_Pat] [] (
411 compare_Case a_Expr b_Expr b_Expr a_Expr b_Expr)
415 %************************************************************************
417 \subsubsection{Generating @Enum@ instance declarations}
419 %************************************************************************
421 @Enum@ can only be derived for enumeration types. For a type
423 data Foo ... = N1 | N2 | ... | Nn
426 we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
427 @maxtag_Foo@ variable (all generated by @gen_tag_n_con_binds@).
430 instance ... Enum (Foo ...) where
431 succ x = toEnum (1 + fromEnum x)
432 pred x = toEnum (fromEnum x - 1)
434 toEnum i = tag2con_Foo i
436 enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
440 = case con2tag_Foo a of
441 a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)
444 = map tag2con_Foo [con2tag_Foo a, con2tag_Foo b .. maxtag_Foo]
448 = case con2tag_Foo a of { a# ->
449 case con2tag_Foo b of { b# ->
450 map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
454 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
457 gen_Enum_binds :: TyCon -> RdrNameMonoBinds
460 = succ_enum `AndMonoBinds`
461 pred_enum `AndMonoBinds`
462 to_enum `AndMonoBinds`
463 enum_from `AndMonoBinds`
464 enum_from_then `AndMonoBinds`
467 tycon_loc = getSrcLoc tycon
468 occ_nm = getOccString tycon
471 = mk_easy_FunMonoBind tycon_loc succ_RDR [a_Pat] [] $
472 untag_Expr tycon [(a_RDR, ah_RDR)] $
473 HsIf (HsApp (HsApp (HsVar eq_RDR)
474 (HsVar (maxtag_RDR tycon)))
475 (mk_easy_App mkInt_RDR [ah_RDR]))
476 (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
477 (HsApp (HsVar (tag2con_RDR tycon))
478 (HsApp (HsApp (HsVar plus_RDR)
479 (mk_easy_App mkInt_RDR [ah_RDR]))
484 = mk_easy_FunMonoBind tycon_loc pred_RDR [a_Pat] [] $
485 untag_Expr tycon [(a_RDR, ah_RDR)] $
486 HsIf (HsApp (HsApp (HsVar eq_RDR) (HsLit (HsInt 0)))
487 (mk_easy_App mkInt_RDR [ah_RDR]))
488 (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
489 (HsApp (HsVar (tag2con_RDR tycon))
490 (HsApp (HsApp (HsVar plus_RDR)
491 (mk_easy_App mkInt_RDR [ah_RDR]))
492 (HsLit (HsInt (-1)))))
496 = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
499 (HsApp (HsApp (HsVar ge_RDR)
502 (HsApp (HsApp (HsVar le_RDR)
504 (HsVar (maxtag_RDR tycon))))
505 (mk_easy_App (tag2con_RDR tycon) [a_RDR])
506 (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
510 = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
511 untag_Expr tycon [(a_RDR, ah_RDR)] $
512 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
513 HsPar (enum_from_to_Expr
514 (mk_easy_App mkInt_RDR [ah_RDR])
515 (HsVar (maxtag_RDR tycon)))
518 = mk_easy_FunMonoBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] [] $
519 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
520 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
521 HsPar (enum_from_then_to_Expr
522 (mk_easy_App mkInt_RDR [ah_RDR])
523 (mk_easy_App mkInt_RDR [bh_RDR])
524 (HsIf (HsApp (HsApp (HsVar gt_RDR)
525 (mk_easy_App mkInt_RDR [ah_RDR]))
526 (mk_easy_App mkInt_RDR [bh_RDR]))
528 (HsVar (maxtag_RDR tycon))
532 = mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
533 untag_Expr tycon [(a_RDR, ah_RDR)] $
534 (mk_easy_App mkInt_RDR [ah_RDR])
537 %************************************************************************
539 \subsubsection{Generating @Bounded@ instance declarations}
541 %************************************************************************
544 gen_Bounded_binds tycon
545 = if isEnumerationTyCon tycon then
546 min_bound_enum `AndMonoBinds` max_bound_enum
548 ASSERT(length data_cons == 1)
549 min_bound_1con `AndMonoBinds` max_bound_1con
551 data_cons = tyConDataCons tycon
552 tycon_loc = getSrcLoc tycon
554 ----- enum-flavored: ---------------------------
555 min_bound_enum = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] (HsVar data_con_1_RDR)
556 max_bound_enum = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] (HsVar data_con_N_RDR)
558 data_con_1 = head data_cons
559 data_con_N = last data_cons
560 data_con_1_RDR = qual_orig_name data_con_1
561 data_con_N_RDR = qual_orig_name data_con_N
563 ----- single-constructor-flavored: -------------
564 arity = argFieldCount data_con_1
566 min_bound_1con = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] $
567 mk_easy_App data_con_1_RDR (nOfThem arity minBound_RDR)
568 max_bound_1con = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] $
569 mk_easy_App data_con_1_RDR (nOfThem arity maxBound_RDR)
572 %************************************************************************
574 \subsubsection{Generating @Ix@ instance declarations}
576 %************************************************************************
578 Deriving @Ix@ is only possible for enumeration types and
579 single-constructor types. We deal with them in turn.
581 For an enumeration type, e.g.,
583 data Foo ... = N1 | N2 | ... | Nn
585 things go not too differently from @Enum@:
587 instance ... Ix (Foo ...) where
589 = map tag2con_Foo [con2tag_Foo a .. con2tag_Foo b]
593 = case (con2tag_Foo a) of { a# ->
594 case (con2tag_Foo b) of { b# ->
595 map tag2con_Foo (enumFromTo (I# a#) (I# b#))
600 then case (con2tag_Foo d -# con2tag_Foo a) of
602 else error "Ix.Foo.index: out of range"
606 p_tag = con2tag_Foo c
608 p_tag >= con2tag_Foo a && p_tag <= con2tag_Foo b
612 = case (con2tag_Foo a) of { a_tag ->
613 case (con2tag_Foo b) of { b_tag ->
614 case (con2tag_Foo c) of { c_tag ->
615 if (c_tag >=# a_tag) then
621 (modulo suitable case-ification to handle the unboxed tags)
623 For a single-constructor type (NB: this includes all tuples), e.g.,
625 data Foo ... = MkFoo a b Int Double c c
627 we follow the scheme given in Figure~19 of the Haskell~1.2 report
631 gen_Ix_binds :: TyCon -> RdrNameMonoBinds
634 = if isEnumerationTyCon tycon
638 tycon_str = getOccString tycon
639 tycon_loc = getSrcLoc tycon
641 --------------------------------------------------------------
642 enum_ixes = enum_range `AndMonoBinds`
643 enum_index `AndMonoBinds` enum_inRange
646 = mk_easy_FunMonoBind tycon_loc range_RDR
647 [TuplePatIn [a_Pat, b_Pat] True{-boxed-}] [] $
648 untag_Expr tycon [(a_RDR, ah_RDR)] $
649 untag_Expr tycon [(b_RDR, bh_RDR)] $
650 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
651 HsPar (enum_from_to_Expr
652 (mk_easy_App mkInt_RDR [ah_RDR])
653 (mk_easy_App mkInt_RDR [bh_RDR]))
656 = mk_easy_FunMonoBind tycon_loc index_RDR
657 [AsPatIn c_RDR (TuplePatIn [a_Pat, wildPat] True{-boxed-}),
659 HsIf (HsPar (mk_easy_App inRange_RDR [c_RDR, d_RDR])) (
660 untag_Expr tycon [(a_RDR, ah_RDR)] (
661 untag_Expr tycon [(d_RDR, dh_RDR)] (
663 rhs = mk_easy_App mkInt_RDR [c_RDR]
666 (genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
667 [mkSimpleMatch [VarPatIn c_RDR] rhs Nothing tycon_loc]
671 HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ ("Ix."++tycon_str++".index: out of range\n"))))
676 = mk_easy_FunMonoBind tycon_loc inRange_RDR
677 [TuplePatIn [a_Pat, b_Pat] True{-boxed-}, c_Pat] [] (
678 untag_Expr tycon [(a_RDR, ah_RDR)] (
679 untag_Expr tycon [(b_RDR, bh_RDR)] (
680 untag_Expr tycon [(c_RDR, ch_RDR)] (
681 HsIf (genOpApp (HsVar ch_RDR) geH_RDR (HsVar ah_RDR)) (
682 (genOpApp (HsVar ch_RDR) leH_RDR (HsVar bh_RDR))
687 --------------------------------------------------------------
689 = single_con_range `AndMonoBinds`
690 single_con_index `AndMonoBinds`
694 = case maybeTyConSingleCon tycon of -- just checking...
695 Nothing -> panic "get_Ix_binds"
696 Just dc -> if (any isUnLiftedType (dataConRawArgTys dc)) then
697 error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
701 con_arity = argFieldCount data_con
702 data_con_RDR = qual_orig_name data_con
704 as_needed = take con_arity as_RDRs
705 bs_needed = take con_arity bs_RDRs
706 cs_needed = take con_arity cs_RDRs
708 con_pat xs = ConPatIn data_con_RDR (map VarPatIn xs)
709 con_expr = mk_easy_App data_con_RDR cs_needed
711 --------------------------------------------------------------
713 = mk_easy_FunMonoBind tycon_loc range_RDR
714 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True{-boxed-}] [] $
715 HsDo ListComp stmts tycon_loc
717 stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
719 [ReturnStmt con_expr]
721 mk_qual a b c = BindStmt (VarPatIn c)
722 (HsApp (HsVar range_RDR)
723 (ExplicitTuple [HsVar a, HsVar b] True))
728 = mk_easy_FunMonoBind tycon_loc index_RDR
729 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
730 con_pat cs_needed] [range_size] (
731 foldl mk_index (HsLit (HsInt 0)) (zip3 as_needed bs_needed cs_needed))
733 mk_index multiply_by (l, u, i)
735 (HsApp (HsApp (HsVar index_RDR)
736 (ExplicitTuple [HsVar l, HsVar u] True)) (HsVar i))
739 (HsApp (HsVar rangeSize_RDR)
740 (ExplicitTuple [HsVar l, HsVar u] True))
741 ) times_RDR multiply_by
745 = mk_easy_FunMonoBind tycon_loc rangeSize_RDR
746 [TuplePatIn [a_Pat, b_Pat] True] [] (
748 (HsApp (HsApp (HsVar index_RDR)
749 (ExplicitTuple [a_Expr, b_Expr] True)) b_Expr)
750 ) plus_RDR (HsLit (HsInt 1)))
754 = mk_easy_FunMonoBind tycon_loc inRange_RDR
755 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
758 foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
760 in_range a b c = HsApp (HsApp (HsVar inRange_RDR)
761 (ExplicitTuple [HsVar a, HsVar b] True))
765 %************************************************************************
767 \subsubsection{Generating @Read@ instance declarations}
769 %************************************************************************
772 gen_Read_binds :: Fixities -> TyCon -> RdrNameMonoBinds
774 gen_Read_binds fixities tycon
775 = reads_prec `AndMonoBinds` read_list
777 tycon_loc = getSrcLoc tycon
778 -----------------------------------------------------------------------
779 read_list = mk_easy_FunMonoBind tycon_loc readList_RDR [] []
780 (HsApp (HsVar readList___RDR) (HsPar (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 0)))))
781 -----------------------------------------------------------------------
784 read_con_comprehensions
785 = map read_con (tyConDataCons tycon)
787 mk_easy_FunMonoBind tycon_loc readsPrec_RDR [zz_a_Pat, b_Pat] [] (
788 foldr1 append_Expr read_con_comprehensions
791 read_con data_con -- note: "b" is the string being "read"
793 readParen_Expr read_paren_arg $ HsPar $
794 HsLam (mk_easy_Match tycon_loc [c_Pat] [] $
795 HsDo ListComp stmts tycon_loc)
798 data_con_RDR = qual_orig_name data_con
799 data_con_str = occNameUserString (getOccName data_con)
800 con_arity = argFieldCount data_con
801 con_expr = mk_easy_App data_con_RDR as_needed
802 nullary_con = con_arity == 0
803 labels = dataConFieldLabels data_con
804 lab_fields = length labels
805 dc_nm = getName data_con
806 is_infix = isDataSymOcc (getOccName dc_nm)
808 as_needed = take con_arity as_RDRs
810 | is_infix = take (1 + con_arity) bs_RDRs
811 | lab_fields == 0 = take con_arity bs_RDRs
812 | otherwise = take (4*lab_fields + 1) bs_RDRs
813 -- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
815 (as1:as2:_) = as_needed
816 (bs1:bs2:bs3:_) = bs_needed
821 (TuplePatIn [LitPatIn (mkHsString data_con_str), d_Pat] True)
822 (HsApp (HsVar lex_RDR) c_Expr)
826 (TuplePatIn [LitPatIn (mkHsString data_con_str), VarPatIn bs2] True)
827 (HsApp (HsVar lex_RDR) (HsVar bs1))
831 str_qual str res draw_from =
833 (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] True)
834 (HsApp (HsVar lex_RDR) draw_from)
837 str_qual_paren str res draw_from =
839 (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] True)
840 (HsApp (readParen_Expr true_Expr (HsVar lex_RDR)) draw_from)
843 read_label f = [rd_lab, str_qual "="]
844 -- There might be spaces between the label and '='
847 | is_op = str_qual_paren nm
848 | otherwise = str_qual nm
850 occ_nm = getOccName (fieldLabelName f)
851 is_op = isSymOcc occ_nm
852 nm = occNameUserString occ_nm
856 snd (mapAccumL mk_qual_infix
858 [ (mk_read_qual lp as1, bs1, bs2)
859 , (mk_read_qual rp as2, bs3, bs3)
861 | lab_fields == 0 = -- common case.
862 snd (mapAccumL mk_qual
864 (zipWithEqual "as_needed"
865 (\ con_field draw_from -> (mk_read_qual 10 con_field,
867 as_needed bs_needed))
870 mapAccumL mk_qual d_Expr
871 (zipEqual "bs_needed"
874 intersperse [str_qual ","] $
877 (\ as b -> as ++ [b])
879 (map read_label labels)
881 (map (mk_read_qual 10) as_needed))) ++ [str_qual "}"])
884 mk_qual_infix draw_from (f, str_left, str_left2) =
885 (HsVar str_left2, -- what to draw from down the line...
886 f str_left draw_from)
888 mk_qual draw_from (f, str_left) =
889 (HsVar str_left, -- what to draw from down the line...
890 f str_left draw_from)
892 mk_read_qual p con_field res draw_from =
894 (TuplePatIn [VarPatIn con_field, VarPatIn res] True)
895 (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt p))) draw_from)
898 result_expr = ExplicitTuple [con_expr, if null bs_needed
900 else HsVar (last bs_needed)] True
902 [lp,rp] = getLRPrecs is_infix fixities dc_nm
905 | is_infix = let (h:t) = field_quals in (h:con_qual:t)
906 | otherwise = con_qual:field_quals
908 stmts = quals ++ [ReturnStmt result_expr]
911 c.f. Figure 18 in Haskell 1.1 report.
914 | not is_infix = fromInt maxPrecedence
915 | otherwise = getFixity fixities dc_nm
917 read_paren_arg -- parens depend on precedence...
918 | nullary_con = false_Expr -- it's optional.
919 | otherwise = HsPar (genOpApp zz_a_Expr gt_RDR (HsLit (HsInt paren_prec_limit)))
922 %************************************************************************
924 \subsubsection{Generating @Show@ instance declarations}
926 %************************************************************************
929 gen_Show_binds :: Fixities -> TyCon -> RdrNameMonoBinds
931 gen_Show_binds fixs_assoc tycon
932 = shows_prec `AndMonoBinds` show_list
934 tycon_loc = getSrcLoc tycon
935 -----------------------------------------------------------------------
936 show_list = mk_easy_FunMonoBind tycon_loc showList_RDR [] []
937 (HsApp (HsVar showList___RDR) (HsPar (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 0)))))
938 -----------------------------------------------------------------------
939 shows_prec = mk_FunMonoBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
942 | nullary_con = -- skip the showParen junk...
943 ASSERT(null bs_needed)
944 ([wildPat, con_pat], show_con)
947 showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt paren_prec_limit))))
948 (HsPar (nested_compose_Expr show_thingies)))
950 data_con_RDR = qual_orig_name data_con
951 con_arity = argFieldCount data_con
952 bs_needed = take con_arity bs_RDRs
953 con_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
954 nullary_con = con_arity == 0
955 labels = dataConFieldLabels data_con
956 lab_fields = length labels
958 dc_nm = getName data_con
959 dc_occ_nm = getOccName data_con
960 dc_occ_nm_str = occNameUserString dc_occ_nm
962 is_infix = isDataSymOcc dc_occ_nm
966 | is_infix = mk_showString_app (' ':dc_occ_nm_str)
967 | otherwise = mk_showString_app (dc_occ_nm_str ++ space_ocurly_maybe)
971 | lab_fields == 0 = " "
975 show_all con fs@(x:xs)
976 | is_infix = x:con:xs
980 | lab_fields > 0 = [mk_showString_app "}"]
983 con:fs ++ ccurly_maybe
985 show_thingies = show_all show_con real_show_thingies_with_labs
987 show_label l = mk_showString_app (the_name ++ "=")
989 occ_nm = getOccName (fieldLabelName l)
991 is_op = isSymOcc occ_nm
993 | is_op = '(':nm ++ ")"
996 nm = occNameUserString occ_nm
999 mk_showString_app str = HsApp (HsVar showString_RDR)
1000 (HsLit (mkHsString str))
1002 prec_cons = getLRPrecs is_infix fixs_assoc dc_nm
1006 [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt p))) (HsVar b)
1007 | (p,b) <- zip prec_cons bs_needed ]
1009 [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
1012 real_show_thingies_with_labs
1013 | lab_fields == 0 = intersperse (HsVar showSpace_RDR) real_show_thingies
1014 | otherwise = --Assumption: no of fields == no of labelled fields
1015 -- (and in same order)
1017 intersperse ([mk_showString_app ","]) $ -- Using SLIT()s containing ,s spells trouble.
1018 zipWithEqual "gen_Show_binds"
1020 (map show_label labels)
1023 (con_left_assoc, con_right_assoc) = isLRAssoc fixs_assoc dc_nm
1026 c.f. Figure 16 and 17 in Haskell 1.1 report
1029 | not is_infix = fromInt maxPrecedence + 1
1030 | otherwise = getFixity fixs_assoc dc_nm + 1
1035 getLRPrecs :: Bool -> Fixities -> Name -> [Integer]
1036 getLRPrecs is_infix fixs_assoc nm = [lp, rp]
1039 Figuring out the fixities of the arguments to a constructor,
1040 cf. Figures 16-18 in Haskell 1.1 report.
1042 (con_left_assoc, con_right_assoc) = isLRAssoc fixs_assoc nm
1043 paren_con_prec = getFixity fixs_assoc nm
1044 maxPrec = fromInt maxPrecedence
1047 | not is_infix = maxPrec + 1
1048 | con_left_assoc = paren_con_prec
1049 | otherwise = paren_con_prec + 1
1052 | not is_infix = maxPrec + 1
1053 | con_right_assoc = paren_con_prec
1054 | otherwise = paren_con_prec + 1
1056 getFixity :: Fixities -> Name -> Integer
1057 getFixity fixs_assoc nm =
1058 case lookupFixity fixs_assoc nm of
1059 Fixity x _ -> fromInt x
1061 isLRAssoc :: Fixities -> Name -> (Bool, Bool)
1062 isLRAssoc fixs_assoc nm =
1063 case lookupFixity fixs_assoc nm of
1064 Fixity _ InfixN -> (False, False)
1065 Fixity _ InfixR -> (False, True)
1066 Fixity _ InfixL -> (True, False)
1068 lookupFixity :: Fixities -> Name -> Fixity
1069 lookupFixity fixs_assoc nm = assocDefault defaultFixity fixs_assoc nm
1071 isInfixOccName :: String -> Bool
1072 isInfixOccName str =
1080 %************************************************************************
1082 \subsection{Generating extra binds (@con2tag@ and @tag2con@)}
1084 %************************************************************************
1089 con2tag_Foo :: Foo ... -> Int#
1090 tag2con_Foo :: Int -> Foo ... -- easier if Int, not Int#
1091 maxtag_Foo :: Int -- ditto (NB: not unboxed)
1094 The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
1099 = GenCon2Tag | GenTag2Con | GenMaxTag
1101 gen_tag_n_con_monobind
1102 :: (RdrName, -- (proto)Name for the thing in question
1103 TyCon, -- tycon in question
1107 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
1108 | lots_of_constructors
1109 = mk_FunMonoBind (getSrcLoc tycon) rdr_name
1110 [([VarPatIn a_RDR], HsApp getTag_Expr a_Expr)]
1113 = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon))
1116 lots_of_constructors = tyConFamilySize tycon > mAX_FAMILY_SIZE_FOR_VEC_RETURNS
1118 mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
1120 = ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
1122 pat = ConPatIn var_RDR (nOfThem (argFieldCount var) WildPatIn)
1123 var_RDR = qual_orig_name var
1125 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
1126 = mk_FunMonoBind (getSrcLoc tycon) rdr_name
1127 [([ConPatIn mkInt_RDR [VarPatIn a_RDR]],
1128 ExprWithTySig (HsApp tagToEnum_Expr a_Expr)
1129 (MonoTyVar (qual_orig_name tycon)))]
1131 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
1132 = mk_easy_FunMonoBind (getSrcLoc tycon)
1133 rdr_name [] [] (HsApp (HsVar mkInt_RDR) (HsLit (HsIntPrim max_tag)))
1135 max_tag = case (tyConDataCons tycon) of
1136 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
1140 %************************************************************************
1142 \subsection{Utility bits for generating bindings}
1144 %************************************************************************
1146 @mk_easy_FunMonoBind fun pats binds expr@ generates:
1148 fun pat1 pat2 ... patN = expr where binds
1151 @mk_FunMonoBind fun [([p1a, p1b, ...], e1), ...]@ is for
1152 multi-clause definitions; it generates:
1154 fun p1a p1b ... p1N = e1
1155 fun p2a p2b ... p2N = e2
1157 fun pMa pMb ... pMN = eM
1161 mk_easy_FunMonoBind :: SrcLoc -> RdrName -> [RdrNamePat]
1162 -> [RdrNameMonoBinds] -> RdrNameHsExpr
1165 mk_easy_FunMonoBind loc fun pats binds expr
1166 = FunMonoBind fun False{-not infix-} [mk_easy_Match loc pats binds expr] loc
1168 mk_easy_Match loc pats binds expr
1169 = mk_match loc pats expr (mkbind binds)
1171 mkbind [] = EmptyBinds
1172 mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] Recursive
1173 -- The renamer expects everything in its input to be a
1174 -- "recursive" MonoBinds, and it is its job to sort things out
1177 mk_FunMonoBind :: SrcLoc -> RdrName
1178 -> [([RdrNamePat], RdrNameHsExpr)]
1181 mk_FunMonoBind loc fun [] = panic "TcGenDeriv:mk_FunMonoBind"
1182 mk_FunMonoBind loc fun pats_and_exprs
1183 = FunMonoBind fun False{-not infix-}
1184 [ mk_match loc p e EmptyBinds | (p,e) <-pats_and_exprs ]
1187 mk_match loc pats expr binds
1188 = Match [] (map paren pats) Nothing
1189 (GRHSs (unguardedRHS expr loc) binds Nothing)
1191 paren p@(VarPatIn _) = p
1192 paren other_p = ParPatIn other_p
1196 mk_easy_App f xs = foldl HsApp (HsVar f) (map HsVar xs)
1199 ToDo: Better SrcLocs.
1203 RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1204 -> RdrNameHsExpr -> RdrNameHsExpr
1208 -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1209 -> RdrNameHsExpr -> RdrNameHsExpr
1211 careful_compare_Case :: -- checks for primitive types...
1213 -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1214 -> RdrNameHsExpr -> RdrNameHsExpr
1217 compare_Case = compare_gen_Case compare_RDR
1218 cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
1219 -- Was: compare_gen_Case cmp_eq_RDR
1221 compare_gen_Case fun lt eq gt a b
1222 = HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
1223 [mkSimpleMatch [ConPatIn ltTag_RDR []] lt Nothing mkGeneratedSrcLoc,
1224 mkSimpleMatch [ConPatIn eqTag_RDR []] eq Nothing mkGeneratedSrcLoc,
1225 mkSimpleMatch [ConPatIn gtTag_RDR []] gt Nothing mkGeneratedSrcLoc]
1228 careful_compare_Case ty lt eq gt a b
1229 = if not (isUnboxedType ty) then
1230 compare_gen_Case compare_RDR lt eq gt a b
1232 else -- we have to do something special for primitive things...
1233 HsIf (genOpApp a relevant_eq_op b)
1235 (HsIf (genOpApp a relevant_lt_op b) lt gt mkGeneratedSrcLoc)
1238 relevant_eq_op = assoc_ty_id eq_op_tbl ty
1239 relevant_lt_op = assoc_ty_id lt_op_tbl ty
1241 assoc_ty_id tyids ty
1242 = if null res then panic "assoc_ty"
1245 res = [id | (ty',id) <- tyids, ty == ty']
1248 [(charPrimTy, eqH_Char_RDR)
1249 ,(intPrimTy, eqH_Int_RDR)
1250 ,(wordPrimTy, eqH_Word_RDR)
1251 ,(addrPrimTy, eqH_Addr_RDR)
1252 ,(floatPrimTy, eqH_Float_RDR)
1253 ,(doublePrimTy, eqH_Double_RDR)
1257 [(charPrimTy, ltH_Char_RDR)
1258 ,(intPrimTy, ltH_Int_RDR)
1259 ,(wordPrimTy, ltH_Word_RDR)
1260 ,(addrPrimTy, ltH_Addr_RDR)
1261 ,(floatPrimTy, ltH_Float_RDR)
1262 ,(doublePrimTy, ltH_Double_RDR)
1265 -----------------------------------------------------------------------
1267 and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1269 and_Expr a b = genOpApp a and_RDR b
1270 append_Expr a b = genOpApp a append_RDR b
1272 -----------------------------------------------------------------------
1274 eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1276 = if not (isUnboxedType ty) then
1278 else -- we have to do something special for primitive things...
1279 genOpApp a relevant_eq_op b
1281 relevant_eq_op = assoc_ty_id eq_op_tbl ty
1285 argFieldCount :: DataCon -> Int -- Works on data and newtype constructors
1286 argFieldCount con = length (dataConRawArgTys con)
1290 untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
1291 untag_Expr tycon [] expr = expr
1292 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
1293 = HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
1294 [mkSimpleMatch [VarPatIn put_tag_here] (untag_Expr tycon more expr) Nothing mkGeneratedSrcLoc]
1297 cmp_tags_Expr :: RdrName -- Comparison op
1298 -> RdrName -> RdrName -- Things to compare
1299 -> RdrNameHsExpr -- What to return if true
1300 -> RdrNameHsExpr -- What to return if false
1303 cmp_tags_Expr op a b true_case false_case
1304 = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case mkGeneratedSrcLoc
1307 :: RdrNameHsExpr -> RdrNameHsExpr
1309 enum_from_then_to_Expr
1310 :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1313 enum_from_to_Expr f t2 = HsApp (HsApp (HsVar enumFromTo_RDR) f) t2
1314 enum_from_then_to_Expr f t t2 = HsApp (HsApp (HsApp (HsVar enumFromThenTo_RDR) f) t) t2
1316 showParen_Expr, readParen_Expr
1317 :: RdrNameHsExpr -> RdrNameHsExpr
1320 showParen_Expr e1 e2 = HsApp (HsApp (HsVar showParen_RDR) e1) e2
1321 readParen_Expr e1 e2 = HsApp (HsApp (HsVar readParen_RDR) e1) e2
1323 nested_compose_Expr :: [RdrNameHsExpr] -> RdrNameHsExpr
1325 nested_compose_Expr [e] = parenify e
1326 nested_compose_Expr (e:es)
1327 = HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
1329 -- impossible_Expr is used in case RHSs that should never happen.
1330 -- We generate these to keep the desugarer from complaining that they *might* happen!
1331 impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ "Urk! in TcGenDeriv")))
1333 -- illegal_Expr is used when signalling error conditions in the RHS of a derived
1334 -- method. It is currently only used by Enum.{succ,pred}
1335 illegal_Expr meth tp msg =
1336 HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ (meth ++ '{':tp ++ "}: " ++ msg))))
1338 -- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
1339 -- to include the value of a_RDR in the error string.
1340 illegal_toEnum_tag tp maxtag =
1341 HsApp (HsVar error_RDR)
1342 (HsApp (HsApp (HsVar append_RDR)
1343 (HsLit (HsString (_PK_ ("toEnum{" ++ tp ++ "}: tag (")))))
1344 (HsApp (HsApp (HsApp
1345 (HsVar showsPrec_RDR)
1350 (HsLit (HsString (_PK_ ") is outside of enumeration's range (0,"))))
1351 (HsApp (HsApp (HsApp
1352 (HsVar showsPrec_RDR)
1355 (HsLit (HsString (_PK_ ")")))))))
1357 parenify e@(HsVar _) = e
1358 parenify e = HsPar e
1360 -- genOpApp wraps brackets round the operator application, so that the
1361 -- renamer won't subsequently try to re-associate it.
1362 -- For some reason the renamer doesn't reassociate it right, and I can't
1363 -- be bothered to find out why just now.
1365 genOpApp e1 op e2 = mkOpApp e1 op e2
1369 qual_orig_name n = nameRdrName (getName n)
1370 varUnqual n = mkSrcUnqual varName n
1372 zz_a_RDR = varUnqual SLIT("_a")
1373 a_RDR = varUnqual SLIT("a")
1374 b_RDR = varUnqual SLIT("b")
1375 c_RDR = varUnqual SLIT("c")
1376 d_RDR = varUnqual SLIT("d")
1377 ah_RDR = varUnqual SLIT("a#")
1378 bh_RDR = varUnqual SLIT("b#")
1379 ch_RDR = varUnqual SLIT("c#")
1380 dh_RDR = varUnqual SLIT("d#")
1381 cmp_eq_RDR = varUnqual SLIT("cmp_eq")
1382 rangeSize_RDR = varUnqual SLIT("rangeSize")
1384 as_RDRs = [ varUnqual (_PK_ ("a"++show i)) | i <- [(1::Int) .. ] ]
1385 bs_RDRs = [ varUnqual (_PK_ ("b"++show i)) | i <- [(1::Int) .. ] ]
1386 cs_RDRs = [ varUnqual (_PK_ ("c"++show i)) | i <- [(1::Int) .. ] ]
1388 mkHsString s = HsString (_PK_ s)
1390 zz_a_Expr = HsVar zz_a_RDR
1391 a_Expr = HsVar a_RDR
1392 b_Expr = HsVar b_RDR
1393 c_Expr = HsVar c_RDR
1394 d_Expr = HsVar d_RDR
1395 ltTag_Expr = HsVar ltTag_RDR
1396 eqTag_Expr = HsVar eqTag_RDR
1397 gtTag_Expr = HsVar gtTag_RDR
1398 false_Expr = HsVar false_RDR
1399 true_Expr = HsVar true_RDR
1401 getTag_Expr = HsVar getTag_RDR
1402 tagToEnum_Expr = HsVar tagToEnumH_RDR
1403 con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
1406 zz_a_Pat = VarPatIn zz_a_RDR
1407 a_Pat = VarPatIn a_RDR
1408 b_Pat = VarPatIn b_RDR
1409 c_Pat = VarPatIn c_RDR
1410 d_Pat = VarPatIn d_RDR
1412 con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
1414 con2tag_RDR tycon = varUnqual (_PK_ ("con2tag_" ++ occNameString (getOccName tycon) ++ "#"))
1415 tag2con_RDR tycon = varUnqual (_PK_ ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
1416 maxtag_RDR tycon = varUnqual (_PK_ ("maxtag_" ++ occNameString (getOccName tycon) ++ "#"))