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(..),
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 import FieldLabel ( fieldLabelName )
39 import DataCon ( isNullaryDataCon, dataConTag,
40 dataConRawArgTys, fIRST_TAG,
43 import Name ( getOccString, getOccName, getSrcLoc, occNameString,
44 occNameUserString, nameRdrName, varName,
45 OccName, Name, NamedThing(..), NameSpace
48 import PrimOp ( PrimOp(..) )
49 import PrelInfo -- Lots of RdrNames
50 import SrcLoc ( mkGeneratedSrcLoc, SrcLoc )
51 import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
54 import Type ( isUnLiftedType, isUnboxedType, Type )
55 import TysPrim ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
56 floatPrimTy, doublePrimTy
58 import Util ( mapAccumL, zipEqual, zipWithEqual,
59 zipWith3Equal, nOfThem )
60 import Panic ( panic, assertPanic )
61 import Maybes ( maybeToBool, assocMaybe )
62 import List ( partition, intersperse )
65 %************************************************************************
67 \subsection{Generating code, by derivable class}
69 %************************************************************************
71 %************************************************************************
73 \subsubsection{Generating @Eq@ instance declarations}
75 %************************************************************************
77 Here are the heuristics for the code we generate for @Eq@:
80 Let's assume we have a data type with some (possibly zero) nullary
81 data constructors and some ordinary, non-nullary ones (the rest,
82 also possibly zero of them). Here's an example, with both \tr{N}ullary
83 and \tr{O}rdinary data cons.
85 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
89 For the ordinary constructors (if any), we emit clauses to do The
93 (==) (O1 a1 b1) (O1 a2 b2) = a1 == a2 && b1 == b2
94 (==) (O2 a1) (O2 a2) = a1 == a2
95 (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2
98 Note: if we're comparing unboxed things, e.g., if \tr{a1} and
99 \tr{a2} are \tr{Float#}s, then we have to generate
101 case (a1 `eqFloat#` a2) of
104 for that particular test.
107 If there are any nullary constructors, we emit a catch-all clause of
111 (==) a b = case (con2tag_Foo a) of { a# ->
112 case (con2tag_Foo b) of { b# ->
113 case (a# ==# b#) of {
118 If there aren't any nullary constructors, we emit a simpler
125 For the @(/=)@ method, we normally just use the default method.
127 If the type is an enumeration type, we could/may/should? generate
128 special code that calls @con2tag_Foo@, much like for @(==)@ shown
132 We thought about doing this: If we're also deriving @Ord@ for this
135 instance ... Eq (Foo ...) where
136 (==) a b = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
137 (/=) a b = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
139 However, that requires that \tr{Ord <whatever>} was put in the context
140 for the instance decl, which it probably wasn't, so the decls
141 produced don't get through the typechecker.
145 deriveEq :: RdrName -- Class
146 -> RdrName -- Type constructor
147 -> [ (RdrName, [RdrType]) ] -- Constructors
148 -> (RdrContext, -- Context for the inst decl
149 [RdrBind], -- Binds in the inst decl
150 [RdrBind]) -- Extra value bindings outside
152 deriveEq clas tycon constrs
153 = (context, [eq_bind, ne_bind], [])
155 context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
158 (nullary_cons, non_nullary_cons) = partition is_nullary constrs
159 is_nullary (_, args) = null args
162 gen_Eq_binds :: TyCon -> RdrNameMonoBinds
166 tycon_loc = getSrcLoc tycon
167 (nullary_cons, nonnullary_cons)
168 | isNewTyCon tycon = ([], tyConDataCons tycon)
169 | otherwise = partition isNullaryDataCon (tyConDataCons tycon)
172 = if (null nullary_cons) then
173 case maybeTyConSingleCon tycon of
175 Nothing -> -- if cons don't match, then False
176 [([a_Pat, b_Pat], false_Expr)]
177 else -- calc. and compare the tags
179 untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
180 (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR true_Expr false_Expr))]
182 mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
184 mk_easy_FunMonoBind tycon_loc ne_RDR [a_Pat, b_Pat] [] (
185 HsApp (HsVar not_RDR) (HsPar (mk_easy_App eq_RDR [a_RDR, b_RDR])))
187 ------------------------------------------------------------------
190 con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
191 con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
193 data_con_RDR = qual_orig_name data_con
194 con_arity = length tys_needed
195 as_needed = take con_arity as_RDRs
196 bs_needed = take con_arity bs_RDRs
197 tys_needed = dataConRawArgTys data_con
199 ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
201 nested_eq_expr [] [] [] = true_Expr
202 nested_eq_expr tys as bs
203 = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
205 nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
208 %************************************************************************
210 \subsubsection{Generating @Ord@ instance declarations}
212 %************************************************************************
214 For a derived @Ord@, we concentrate our attentions on @compare@
216 compare :: a -> a -> Ordering
217 data Ordering = LT | EQ | GT deriving ()
220 We will use the same example data type as above:
222 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
227 We do all the other @Ord@ methods with calls to @compare@:
229 instance ... (Ord <wurble> <wurble>) where
230 a < b = case (compare a b) of { LT -> True; EQ -> False; GT -> False }
231 a <= b = case (compare a b) of { LT -> True; EQ -> True; GT -> False }
232 a >= b = case (compare a b) of { LT -> False; EQ -> True; GT -> True }
233 a > b = case (compare a b) of { LT -> False; EQ -> False; GT -> True }
235 max a b = case (compare a b) of { LT -> b; EQ -> a; GT -> a }
236 min a b = case (compare a b) of { LT -> a; EQ -> b; GT -> b }
238 -- compare to come...
242 @compare@ always has two parts. First, we use the compared
243 data-constructors' tags to deal with the case of different
246 compare a b = case (con2tag_Foo a) of { a# ->
247 case (con2tag_Foo b) of { b# ->
248 case (a# ==# b#) of {
250 False -> case (a# <# b#) of
255 cmp_eq = ... to come ...
259 We are only left with the ``help'' function @cmp_eq@, to deal with
260 comparing data constructors with the same tag.
262 For the ordinary constructors (if any), we emit the sorta-obvious
263 compare-style stuff; for our example:
265 cmp_eq (O1 a1 b1) (O1 a2 b2)
266 = case (compare a1 a2) of { LT -> LT; EQ -> compare b1 b2; GT -> GT }
268 cmp_eq (O2 a1) (O2 a2)
271 cmp_eq (O3 a1 b1 c1) (O3 a2 b2 c2)
272 = case (compare a1 a2) of {
275 EQ -> case compare b1 b2 of {
283 Again, we must be careful about unboxed comparisons. For example,
284 if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
288 cmp_eq lt eq gt (O2 a1) (O2 a2)
290 -- or maybe the unfolded equivalent
294 For the remaining nullary constructors, we already know that the
301 If there is only one constructor in the Data Type we don't need the WildCard Pattern.
305 gen_Ord_binds :: TyCon -> RdrNameMonoBinds
308 = defaulted `AndMonoBinds` compare
310 tycon_loc = getSrcLoc tycon
311 --------------------------------------------------------------------
312 compare = mk_easy_FunMonoBind tycon_loc compare_RDR
315 (if maybeToBool (maybeTyConSingleCon tycon) then
317 -- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
318 -- Wierd. Was: case (cmp a b) of { LT -> LT; EQ -> EQ; GT -> GT }
320 cmp_eq_Expr a_Expr b_Expr
322 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
323 (cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR
324 -- True case; they are equal
325 -- If an enumeration type we are done; else
326 -- recursively compare their components
327 (if isEnumerationTyCon tycon then
330 -- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
332 cmp_eq_Expr a_Expr b_Expr
334 -- False case; they aren't equal
335 -- So we need to do a less-than comparison on the tags
336 (cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
338 tycon_data_cons = tyConDataCons tycon
339 (nullary_cons, nonnullary_cons)
340 | isNewTyCon tycon = ([], tyConDataCons tycon)
341 | otherwise = partition isNullaryDataCon tycon_data_cons
344 mk_FunMonoBind tycon_loc
346 (if null nonnullary_cons && (length nullary_cons == 1) then
347 -- catch this specially to avoid warnings
348 -- about overlapping patterns from the desugarer.
350 data_con = head nullary_cons
351 data_con_RDR = qual_orig_name data_con
352 pat = ConPatIn data_con_RDR []
354 [([pat,pat], eqTag_Expr)]
356 map pats_etc nonnullary_cons ++
357 -- leave out wildcards to silence desugarer.
358 (if length tycon_data_cons == 1 then
361 [([WildPatIn, WildPatIn], default_rhs)]))
364 = ([con1_pat, con2_pat],
365 nested_compare_expr tys_needed as_needed bs_needed)
367 con1_pat = ConPatIn data_con_RDR (map VarPatIn as_needed)
368 con2_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
370 data_con_RDR = qual_orig_name data_con
371 con_arity = length tys_needed
372 as_needed = take con_arity as_RDRs
373 bs_needed = take con_arity bs_RDRs
374 tys_needed = dataConRawArgTys data_con
376 nested_compare_expr [ty] [a] [b]
377 = careful_compare_Case ty ltTag_Expr eqTag_Expr gtTag_Expr (HsVar a) (HsVar b)
379 nested_compare_expr (ty:tys) (a:as) (b:bs)
380 = let eq_expr = nested_compare_expr tys as bs
381 in careful_compare_Case ty ltTag_Expr eq_expr gtTag_Expr (HsVar a) (HsVar b)
383 default_rhs | null nullary_cons = impossible_Expr -- Keep desugarer from complaining about
384 -- inexhaustive patterns
385 | otherwise = eqTag_Expr -- Some nullary constructors;
386 -- Tags are equal, no args => return EQ
387 --------------------------------------------------------------------
389 defaulted = foldr1 AndMonoBinds [lt, le, ge, gt, max_, min_]
391 lt = mk_easy_FunMonoBind mkGeneratedSrcLoc lt_RDR [a_Pat, b_Pat] [] (
392 compare_Case true_Expr false_Expr false_Expr a_Expr b_Expr)
393 le = mk_easy_FunMonoBind mkGeneratedSrcLoc le_RDR [a_Pat, b_Pat] [] (
394 compare_Case true_Expr true_Expr false_Expr a_Expr b_Expr)
395 ge = mk_easy_FunMonoBind mkGeneratedSrcLoc ge_RDR [a_Pat, b_Pat] [] (
396 compare_Case false_Expr true_Expr true_Expr a_Expr b_Expr)
397 gt = mk_easy_FunMonoBind mkGeneratedSrcLoc gt_RDR [a_Pat, b_Pat] [] (
398 compare_Case false_Expr false_Expr true_Expr a_Expr b_Expr)
400 max_ = mk_easy_FunMonoBind mkGeneratedSrcLoc max_RDR [a_Pat, b_Pat] [] (
401 compare_Case b_Expr a_Expr a_Expr a_Expr b_Expr)
402 min_ = mk_easy_FunMonoBind mkGeneratedSrcLoc min_RDR [a_Pat, b_Pat] [] (
403 compare_Case a_Expr b_Expr b_Expr a_Expr b_Expr)
406 %************************************************************************
408 \subsubsection{Generating @Enum@ instance declarations}
410 %************************************************************************
412 @Enum@ can only be derived for enumeration types. For a type
414 data Foo ... = N1 | N2 | ... | Nn
417 we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
418 @maxtag_Foo@ variable (all generated by @gen_tag_n_con_binds@).
421 instance ... Enum (Foo ...) where
422 succ x = toEnum (1 + fromEnum x)
423 pred x = toEnum (fromEnum x - 1)
425 toEnum i = tag2con_Foo i
427 enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
431 = case con2tag_Foo a of
432 a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)
435 = map tag2con_Foo [con2tag_Foo a, con2tag_Foo b .. maxtag_Foo]
439 = case con2tag_Foo a of { a# ->
440 case con2tag_Foo b of { b# ->
441 map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
445 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
448 gen_Enum_binds :: TyCon -> RdrNameMonoBinds
451 = succ_enum `AndMonoBinds`
452 pred_enum `AndMonoBinds`
453 to_enum `AndMonoBinds`
454 enum_from `AndMonoBinds`
455 enum_from_then `AndMonoBinds`
458 tycon_loc = getSrcLoc tycon
459 occ_nm = getOccString tycon
462 = mk_easy_FunMonoBind tycon_loc succ_RDR [a_Pat] [] $
463 untag_Expr tycon [(a_RDR, ah_RDR)] $
464 HsIf (HsApp (HsApp (HsVar eq_RDR)
465 (HsVar (maxtag_RDR tycon)))
466 (mk_easy_App mkInt_RDR [ah_RDR]))
467 (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
468 (HsApp (HsVar (tag2con_RDR tycon))
469 (HsApp (HsApp (HsVar plus_RDR)
470 (mk_easy_App mkInt_RDR [ah_RDR]))
475 = mk_easy_FunMonoBind tycon_loc pred_RDR [a_Pat] [] $
476 untag_Expr tycon [(a_RDR, ah_RDR)] $
477 HsIf (HsApp (HsApp (HsVar eq_RDR) (HsLit (HsInt 0)))
478 (mk_easy_App mkInt_RDR [ah_RDR]))
479 (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
480 (HsApp (HsVar (tag2con_RDR tycon))
481 (HsApp (HsApp (HsVar plus_RDR)
482 (mk_easy_App mkInt_RDR [ah_RDR]))
483 (HsLit (HsInt (-1)))))
487 = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
490 (HsApp (HsApp (HsVar ge_RDR)
493 (HsApp (HsApp (HsVar le_RDR)
495 (HsVar (maxtag_RDR tycon))))
496 (mk_easy_App (tag2con_RDR tycon) [a_RDR])
497 (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
501 = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
502 untag_Expr tycon [(a_RDR, ah_RDR)] $
503 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
504 HsPar (enum_from_to_Expr
505 (mk_easy_App mkInt_RDR [ah_RDR])
506 (HsVar (maxtag_RDR tycon)))
509 = mk_easy_FunMonoBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] [] $
510 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
511 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
512 HsPar (enum_from_then_to_Expr
513 (mk_easy_App mkInt_RDR [ah_RDR])
514 (mk_easy_App mkInt_RDR [bh_RDR])
515 (HsIf (HsApp (HsApp (HsVar gt_RDR)
516 (mk_easy_App mkInt_RDR [ah_RDR]))
517 (mk_easy_App mkInt_RDR [bh_RDR]))
519 (HsVar (maxtag_RDR tycon))
523 = mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
524 untag_Expr tycon [(a_RDR, ah_RDR)] $
525 (mk_easy_App mkInt_RDR [ah_RDR])
528 %************************************************************************
530 \subsubsection{Generating @Bounded@ instance declarations}
532 %************************************************************************
535 gen_Bounded_binds tycon
536 = if isEnumerationTyCon tycon then
537 min_bound_enum `AndMonoBinds` max_bound_enum
539 ASSERT(length data_cons == 1)
540 min_bound_1con `AndMonoBinds` max_bound_1con
542 data_cons = tyConDataCons tycon
543 tycon_loc = getSrcLoc tycon
545 ----- enum-flavored: ---------------------------
546 min_bound_enum = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] (HsVar data_con_1_RDR)
547 max_bound_enum = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] (HsVar data_con_N_RDR)
549 data_con_1 = head data_cons
550 data_con_N = last data_cons
551 data_con_1_RDR = qual_orig_name data_con_1
552 data_con_N_RDR = qual_orig_name data_con_N
554 ----- single-constructor-flavored: -------------
555 arity = argFieldCount data_con_1
557 min_bound_1con = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] $
558 mk_easy_App data_con_1_RDR (nOfThem arity minBound_RDR)
559 max_bound_1con = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] $
560 mk_easy_App data_con_1_RDR (nOfThem arity maxBound_RDR)
563 %************************************************************************
565 \subsubsection{Generating @Ix@ instance declarations}
567 %************************************************************************
569 Deriving @Ix@ is only possible for enumeration types and
570 single-constructor types. We deal with them in turn.
572 For an enumeration type, e.g.,
574 data Foo ... = N1 | N2 | ... | Nn
576 things go not too differently from @Enum@:
578 instance ... Ix (Foo ...) where
580 = map tag2con_Foo [con2tag_Foo a .. con2tag_Foo b]
584 = case (con2tag_Foo a) of { a# ->
585 case (con2tag_Foo b) of { b# ->
586 map tag2con_Foo (enumFromTo (I# a#) (I# b#))
591 then case (con2tag_Foo d -# con2tag_Foo a) of
593 else error "Ix.Foo.index: out of range"
597 p_tag = con2tag_Foo c
599 p_tag >= con2tag_Foo a && p_tag <= con2tag_Foo b
603 = case (con2tag_Foo a) of { a_tag ->
604 case (con2tag_Foo b) of { b_tag ->
605 case (con2tag_Foo c) of { c_tag ->
606 if (c_tag >=# a_tag) then
612 (modulo suitable case-ification to handle the unboxed tags)
614 For a single-constructor type (NB: this includes all tuples), e.g.,
616 data Foo ... = MkFoo a b Int Double c c
618 we follow the scheme given in Figure~19 of the Haskell~1.2 report
622 gen_Ix_binds :: TyCon -> RdrNameMonoBinds
625 = if isEnumerationTyCon tycon
629 tycon_str = getOccString tycon
630 tycon_loc = getSrcLoc tycon
632 --------------------------------------------------------------
633 enum_ixes = enum_range `AndMonoBinds`
634 enum_index `AndMonoBinds` enum_inRange
637 = mk_easy_FunMonoBind tycon_loc range_RDR
638 [TuplePatIn [a_Pat, b_Pat] True{-boxed-}] [] $
639 untag_Expr tycon [(a_RDR, ah_RDR)] $
640 untag_Expr tycon [(b_RDR, bh_RDR)] $
641 HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
642 HsPar (enum_from_to_Expr
643 (mk_easy_App mkInt_RDR [ah_RDR])
644 (mk_easy_App mkInt_RDR [bh_RDR]))
647 = mk_easy_FunMonoBind tycon_loc index_RDR
648 [AsPatIn c_RDR (TuplePatIn [a_Pat, b_Pat] True{-boxed-}),
650 HsIf (HsPar (mk_easy_App inRange_RDR [c_RDR, d_RDR])) (
651 untag_Expr tycon [(a_RDR, ah_RDR)] (
652 untag_Expr tycon [(d_RDR, dh_RDR)] (
654 rhs = mk_easy_App mkInt_RDR [c_RDR]
657 (genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
658 [mkSimpleMatch [VarPatIn c_RDR] rhs Nothing tycon_loc]
662 HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ ("Ix."++tycon_str++".index: out of range\n"))))
667 = mk_easy_FunMonoBind tycon_loc inRange_RDR
668 [TuplePatIn [a_Pat, b_Pat] True{-boxed-}, c_Pat] [] (
669 untag_Expr tycon [(a_RDR, ah_RDR)] (
670 untag_Expr tycon [(b_RDR, bh_RDR)] (
671 untag_Expr tycon [(c_RDR, ch_RDR)] (
672 HsIf (genOpApp (HsVar ch_RDR) geH_RDR (HsVar ah_RDR)) (
673 (genOpApp (HsVar ch_RDR) leH_RDR (HsVar bh_RDR))
678 --------------------------------------------------------------
680 = single_con_range `AndMonoBinds`
681 single_con_index `AndMonoBinds`
685 = case maybeTyConSingleCon tycon of -- just checking...
686 Nothing -> panic "get_Ix_binds"
687 Just dc -> if (any isUnLiftedType (dataConRawArgTys dc)) then
688 error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
692 con_arity = argFieldCount data_con
693 data_con_RDR = qual_orig_name data_con
695 as_needed = take con_arity as_RDRs
696 bs_needed = take con_arity bs_RDRs
697 cs_needed = take con_arity cs_RDRs
699 con_pat xs = ConPatIn data_con_RDR (map VarPatIn xs)
700 con_expr = mk_easy_App data_con_RDR cs_needed
702 --------------------------------------------------------------
704 = mk_easy_FunMonoBind tycon_loc range_RDR
705 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True{-boxed-}] [] $
706 HsDo ListComp stmts tycon_loc
708 stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
710 [ReturnStmt con_expr]
712 mk_qual a b c = BindStmt (VarPatIn c)
713 (HsApp (HsVar range_RDR)
714 (ExplicitTuple [HsVar a, HsVar b] True))
719 = mk_easy_FunMonoBind tycon_loc index_RDR
720 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
721 con_pat cs_needed] [range_size] (
722 foldl mk_index (HsLit (HsInt 0)) (zip3 as_needed bs_needed cs_needed))
724 mk_index multiply_by (l, u, i)
726 (HsApp (HsApp (HsVar index_RDR)
727 (ExplicitTuple [HsVar l, HsVar u] True)) (HsVar i))
730 (HsApp (HsVar rangeSize_RDR)
731 (ExplicitTuple [HsVar l, HsVar u] True))
732 ) times_RDR multiply_by
736 = mk_easy_FunMonoBind tycon_loc rangeSize_RDR
737 [TuplePatIn [a_Pat, b_Pat] True] [] (
739 (HsApp (HsApp (HsVar index_RDR)
740 (ExplicitTuple [a_Expr, b_Expr] True)) b_Expr)
741 ) plus_RDR (HsLit (HsInt 1)))
745 = mk_easy_FunMonoBind tycon_loc inRange_RDR
746 [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
749 foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
751 in_range a b c = HsApp (HsApp (HsVar inRange_RDR)
752 (ExplicitTuple [HsVar a, HsVar b] True))
756 %************************************************************************
758 \subsubsection{Generating @Read@ instance declarations}
760 %************************************************************************
763 gen_Read_binds :: Fixities -> TyCon -> RdrNameMonoBinds
765 gen_Read_binds fixities tycon
766 = reads_prec `AndMonoBinds` read_list
768 tycon_loc = getSrcLoc tycon
769 -----------------------------------------------------------------------
770 read_list = mk_easy_FunMonoBind tycon_loc readList_RDR [] []
771 (HsApp (HsVar readList___RDR) (HsPar (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 0)))))
772 -----------------------------------------------------------------------
775 read_con_comprehensions
776 = map read_con (tyConDataCons tycon)
778 mk_easy_FunMonoBind tycon_loc readsPrec_RDR [a_Pat, b_Pat] [] (
779 foldr1 append_Expr read_con_comprehensions
782 read_con data_con -- note: "b" is the string being "read"
784 readParen_Expr read_paren_arg $ HsPar $
785 HsLam (mk_easy_Match tycon_loc [c_Pat] [] $
786 HsDo ListComp stmts tycon_loc)
789 data_con_RDR = qual_orig_name data_con
790 data_con_str = occNameUserString (getOccName data_con)
791 con_arity = argFieldCount data_con
792 con_expr = mk_easy_App data_con_RDR as_needed
793 nullary_con = con_arity == 0
794 labels = dataConFieldLabels data_con
795 lab_fields = length labels
796 dc_nm = getName data_con
797 is_infix = isInfixOccName data_con_str
799 as_needed = take con_arity as_RDRs
801 | is_infix = take (1 + con_arity) bs_RDRs
802 | lab_fields == 0 = take con_arity bs_RDRs
803 | otherwise = take (4*lab_fields + 1) bs_RDRs
804 -- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
806 (as1:as2:_) = as_needed
807 (bs1:bs2:bs3:_) = bs_needed
812 (TuplePatIn [LitPatIn (mkHsString data_con_str), d_Pat] True)
813 (HsApp (HsVar lex_RDR) c_Expr)
817 (TuplePatIn [LitPatIn (mkHsString data_con_str), VarPatIn bs2] True)
818 (HsApp (HsVar lex_RDR) (HsVar bs1))
822 str_qual str res draw_from =
824 (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] True)
825 (HsApp (HsVar lex_RDR) draw_from)
828 read_label f = [str_qual nm, str_qual "="]
829 -- There might be spaces between the label and '='
831 nm = occNameUserString (getOccName (fieldLabelName f))
835 snd (mapAccumL mk_qual_infix
837 [ (mk_read_qual lp as1, bs1, bs2)
838 , (mk_read_qual rp as2, bs3, bs3)
840 | lab_fields == 0 = -- common case.
841 snd (mapAccumL mk_qual
843 (zipWithEqual "as_needed"
844 (\ con_field draw_from -> (mk_read_qual 10 con_field,
846 as_needed bs_needed))
849 mapAccumL mk_qual c_Expr
850 (zipEqual "bs_needed"
853 intersperse [str_qual ","] $
856 (\ as b -> as ++ [b])
858 (map read_label labels)
860 (map (mk_read_qual 10) as_needed))) ++ [str_qual "}"])
863 mk_qual_infix draw_from (f, str_left, str_left2) =
864 (HsVar str_left2, -- what to draw from down the line...
865 f str_left draw_from)
867 mk_qual draw_from (f, str_left) =
868 (HsVar str_left, -- what to draw from down the line...
869 f str_left draw_from)
871 mk_read_qual p con_field res draw_from =
873 (TuplePatIn [VarPatIn con_field, VarPatIn res] True)
874 (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt p))) draw_from)
877 result_expr = ExplicitTuple [con_expr, if null bs_needed
879 else HsVar (last bs_needed)] True
881 [lp,rp] = getLRPrecs fixities dc_nm
884 | is_infix = let (h:t) = field_quals in (h:con_qual:t)
885 | otherwise = con_qual:field_quals
887 stmts = quals ++ [ReturnStmt result_expr]
891 | otherwise = getFixity fixities dc_nm
893 read_paren_arg = -- parens depend on precedence...
894 HsPar (genOpApp a_Expr gt_RDR (HsLit (HsInt paren_prec_limit)))
898 %************************************************************************
900 \subsubsection{Generating @Show@ instance declarations}
902 %************************************************************************
905 gen_Show_binds :: Fixities -> TyCon -> RdrNameMonoBinds
907 gen_Show_binds fixs_assoc tycon
908 = shows_prec `AndMonoBinds` show_list
910 tycon_loc = getSrcLoc tycon
911 -----------------------------------------------------------------------
912 show_list = mk_easy_FunMonoBind tycon_loc showList_RDR [] []
913 (HsApp (HsVar showList___RDR) (HsPar (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 0)))))
914 -----------------------------------------------------------------------
915 shows_prec = mk_FunMonoBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
918 | nullary_con = -- skip the showParen junk...
919 ASSERT(null bs_needed)
920 ([a_Pat, con_pat], show_con)
923 showParen_Expr (HsPar (genOpApp a_Expr gt_RDR (HsLit (HsInt paren_prec_limit))))
924 (HsPar (nested_compose_Expr show_thingies)))
926 data_con_RDR = qual_orig_name data_con
927 con_arity = argFieldCount data_con
928 bs_needed = take con_arity bs_RDRs
929 con_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
930 nullary_con = con_arity == 0
931 labels = dataConFieldLabels data_con
932 lab_fields = length labels
934 dc_occ_nm = occNameUserString (getOccName data_con)
935 dc_nm = getName data_con
937 is_infix = isInfixOccName dc_occ_nm
941 | is_infix = mk_showString_app (' ':dc_occ_nm)
946 | lab_fields == 0 = " "
949 mk_showString_app (dc_occ_nm ++ space_ocurly_maybe)
951 show_all con fs@(x:xs)
952 | is_infix = x:con:xs
956 | lab_fields > 0 = [mk_showString_app "}"]
959 con:fs ++ ccurly_maybe
961 show_thingies = show_all show_con real_show_thingies_with_labs
963 show_label l = mk_showString_app (nm ++ "=")
965 nm = occNameUserString (getOccName (fieldLabelName l))
968 mk_showString_app str = HsApp (HsVar showString_RDR)
969 (HsLit (mkHsString str))
971 prec_cons = getLRPrecs fixs_assoc dc_nm
975 [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt p))) (HsVar b)
976 | (p,b) <- zip prec_cons bs_needed ]
978 [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
981 real_show_thingies_with_labs
982 | lab_fields == 0 = intersperse (HsVar showSpace_RDR) real_show_thingies
983 | otherwise = --Assumption: no of fields == no of labelled fields
984 -- (and in same order)
986 intersperse ([mk_showString_app ","]) $ -- Using SLIT()s containing ,s spells trouble.
987 zipWithEqual "gen_Show_binds"
989 (map show_label labels)
992 (con_left_assoc, con_right_assoc) = isLRAssoc fixs_assoc dc_nm
996 | otherwise = getFixity fixs_assoc dc_nm
1001 getLRPrecs :: Fixities -> Name -> [Integer]
1002 getLRPrecs fixs_assoc nm = [lp, rp]
1004 ( con_left_assoc, con_right_assoc) = isLRAssoc fixs_assoc nm
1005 paren_prec_limit = 9
1008 | con_left_assoc = paren_prec_limit
1009 | otherwise = paren_prec_limit + 1
1012 | con_right_assoc = paren_prec_limit
1013 | otherwise = paren_prec_limit + 1
1016 getFixity :: Fixities -> Name -> Integer
1017 getFixity fixs_assoc nm =
1018 case assocMaybe fixs_assoc nm of
1020 Just (Fixity x _) -> fromInt x + 1
1022 isLRAssoc :: Fixities -> Name -> (Bool, Bool)
1023 isLRAssoc fixs_assoc nm =
1024 case assocMaybe fixs_assoc nm of
1025 Just (Fixity _ InfixL) -> (True, False)
1026 Just (Fixity _ InfixR) -> (False, True)
1029 isInfixOccName :: String -> Bool
1030 isInfixOccName str =
1038 %************************************************************************
1040 \subsection{Generating extra binds (@con2tag@ and @tag2con@)}
1042 %************************************************************************
1047 con2tag_Foo :: Foo ... -> Int#
1048 tag2con_Foo :: Int -> Foo ... -- easier if Int, not Int#
1049 maxtag_Foo :: Int -- ditto (NB: not unboxed)
1052 The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
1057 = GenCon2Tag | GenTag2Con | GenMaxTag
1059 gen_tag_n_con_monobind
1060 :: (RdrName, -- (proto)Name for the thing in question
1061 TyCon, -- tycon in question
1065 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
1066 = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon))
1068 mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
1071 = ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
1073 pat = ConPatIn var_RDR (nOfThem (argFieldCount var) WildPatIn)
1074 var_RDR = qual_orig_name var
1076 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
1077 = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon) ++
1078 [([WildPatIn], impossible_Expr)])
1080 mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
1081 mk_stuff var = ([lit_pat], HsVar var_RDR)
1083 lit_pat = ConPatIn mkInt_RDR [LitPatIn (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG)))]
1084 var_RDR = qual_orig_name var
1086 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
1087 = mk_easy_FunMonoBind (getSrcLoc tycon)
1088 rdr_name [] [] (HsApp (HsVar mkInt_RDR) (HsLit (HsIntPrim max_tag)))
1090 max_tag = case (tyConDataCons tycon) of
1091 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
1095 %************************************************************************
1097 \subsection{Utility bits for generating bindings}
1099 %************************************************************************
1101 @mk_easy_FunMonoBind fun pats binds expr@ generates:
1103 fun pat1 pat2 ... patN = expr where binds
1106 @mk_FunMonoBind fun [([p1a, p1b, ...], e1), ...]@ is for
1107 multi-clause definitions; it generates:
1109 fun p1a p1b ... p1N = e1
1110 fun p2a p2b ... p2N = e2
1112 fun pMa pMb ... pMN = eM
1116 mk_easy_FunMonoBind :: SrcLoc -> RdrName -> [RdrNamePat]
1117 -> [RdrNameMonoBinds] -> RdrNameHsExpr
1120 mk_easy_FunMonoBind loc fun pats binds expr
1121 = FunMonoBind fun False{-not infix-} [mk_easy_Match loc pats binds expr] loc
1123 mk_easy_Match loc pats binds expr
1124 = mk_match loc pats expr (mkbind binds)
1126 mkbind [] = EmptyBinds
1127 mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] Recursive
1128 -- The renamer expects everything in its input to be a
1129 -- "recursive" MonoBinds, and it is its job to sort things out
1132 mk_FunMonoBind :: SrcLoc -> RdrName
1133 -> [([RdrNamePat], RdrNameHsExpr)]
1136 mk_FunMonoBind loc fun [] = panic "TcGenDeriv:mk_FunMonoBind"
1137 mk_FunMonoBind loc fun pats_and_exprs
1138 = FunMonoBind fun False{-not infix-}
1139 [ mk_match loc p e EmptyBinds | (p,e) <-pats_and_exprs ]
1142 mk_match loc pats expr binds
1143 = Match [] (map paren pats) Nothing
1144 (GRHSs (unguardedRHS expr loc) binds Nothing)
1146 paren p@(VarPatIn _) = p
1147 paren other_p = ParPatIn other_p
1151 mk_easy_App f xs = foldl HsApp (HsVar f) (map HsVar xs)
1154 ToDo: Better SrcLocs.
1158 RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1159 -> RdrNameHsExpr -> RdrNameHsExpr
1163 -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1164 -> RdrNameHsExpr -> RdrNameHsExpr
1166 careful_compare_Case :: -- checks for primitive types...
1168 -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1169 -> RdrNameHsExpr -> RdrNameHsExpr
1172 compare_Case = compare_gen_Case compare_RDR
1173 cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
1174 -- Was: compare_gen_Case cmp_eq_RDR
1176 compare_gen_Case fun lt eq gt a b
1177 = HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
1178 [mkSimpleMatch [ConPatIn ltTag_RDR []] lt Nothing mkGeneratedSrcLoc,
1179 mkSimpleMatch [ConPatIn eqTag_RDR []] eq Nothing mkGeneratedSrcLoc,
1180 mkSimpleMatch [ConPatIn gtTag_RDR []] gt Nothing mkGeneratedSrcLoc]
1183 careful_compare_Case ty lt eq gt a b
1184 = if not (isUnboxedType ty) then
1185 compare_gen_Case compare_RDR lt eq gt a b
1187 else -- we have to do something special for primitive things...
1188 HsIf (genOpApp a relevant_eq_op b)
1190 (HsIf (genOpApp a relevant_lt_op b) lt gt mkGeneratedSrcLoc)
1193 relevant_eq_op = assoc_ty_id eq_op_tbl ty
1194 relevant_lt_op = assoc_ty_id lt_op_tbl ty
1196 assoc_ty_id tyids ty
1197 = if null res then panic "assoc_ty"
1200 res = [id | (ty',id) <- tyids, ty == ty']
1203 [(charPrimTy, eqH_Char_RDR)
1204 ,(intPrimTy, eqH_Int_RDR)
1205 ,(wordPrimTy, eqH_Word_RDR)
1206 ,(addrPrimTy, eqH_Addr_RDR)
1207 ,(floatPrimTy, eqH_Float_RDR)
1208 ,(doublePrimTy, eqH_Double_RDR)
1212 [(charPrimTy, ltH_Char_RDR)
1213 ,(intPrimTy, ltH_Int_RDR)
1214 ,(wordPrimTy, ltH_Word_RDR)
1215 ,(addrPrimTy, ltH_Addr_RDR)
1216 ,(floatPrimTy, ltH_Float_RDR)
1217 ,(doublePrimTy, ltH_Double_RDR)
1220 -----------------------------------------------------------------------
1222 and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1224 and_Expr a b = genOpApp a and_RDR b
1225 append_Expr a b = genOpApp a append_RDR b
1227 -----------------------------------------------------------------------
1229 eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1231 = if not (isUnboxedType ty) then
1233 else -- we have to do something special for primitive things...
1234 genOpApp a relevant_eq_op b
1236 relevant_eq_op = assoc_ty_id eq_op_tbl ty
1240 argFieldCount :: DataCon -> Int -- Works on data and newtype constructors
1241 argFieldCount con = length (dataConRawArgTys con)
1245 untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
1246 untag_Expr tycon [] expr = expr
1247 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
1248 = HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
1249 [mkSimpleMatch [VarPatIn put_tag_here] (untag_Expr tycon more expr) Nothing mkGeneratedSrcLoc]
1252 cmp_tags_Expr :: RdrName -- Comparison op
1253 -> RdrName -> RdrName -- Things to compare
1254 -> RdrNameHsExpr -- What to return if true
1255 -> RdrNameHsExpr -- What to return if false
1258 cmp_tags_Expr op a b true_case false_case
1259 = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case mkGeneratedSrcLoc
1262 :: RdrNameHsExpr -> RdrNameHsExpr
1264 enum_from_then_to_Expr
1265 :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1268 enum_from_to_Expr f t2 = HsApp (HsApp (HsVar enumFromTo_RDR) f) t2
1269 enum_from_then_to_Expr f t t2 = HsApp (HsApp (HsApp (HsVar enumFromThenTo_RDR) f) t) t2
1271 showParen_Expr, readParen_Expr
1272 :: RdrNameHsExpr -> RdrNameHsExpr
1275 showParen_Expr e1 e2 = HsApp (HsApp (HsVar showParen_RDR) e1) e2
1276 readParen_Expr e1 e2 = HsApp (HsApp (HsVar readParen_RDR) e1) e2
1278 nested_compose_Expr :: [RdrNameHsExpr] -> RdrNameHsExpr
1280 nested_compose_Expr [e] = parenify e
1281 nested_compose_Expr (e:es)
1282 = HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
1284 -- impossible_Expr is used in case RHSs that should never happen.
1285 -- We generate these to keep the desugarer from complaining that they *might* happen!
1286 impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ "Urk! in TcGenDeriv")))
1288 -- illegal_Expr is used when signalling error conditions in the RHS of a derived
1289 -- method. It is currently only used by Enum.{succ,pred}
1290 illegal_Expr meth tp msg =
1291 HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ (meth ++ '{':tp ++ "}: " ++ msg))))
1293 -- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
1294 -- to include the value of a_RDR in the error string.
1295 illegal_toEnum_tag tp maxtag =
1296 HsApp (HsVar error_RDR)
1297 (HsApp (HsApp (HsVar append_RDR)
1298 (HsLit (HsString (_PK_ ("toEnum{" ++ tp ++ "}: tag (")))))
1299 (HsApp (HsApp (HsApp
1300 (HsVar showsPrec_RDR)
1305 (HsLit (HsString (_PK_ ") is outside of enumeration's range (0,"))))
1306 (HsApp (HsApp (HsApp
1307 (HsVar showsPrec_RDR)
1310 (HsLit (HsString (_PK_ ")")))))))
1312 parenify e@(HsVar _) = e
1313 parenify e = HsPar e
1315 -- genOpApp wraps brackets round the operator application, so that the
1316 -- renamer won't subsequently try to re-associate it.
1317 -- For some reason the renamer doesn't reassociate it right, and I can't
1318 -- be bothered to find out why just now.
1320 genOpApp e1 op e2 = mkOpApp e1 op e2
1324 qual_orig_name n = nameRdrName (getName n)
1325 varUnqual n = mkSrcUnqual varName n
1327 a_RDR = varUnqual SLIT("a")
1328 b_RDR = varUnqual SLIT("b")
1329 c_RDR = varUnqual SLIT("c")
1330 d_RDR = varUnqual SLIT("d")
1331 ah_RDR = varUnqual SLIT("a#")
1332 bh_RDR = varUnqual SLIT("b#")
1333 ch_RDR = varUnqual SLIT("c#")
1334 dh_RDR = varUnqual SLIT("d#")
1335 cmp_eq_RDR = varUnqual SLIT("cmp_eq")
1336 rangeSize_RDR = varUnqual SLIT("rangeSize")
1338 as_RDRs = [ varUnqual (_PK_ ("a"++show i)) | i <- [(1::Int) .. ] ]
1339 bs_RDRs = [ varUnqual (_PK_ ("b"++show i)) | i <- [(1::Int) .. ] ]
1340 cs_RDRs = [ varUnqual (_PK_ ("c"++show i)) | i <- [(1::Int) .. ] ]
1342 mkHsString s = HsString (_PK_ s)
1344 a_Expr = HsVar a_RDR
1345 b_Expr = HsVar b_RDR
1346 c_Expr = HsVar c_RDR
1347 d_Expr = HsVar d_RDR
1348 ltTag_Expr = HsVar ltTag_RDR
1349 eqTag_Expr = HsVar eqTag_RDR
1350 gtTag_Expr = HsVar gtTag_RDR
1351 false_Expr = HsVar false_RDR
1352 true_Expr = HsVar true_RDR
1354 con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
1356 a_Pat = VarPatIn a_RDR
1357 b_Pat = VarPatIn b_RDR
1358 c_Pat = VarPatIn c_RDR
1359 d_Pat = VarPatIn d_RDR
1361 con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
1363 con2tag_RDR tycon = varUnqual (_PK_ ("con2tag_" ++ occNameString (getOccName tycon) ++ "#"))
1364 tag2con_RDR tycon = varUnqual (_PK_ ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
1365 maxtag_RDR tycon = varUnqual (_PK_ ("maxtag_" ++ occNameString (getOccName tycon) ++ "#"))