+\subsection{Data}
+%* *
+%************************************************************************
+
+From the data type
+
+ data T a b = T1 a b | T2
+
+we generate
+
+ 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
+
+ gunfold k z _ (Constr "T1") = k (k (z T1))
+ gunfold k z _ (Constr "T2") = z T2
+ gunfold _ _ e _ = e
+
+ conOf (T1 _ _) = Constr "T1"
+ conOf T2 = Constr "T2"
+
+ consOf _ = [Constr "T1", Constr "T2"]
+
+ToDo: generate auxiliary bindings for the Constrs?
+
+\begin{code}
+gen_Data_binds :: TyCon -> RdrNameMonoBinds
+gen_Data_binds tycon
+ = andMonoBindList [gfoldl_bind, gunfold_bind, conOf_bind, consOf_bind]
+ where
+ tycon_loc = getSrcLoc tycon
+ data_cons = tyConDataCons tycon
+
+ ------------ gfoldl
+ gfoldl_bind = mk_FunMonoBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
+ gfoldl_eqn con = ([VarPat k_RDR, VarPat z_RDR, mkConPat con_name as_needed],
+ foldl mk_k_app (HsVar z_RDR `HsApp` HsVar con_name) as_needed)
+ where
+ con_name :: RdrName
+ con_name = getRdrName con
+ as_needed = take (dataConSourceArity con) as_RDRs
+ mk_k_app e v = HsPar (mkHsOpApp e k_RDR (HsVar v))
+
+ ------------ gunfold
+ gunfold_bind = mk_FunMonoBind tycon_loc gunfold_RDR (map gunfold_eqn data_cons ++ [catch_all])
+ gunfold_eqn con = ([VarPat k_RDR, VarPat z_RDR, wildPat,
+ ConPatIn constr_RDR (PrefixCon [LitPat (mk_constr_string con)])],
+ apN (dataConSourceArity con)
+ (\e -> HsVar k_RDR `HsApp` e)
+ (z_Expr `HsApp` HsVar (getRdrName con)))
+ catch_all = ([wildPat, wildPat, VarPat e_RDR, wildPat], HsVar e_RDR)
+ mk_constr_string con = mkHsString (occNameUserString (getOccName con))
+
+ ------------ conOf
+ conOf_bind = mk_FunMonoBind tycon_loc conOf_RDR (map conOf_eqn data_cons)
+ conOf_eqn con = ([mkWildConPat con], mk_constr con)
+
+ ------------ consOf
+ consOf_bind = mk_easy_FunMonoBind tycon_loc consOf_RDR [wildPat] []
+ (ExplicitList placeHolderType (map mk_constr data_cons))
+ mk_constr con = HsVar constr_RDR `HsApp` (HsLit (mk_constr_string con))
+
+
+apN :: Int -> (a -> a) -> a -> a
+apN 0 k z = z
+apN n k z = apN (n-1) k (k z)
+\end{code}
+
+%************************************************************************
+%* *