From aa2c486e51caa0386aaff0d1b866a60316500b41 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Sun, 2 Apr 2006 21:59:11 +0000 Subject: [PATCH] Improve newtype deriving Ross Paterson pointed out a useful generalisation of GHC's newtype-deriving mechanism. This implements it. The idea is to allow newtype Wrap m a = Wrap (m a) deriving (Monad, Eq) where the representation type doesn't start with a type constructor. Actually GHC already *did* implement this, but the eta-ok check in TcDeriv missed a case, so there was a lurking bug. This patches fixes the documentation too. drvrun019 tests. --- compiler/typecheck/TcDeriv.lhs | 9 +++++---- docs/users_guide/glasgow_exts.xml | 13 +++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs index 472ce6b..c31e6aa 100644 --- a/compiler/typecheck/TcDeriv.lhs +++ b/compiler/typecheck/TcDeriv.lhs @@ -44,8 +44,8 @@ import TyCon ( tyConTyVars, tyConDataCons, tyConArity, tyConHasGenerics, isEnumerationTyCon, isRecursiveTyCon, TyCon ) import TcType ( TcType, ThetaType, mkTyVarTys, mkTyConApp, tcTyConAppTyCon, - isUnLiftedType, mkClassPred, tyVarsOfTypes, isArgTypeKind, - tcEqTypes, tcSplitAppTys, mkAppTys ) + isUnLiftedType, mkClassPred, tyVarsOfType, + isArgTypeKind, tcEqTypes, tcSplitAppTys, mkAppTys ) import Var ( TyVar, tyVarKind, varName ) import VarSet ( mkVarSet, subVarSet ) import PrelNames @@ -419,7 +419,8 @@ makeDerivEqns overlap_flag tycl_decls args_to_drop = drop n_args_to_keep rep_ty_args args_to_keep = take n_args_to_keep rep_ty_args - rep_tys = tys ++ [mkAppTys rep_fn args_to_keep] + rep_fn' = mkAppTys rep_fn args_to_keep + rep_tys = tys ++ [rep_fn'] rep_pred = mkClassPred clas rep_tys -- rep_pred is the representation dictionary, from where -- we are gong to get all the methods for the newtype dictionary @@ -494,7 +495,7 @@ makeDerivEqns overlap_flag tycl_decls -- (b) the remaining type args mention -- only the remaining type variables eta_ok = (args_to_drop `tcEqTypes` mkTyVarTys tyvars_to_drop) - && (tyVarsOfTypes args_to_keep `subVarSet` mkVarSet tyvars_to_keep) + && (tyVarsOfType rep_fn' `subVarSet` mkVarSet tyvars_to_keep) cant_derive_err = derivingThingErr clas tys tycon tyvars_to_keep (vcat [ptext SLIT("even with cunning newtype deriving:"), diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index dd410c8..c1dca22 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -3742,20 +3742,17 @@ Derived instance declarations are constructed as follows. Consider the declaration (after expansion of any type synonyms) - newtype T v1...vn = T' (S t1...tk vk+1...vn) deriving (c1...cm) + newtype T v1...vn = T' (t vk+1...vn) deriving (c1...cm) where - S is a type constructor, + The type t is an arbitrary type - The t1...tk are types, - - - The vk+1...vn are type variables which do not occur in any of - the ti, and + The vk+1...vn are type variables which do not occur in + t, and The ci are partial applications of @@ -3773,7 +3770,7 @@ where Then, for each ci, the derived instance declaration is: - instance ci (S t1...tk vk+1...v) => ci (T v1...vp) + instance ci (t vk+1...v) => ci (T v1...vp) where p is chosen so that T v1...vp is of the right kind for the last parameter of class Ci. -- 1.7.10.4