+\begin{code}
+getPrec :: Bool -> FixityEnv -> Name -> Integer
+getPrec is_infix get_fixity nm
+ | not is_infix = appPrecedence
+ | otherwise = getPrecedence get_fixity nm
+
+appPrecedence :: Integer
+appPrecedence = fromIntegral maxPrecedence + 1
+ -- One more than the precedence of the most
+ -- tightly-binding operator
+
+getPrecedence :: FixityEnv -> Name -> Integer
+getPrecedence get_fixity nm
+ = case lookupFixity get_fixity nm of
+ Fixity x _ -> fromIntegral x
+
+isLRAssoc :: FixityEnv -> Name -> (Bool, Bool)
+isLRAssoc get_fixity nm =
+ case lookupFixity get_fixity nm of
+ Fixity _ InfixN -> (False, False)
+ Fixity _ InfixR -> (False, True)
+ Fixity _ InfixL -> (True, False)
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Typeable}
+%* *
+%************************************************************************
+
+From the data type
+
+ data T a b = ....
+
+we generate
+
+ instance (Typeable a, Typeable b) => Typeable (T a b) where
+ typeOf _ = mkTypeRep (mkTyConRep "T")
+ [typeOf (undefined::a),
+ typeOf (undefined::b)]
+
+Notice the use of lexically scoped type variables.
+
+\begin{code}
+gen_Typeable_binds :: TyCon -> RdrNameMonoBinds
+gen_Typeable_binds tycon
+ = mk_easy_FunMonoBind tycon_loc typeOf_RDR [wildPat] []
+ (mkHsApps mkTypeRep_RDR [tycon_rep, arg_reps])
+ where
+ tycon_loc = getSrcLoc tycon
+ tyvars = tyConTyVars tycon
+ tycon_rep = HsVar mkTyConRep_RDR `HsApp` HsLit (mkHsString (showSDoc (ppr tycon)))
+ arg_reps = ExplicitList placeHolderType (map mk tyvars)
+ mk tyvar = HsApp (HsVar typeOf_RDR)
+ (ExprWithTySig (HsVar undefined_RDR)
+ (HsTyVar (getRdrName tyvar)))
+\end{code}
+
+
+
+%************************************************************************
+%* *
+\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
+
+ 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)
+ gunfold_eqn con = ([VarPat k_RDR, VarPat z_RDR,
+ ConPatIn constr_RDR (PrefixCon [LitPat (mk_constr_string con)])],
+ apN (dataConSourceArity con)
+ (\e -> HsVar k_RDR `HsApp` e)
+ (z_Expr `HsApp` HsVar (getRdrName con)))
+ 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)