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

Separate flags -XDeriveFunctor, -XDeriveFoldable, -XDeriveTraversable

See Trac #2953. This patch implements a distinct flag for each extended
class that may be automatically derived.  And I updated the user manual
to reflect the fact that we can now derive Functor, Foldable, Traversable.
parent e94ca46c
......@@ -222,9 +222,13 @@ data DynFlag
| Opt_ViewPatterns
| Opt_GADTs
| Opt_RelaxedPolyRec
| Opt_StandaloneDeriving
| Opt_DeriveDataTypeable
| Opt_DeriveFunctor
| Opt_DeriveTraversable
| Opt_DeriveFoldable
| Opt_TypeSynonymInstances
| Opt_FlexibleContexts
| Opt_FlexibleInstances
......@@ -1792,6 +1796,8 @@ xFlags = [
( "StandaloneDeriving", Opt_StandaloneDeriving, const Supported ),
( "DeriveDataTypeable", Opt_DeriveDataTypeable, const Supported ),
( "DeriveFunctor", Opt_DeriveFunctor, const Supported ),
( "DeriveTraversable", Opt_DeriveTraversable, const Supported ),
( "DeriveFoldable", Opt_DeriveFoldable, const Supported ),
( "TypeSynonymInstances", Opt_TypeSynonymInstances, const Supported ),
( "FlexibleContexts", Opt_FlexibleContexts, const Supported ),
( "FlexibleInstances", Opt_FlexibleInstances, const Supported ),
......@@ -1833,6 +1839,8 @@ glasgowExtsFlags = [
, Opt_StandaloneDeriving
, Opt_DeriveDataTypeable
, Opt_DeriveFunctor
, Opt_DeriveFoldable
, Opt_DeriveTraversable
, Opt_FlexibleContexts
, Opt_FlexibleInstances
, Opt_ConstrainedClassMethods
......
......@@ -801,11 +801,15 @@ sideConditions cls
| cls_key == enumClassKey = Just (cond_std `andCond` cond_isEnumeration)
| cls_key == ixClassKey = Just (cond_std `andCond` cond_enumOrProduct)
| cls_key == boundedClassKey = Just (cond_std `andCond` cond_enumOrProduct)
| cls_key == dataClassKey = Just (cond_mayDeriveDataTypeable `andCond` cond_std `andCond` cond_noUnliftedArgs)
| cls_key == functorClassKey = Just (cond_functorOK True) -- NB: no cond_std!
| cls_key == foldableClassKey = Just (cond_functorOK False) -- Functor/Fold/Trav works ok for rank-n types
| cls_key == traversableClassKey = Just (cond_functorOK False)
| getName cls `elem` typeableClassNames = Just (cond_mayDeriveDataTypeable `andCond` cond_typeableOK)
| cls_key == dataClassKey = Just (checkFlag Opt_DeriveDataTypeable `andCond`
cond_std `andCond` cond_noUnliftedArgs)
| cls_key == functorClassKey = Just (checkFlag Opt_DeriveFunctor `andCond`
cond_functorOK True) -- NB: no cond_std!
| cls_key == foldableClassKey = Just (checkFlag Opt_DeriveFoldable `andCond`
cond_functorOK False) -- Functor/Fold/Trav works ok for rank-n types
| cls_key == traversableClassKey = Just (checkFlag Opt_DeriveTraversable `andCond`
cond_functorOK False)
| getName cls `elem` typeableClassNames = Just (checkFlag Opt_DeriveDataTypeable `andCond` cond_typeableOK)
| otherwise = Nothing
where
cls_key = getUnique cls
......@@ -936,12 +940,16 @@ cond_functorOK allowFunctions (dflags, rep_tc)
functions = ptext (sLit "contains function types")
wrong_arg = ptext (sLit "uses the type variable in an argument other than the last")
cond_mayDeriveDataTypeable :: Condition
cond_mayDeriveDataTypeable (dflags, _)
| dopt Opt_DeriveDataTypeable dflags = Nothing
| otherwise = Just why
checkFlag :: DynFlag -> Condition
checkFlag flag (dflags, _)
| dopt flag dflags = Nothing
| otherwise = Just why
where
why = ptext (sLit "You need -XDeriveDataTypeable to derive an instance for this class")
why = ptext (sLit "You need -X") <> text flag_str
<+> ptext (sLit "to derive an instance for this class")
flag_str = case [ s | (s, f, _) <- xFlags, f==flag ] of
[s] -> s
other -> pprPanic "checkFlag" (ppr other)
std_class_via_iso :: Class -> Bool
std_class_via_iso clas -- These standard classes can be derived for a newtype
......
......@@ -2682,7 +2682,7 @@ GHC always treats the <emphasis>last</emphasis> parameter of the instance
<sect2 id="deriving-typeable">
<title>Deriving clause for classes <literal>Typeable</literal> and <literal>Data</literal></title>
<title>Deriving clause for extra classes (<literal>Typeable</literal>, <literal>Data</literal>, etc)</title>
<para>
Haskell 98 allows the programmer to add "<literal>deriving( Eq, Ord )</literal>" to a data type
......@@ -2692,11 +2692,11 @@ classes <literal>Eq</literal>, <literal>Ord</literal>,
<literal>Enum</literal>, <literal>Ix</literal>, <literal>Bounded</literal>, <literal>Read</literal>, and <literal>Show</literal>.
</para>
<para>
GHC extends this list with two more classes that may be automatically derived
(provided the <option>-XDeriveDataTypeable</option> flag is specified):
<literal>Typeable</literal>, and <literal>Data</literal>. These classes are defined in the library
modules <literal>Data.Typeable</literal> and <literal>Data.Generics</literal> respectively, and the
appropriate class must be in scope before it can be mentioned in the <literal>deriving</literal> clause.
GHC extends this list with several more classes that may be automatically derived:
<itemizedlist>
<listitem><para> With <option>-XDeriveDataTypeable</option>, you can derive instances of the classes
<literal>Typeable</literal>, and <literal>Data</literal>, defined in the library
modules <literal>Data.Typeable</literal> and <literal>Data.Generics</literal> respectively.
</para>
<para>An instance of <literal>Typeable</literal> can only be derived if the
data type has seven or fewer type parameters, all of kind <literal>*</literal>.
......@@ -2712,6 +2712,26 @@ In other cases, there is nothing to stop the programmer writing a <literal>Typab
class, whose kind suits that of the data type constructor, and
then writing the data type instance by hand.
</para>
</listitem>
<listitem><para> With <option>-XDeriveFunctor</option>, you can derive instances of
the class <literal>Functor</literal>,
defined in <literal>GHC.Base</literal>.
</para></listitem>
<listitem><para> With <option>-XDeriveFoldable</option>, you can derive instances of
the class <literal>Foldable</literal>,
defined in <literal>Data.Foldable</literal>.
</para></listitem>
<listitem><para> With <option>-XDeriveTraversable</option>, you can derive instances of
the class <literal>Traversable</literal>,
defined in <literal>Data.Traversable</literal>.
</para></listitem>
</itemizedlist>
In each case the appropriate class must be in scope before it
can be mentioned in the <literal>deriving</literal> clause.
</para>
</sect2>
<sect2 id="newtype-deriving">
......
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