import MkId ( eRROR_ID )
import PrimOp ( PrimOp(..) )
import SrcLoc ( Located(..), noLoc, srcLocSpan )
-import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
+import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon, tyConArity,
maybeTyConSingleCon, tyConFamilySize, tyConTyVars, tyConName
)
import TcType ( isUnLiftedType, tcEqType, Type )
case maybeTyConSingleCon tycon of
Just _ -> []
Nothing -> -- if cons don't match, then False
- [([wildPat, wildPat], false_Expr)]
+ [([nlWildPat, nlWildPat], false_Expr)]
else -- calc. and compare the tags
[([a_Pat, b_Pat],
untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
-- Catch this specially to avoid warnings
-- about overlapping patterns from the desugarer,
-- and to avoid unnecessary pattern-matching
- = [([wildPat,wildPat], eqTag_Expr)]
+ = [([nlWildPat,nlWildPat], eqTag_Expr)]
| otherwise
= map pats_etc nonnullary_cons ++
(if single_con_type then -- Omit wildcards when there's just one
[] -- constructor, to silence desugarer
else
- [([wildPat, wildPat], default_rhs)])
+ [([nlWildPat, nlWildPat], default_rhs)])
where
pats_etc data_con
enum_index
= mk_easy_FunBind tycon_loc index_RDR
[noLoc (AsPat (noLoc c_RDR)
- (nlTuplePat [a_Pat, wildPat] Boxed)),
+ (nlTuplePat [a_Pat, nlWildPat] Boxed)),
d_Pat] emptyBag (
nlHsIf (nlHsPar (nlHsVarApps inRange_RDR [c_RDR, d_RDR])) (
untag_Expr tycon [(a_RDR, ah_RDR)] (
pats_etc data_con
| nullary_con = -- skip the showParen junk...
ASSERT(null bs_needed)
- ([wildPat, con_pat], mk_showString_app con_str)
+ ([nlWildPat, con_pat], mk_showString_app con_str)
| otherwise =
([a_Pat, con_pat],
showParen_Expr (nlHsPar (genOpApp a_Expr ge_RDR (nlHsLit (HsInt con_prec_plus_one))))
we generate
- instance (Typeable a, Typeable b) => Typeable (T a b) where
- typeOf _ = mkTypeRep (mkTyConRep "T")
- [typeOf (undefined::a),
- typeOf (undefined::b)]
+ instance Typeable2 T where
+ typeOf2 _ = mkTyConApp (mkTyConRep "T") []
-Notice the use of lexically scoped type variables.
+We are passed the Typeable2 class as well as T
\begin{code}
gen_Typeable_binds :: TyCon -> LHsBinds RdrName
gen_Typeable_binds tycon
= unitBag $
- mk_easy_FunBind tycon_loc typeOf_RDR [wildPat] emptyBag
- (nlHsApps mkTypeRep_RDR [tycon_rep, arg_reps])
+ mk_easy_FunBind tycon_loc
+ (mk_typeOf_RDR tycon) -- Name of appropriate type0f function
+ [nlWildPat] emptyBag
+ (nlHsApps mkTypeRep_RDR [tycon_rep, nlList []])
where
tycon_loc = getSrcSpan tycon
- tyvars = tyConTyVars tycon
tycon_rep = nlHsVar mkTyConRep_RDR `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
- arg_reps = nlList (map mk tyvars)
- mk tyvar = nlHsApp (nlHsVar typeOf_RDR)
- (noLoc (ExprWithTySig (nlHsVar undefined_RDR)
- (nlHsTyVar (getRdrName tyvar))))
+
+mk_typeOf_RDR :: TyCon -> RdrName
+-- Use the arity of the TyCon to make the right typeOfn function
+mk_typeOf_RDR tycon = varQual_RDR tYPEABLE_Name (mkFastString ("typeOf" ++ suffix))
+ where
+ arity = tyConArity tycon
+ suffix | arity == 0 = ""
+ | otherwise = show arity
\end{code}
$cT1 = mkDataCon $dT "T1" Prefix
$cT2 = mkDataCon $dT "T2" Prefix
- $dT = mkDataType "Module.T" [$con_T1, $con_T2]
+ $dT = mkDataType "Module.T" [] [$con_T1, $con_T2]
+ -- the [] is for field labels.
instance (Data a, Data b) => Data (T a b) where
gfoldl k z (T1 a b) = z T `k` a `k` b
gfoldl k z T2 = z T2
-- ToDo: add gmapT,Q,M, gfoldr
-
- fromConstr c = case conIndex c of
- I# 1# -> T1 undefined undefined
- I# 2# -> T2
-
+
+ gunfold k z c = case conIndex c of
+ I# 1# -> k (k (z T1))
+ I# 2# -> z T2
+
toConstr (T1 _ _) = $cT1
toConstr T2 = $cT2
-> (LHsBinds RdrName, -- The method bindings
LHsBinds RdrName) -- Auxiliary bindings
gen_Data_binds fix_env tycon
- = (listToBag [gfoldl_bind, fromCon_bind, toCon_bind, dataTypeOf_bind],
+ = (listToBag [gfoldl_bind, gunfold_bind, toCon_bind, dataTypeOf_bind],
-- Auxiliary definitions: the data type and constructors
datatype_bind `consBag` listToBag (map mk_con_bind data_cons))
where
- tycon_loc = getSrcSpan tycon
+ tycon_loc = getSrcSpan tycon
tycon_name = tyConName tycon
- data_cons = tyConDataCons tycon
+ data_cons = tyConDataCons tycon
+ n_cons = length data_cons
+ one_constr = n_cons == 1
------------ gfoldl
gfoldl_bind = mk_FunBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
as_needed = take (dataConSourceArity con) as_RDRs
mk_k_app e v = nlHsPar (nlHsOpApp e k_RDR (nlHsVar v))
- ------------ fromConstr
- fromCon_bind = mk_FunBind tycon_loc fromConstr_RDR [([c_Pat], from_con_rhs)]
- from_con_rhs = nlHsCase (nlHsVar conIndex_RDR `nlHsApp` c_Expr)
- (map from_con_alt data_cons)
- from_con_alt dc = mkSimpleHsAlt (nlConPat intDataCon_RDR [nlLitPat (HsIntPrim (toInteger (dataConTag dc)))])
- (nlHsVarApps (getRdrName dc)
- (replicate (dataConSourceArity dc) undefined_RDR))
+ ------------ gunfold
+ gunfold_bind = mk_FunBind tycon_loc
+ gunfold_RDR
+ [([k_Pat, z_Pat, if one_constr then nlWildPat else c_Pat],
+ gunfold_rhs)]
+
+ gunfold_rhs
+ | one_constr = mk_unfold_rhs (head data_cons) -- No need for case
+ | otherwise = nlHsCase (nlHsVar conIndex_RDR `nlHsApp` c_Expr)
+ (map gunfold_alt data_cons)
+
+ gunfold_alt dc = mkSimpleHsAlt (mk_unfold_pat dc) (mk_unfold_rhs dc)
+ mk_unfold_rhs dc = foldr nlHsApp
+ (nlHsVar z_RDR `nlHsApp` nlHsVar (getRdrName dc))
+ (replicate (dataConSourceArity dc) (nlHsVar k_RDR))
+
+ mk_unfold_pat dc -- Last one is a wild-pat, to avoid
+ -- redundant test, and annoying warning
+ | tag-fIRST_TAG == n_cons-1 = nlWildPat -- Last constructor
+ | otherwise = nlConPat intDataCon_RDR [nlLitPat (HsIntPrim (toInteger tag))]
+ where
+ tag = dataConTag dc
------------ toConstr
toCon_bind = mk_FunBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
dataTypeOf_bind = mk_easy_FunBind
tycon_loc
dataTypeOf_RDR
- [wildPat]
+ [nlWildPat]
emptyBag
(nlHsVar data_type_name)
[ -- nlHsIntLit (toInteger (dataConTag dc)), -- Tag
nlHsVar data_type_name, -- DataType
nlHsLit (mkHsString (occNameUserString dc_occ)), -- String name
+ nlList labels, -- Field labels
nlHsVar fixity] -- Fixity
where
+ labels = map (nlHsLit . mkHsString . getOccString . fieldLabelName)
+ (dataConFieldLabels dc)
dc_occ = getOccName dc
is_infix = isDataSymOcc dc_occ
fixity | is_infix = infix_RDR
| otherwise = prefix_RDR
gfoldl_RDR = varQual_RDR gENERICS_Name FSLIT("gfoldl")
-fromConstr_RDR = varQual_RDR gENERICS_Name FSLIT("fromConstr")
+gunfold_RDR = varQual_RDR gENERICS_Name FSLIT("gunfold")
toConstr_RDR = varQual_RDR gENERICS_Name FSLIT("toConstr")
dataTypeOf_RDR = varQual_RDR gENERICS_Name FSLIT("dataTypeOf")
-mkConstr_RDR = varQual_RDR gENERICS_Name FSLIT("mkDataCon")
+mkConstr_RDR = varQual_RDR gENERICS_Name FSLIT("mkConstr")
mkDataType_RDR = varQual_RDR gENERICS_Name FSLIT("mkDataType")
-conIndex_RDR = varQual_RDR gENERICS_Name FSLIT("conIndex")
+conIndex_RDR = varQual_RDR gENERICS_Name FSLIT("constrIndex")
prefix_RDR = dataQual_RDR gENERICS_Name FSLIT("Prefix")
infix_RDR = dataQual_RDR gENERICS_Name FSLIT("Infix")
\end{code}
b_Pat = nlVarPat b_RDR
c_Pat = nlVarPat c_RDR
d_Pat = nlVarPat d_RDR
+k_Pat = nlVarPat k_RDR
+z_Pat = nlVarPat z_RDR
con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
-- Generates Orig s RdrName, for the binding positions