Commit aa2c486e authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

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.
parent 04e62d08
......@@ -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:"),
......
......@@ -3742,20 +3742,17 @@ Derived instance declarations are constructed as follows. Consider the
declaration (after expansion of any type synonyms)
<programlisting>
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)
</programlisting>
where
<itemizedlist>
<listitem><para>
<literal>S</literal> is a type constructor,
The type <literal>t</literal> is an arbitrary type
</para></listitem>
<listitem><para>
The <literal>t1...tk</literal> are types,
</para></listitem>
<listitem><para>
The <literal>vk+1...vn</literal> are type variables which do not occur in any of
the <literal>ti</literal>, and
The <literal>vk+1...vn</literal> are type variables which do not occur in
<literal>t</literal>, and
</para></listitem>
<listitem><para>
The <literal>ci</literal> are partial applications of
......@@ -3773,7 +3770,7 @@ where
Then, for each <literal>ci</literal>, the derived instance
declaration is:
<programlisting>
instance ci (S t1...tk vk+1...v) => ci (T v1...vp)
instance ci (t vk+1...v) => ci (T v1...vp)
</programlisting>
where <literal>p</literal> is chosen so that <literal>T v1...vp</literal> is of the
right <emphasis>kind</emphasis> for the last parameter of class <literal>Ci</literal>.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment