+ 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
+
+ toConstr (T1 _ _) = $cT1
+ toConstr T2 = $cT2
+
+ dataTypeOf _ = $dT
+
+\begin{code}
+gen_Data_binds :: FixityEnv
+ -> TyCon
+ -> (LHsBinds RdrName, -- The method bindings
+ LHsBinds RdrName) -- Auxiliary bindings
+gen_Data_binds fix_env tycon
+ = (listToBag [gfoldl_bind, fromCon_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_name = tyConName tycon
+ data_cons = tyConDataCons tycon
+
+ ------------ gfoldl
+ gfoldl_bind = mk_FunBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
+ gfoldl_eqn con = ([nlVarPat k_RDR, nlVarPat z_RDR, nlConVarPat con_name as_needed],
+ foldl mk_k_app (nlHsVar z_RDR `nlHsApp` nlHsVar con_name) as_needed)
+ where
+ con_name :: RdrName
+ con_name = getRdrName con
+ 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))
+
+ ------------ toConstr
+ toCon_bind = mk_FunBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
+ to_con_eqn dc = ([nlWildConPat dc], nlHsVar (mk_constr_name dc))
+
+ ------------ dataTypeOf
+ dataTypeOf_bind = mk_easy_FunBind tycon_loc dataTypeOf_RDR [wildPat]
+ emptyBag (nlHsVar data_type_name)
+
+ ------------ $dT
+ data_type_name = mkDerivedRdrName tycon_name mkDataTOcc
+ datatype_bind = mkVarBind tycon_loc data_type_name
+ (nlHsVar mkDataType_RDR `nlHsApp`
+ nlList constrs)
+ constrs = [nlHsVar (mk_constr_name con) | con <- data_cons]
+
+
+ ------------ $cT1 etc
+ mk_constr_name con = mkDerivedRdrName (dataConName con) mkDataCOcc
+ mk_con_bind dc = mkVarBind tycon_loc (mk_constr_name dc)
+ (nlHsApps mkConstr_RDR (constr_args dc))
+ constr_args dc = [nlHsIntLit (toInteger (dataConTag dc)), -- Tag
+ nlHsLit (mkHsString (occNameUserString dc_occ)), -- String name
+ nlHsVar fixity] -- Fixity
+ where
+ 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")
+toConstr_RDR = varQual_RDR gENERICS_Name FSLIT("toConstr")
+dataTypeOf_RDR = varQual_RDR gENERICS_Name FSLIT("dataTypeOf")
+mkConstr_RDR = varQual_RDR gENERICS_Name FSLIT("mkConstr")
+mkDataType_RDR = varQual_RDR gENERICS_Name FSLIT("mkDataType")
+conIndex_RDR = varQual_RDR gENERICS_Name FSLIT("conIndex")
+prefix_RDR = dataQual_RDR gENERICS_Name FSLIT("Prefix")
+infix_RDR = dataQual_RDR gENERICS_Name FSLIT("Infix")