diff options
author | simonpj@microsoft.com <unknown> | 2009-05-28 07:50:31 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2009-05-28 07:50:31 +0000 |
commit | 5eb2190d2aebc6e1a11780a43d31cbc7e831dd78 (patch) | |
tree | a62cb44d6938aad0ba0600c45eb3cfbdd6e36472 | |
parent | e94ca46c4a4b5522a9eb3b971b6330b3bfbe2285 (diff) | |
download | haskell-5eb2190d2aebc6e1a11780a43d31cbc7e831dd78.tar.gz |
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.
-rw-r--r-- | compiler/main/DynFlags.hs | 8 | ||||
-rw-r--r-- | compiler/typecheck/TcDeriv.lhs | 28 | ||||
-rw-r--r-- | docs/users_guide/glasgow_exts.xml | 32 |
3 files changed, 52 insertions, 16 deletions
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 3b027d8d6f..b71712bded 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -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 diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs index 545a342892..e121cc6e2e 100644 --- a/compiler/typecheck/TcDeriv.lhs +++ b/compiler/typecheck/TcDeriv.lhs @@ -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 diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index f63c90ebdb..31206017e7 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -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"> |