| Copyright | (C) 2014-2017 Ryan Scott |
|---|---|
| License | BSD-style (see the file LICENSE) |
| Maintainer | Ryan Scott |
| Stability | Provisional |
| Portability | GHC |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
TextShow.TH
Description
Functions to mechanically derive TextShow, TextShow1, or TextShow2 instances,
or to splice show-related expressions into Haskell source code. You need to enable
the TemplateHaskell language extension in order to use this module.
Since: 2
Synopsis
- deriveTextShow :: Name -> Q [Dec]
- deriveTextShow1 :: Name -> Q [Dec]
- deriveTextShow2 :: Name -> Q [Dec]
- makeShowt :: Name -> Q Exp
- makeShowtl :: Name -> Q Exp
- makeShowtPrec :: Name -> Q Exp
- makeShowtlPrec :: Name -> Q Exp
- makeShowtList :: Name -> Q Exp
- makeShowtlList :: Name -> Q Exp
- makeShowb :: Name -> Q Exp
- makeShowbPrec :: Name -> Q Exp
- makeShowbList :: Name -> Q Exp
- makePrintT :: Name -> Q Exp
- makePrintTL :: Name -> Q Exp
- makeHPrintT :: Name -> Q Exp
- makeHPrintTL :: Name -> Q Exp
- makeLiftShowbPrec :: Name -> Q Exp
- makeShowbPrec1 :: Name -> Q Exp
- makeLiftShowbPrec2 :: Name -> Q Exp
- makeShowbPrec2 :: Name -> Q Exp
- data Options = Options {}
- defaultOptions :: Options
- data GenTextMethods
- deriveTextShowOptions :: Options -> Name -> Q [Dec]
- deriveTextShow1Options :: Options -> Name -> Q [Dec]
- deriveTextShow2Options :: Options -> Name -> Q [Dec]
deriveTextShow
deriveTextShow automatically generates a TextShowClass instance declaration for a data
type, newtype, or data family instance. This emulates what would (hypothetically)
happen if you could attach a deriving clause to the end of a data
declaration.TextShowClass
Here are some examples of how to derive TextShowClass for simple data types:
{-# LANGUAGE TemplateHaskell #-}
import TextShow.TH
data Letter = A | B | C
$(deriveTextShow ''Letter) -- instance TextShow Letter where ...
newtype Box a = Box a
$(deriveTextShow ''Box) -- instance TextShow a => TextShow (Box a) where ...
deriveTextShow can also be used to derive TextShowClass instances for data family
instances (which requires the -XTypeFamilies extension). To do so, pass the name of
a data or newtype instance constructor (NOT a data family name!) to deriveTextShow.
Note that the generated code may require the -XFlexibleInstances extension.
Some examples:
{-# LANGUAGE FlexibleInstances, TemplateHaskell, TypeFamilies #-}
import TextShow.TH (deriveTextShow)
class AssocClass a where
data AssocData a
instance AssocClass Int where
data AssocData Int = AssocDataInt1 Int | AssocDataInt2 Int Int
$(deriveTextShow 'AssocDataInt1) -- instance TextShow (AssocData Int) where ...
-- Alternatively, one could use $(deriveTextShow 'AssocDataInt2)
data family DataFam a b
newtype instance DataFam () b = DataFamB b
$(deriveTextShow 'DataFamB) -- instance TextShow b => TextShow (DataFam () b)
Note that at the moment, there are some limitations:
- The
Nameargument toderiveTextShowmust not be a type synonym. deriveTextShowmakes the assumption that all type variables of kind*require aTextShowClassconstraint when creating the type context. For example, if you havedata Phantom a = Phantom, then(will generatederiveTextShow''Phantom)instance, even thoughTextShowClassa =>TextShowClass(Phantom a) where ...is not required. If you want a properTextShowClassaTextShowClassinstance forPhantom, you will need to usemakeShowbPrec(see the documentation of themakefunctions for more information).deriveTextShowlacks the ability to properly detect data types with higher-kinded type parameters (e.g.,data HK f a = HK (f a)) or with kinds other than*(e.g.,data List a (empty :: Bool)). If you wish to deriveTextShowClassinstances for these data types, you will need to usemakeShowbPrec.- Some data constructors have arguments whose
TextShowClassinstance depends on a typeclass besidesTextShowClass. For example, considernewtype MyFixed a = MyFixed (Fixed a).is aFixedaTextShowClassinstance only ifais an instance of bothHasResolutionandTextShowClass. Unfortunately,deriveTextShowcannot infer thatamust be an instance ofHasResolution, so it cannot create aTextShowClassinstance forMyFixed. However, you can usemakeShowbPrecto get around this.
deriveTextShow :: Name -> Q [Dec] Source #
Generates a TextShowClass instance declaration for the given data type or data
family instance.
Since: 2
deriveTextShow1
deriveTextShow1 automatically generates a Show1 instance declaration for a data
type, newtype, or data family instance that has at least one type variable.
This emulates what would (hypothetically) happen if you could attach a deriving
clause to the end of a data declaration. Examples:TextShowClass
{-# LANGUAGE TemplateHaskell #-}
import TextShow.TH
data Stream a = Stream a (Stream a)
$(deriveTextShow1 ''Stream) -- instance TextShow1 TextStream where ...
newtype WrappedFunctor f a = WrapFunctor (f a)
$(deriveTextShow1 ''WrappedFunctor) -- instance TextShow1 f => TextShow1 (WrappedFunctor f) where ...
The same restrictions that apply to deriveTextShow also apply to deriveTextShow1,
with some caveats:
- With
deriveTextShow1, the last type variable must be of kind*. For other ones, type variables of kind*are assumed to require aTextShowClasscontext, and type variables of kind* -> *are assumed to require aTextShowClasscontext. For more complicated scenarios, usemakeLiftShowbPrec. - If using
-XDatatypeContexts, a datatype constraint cannot mention the last type variable. For example,data Ord a => Illegal a = Illegal acannot have a derivedTextShowClassinstance. - If the last type variable is used within a data field of a constructor, it must only
be used in the last argument of the data type constructor. For example,
data Legal a = Legal (Either Int a)can have a derivedTextShowClassinstance, butdata Illegal a = Illegal (Either a a)cannot. - Data family instances must be able to eta-reduce the last type variable. In other words, if you have a instance of the form:
data family Family a1 ... an t data instance Family e1 ... e2 v = ...
Then the following conditions must hold:
vmust be a type variable.vmust not be mentioned in any ofe1, ...,e2.
deriveTextShow1 :: Name -> Q [Dec] Source #
Generates a TextShowClass instance declaration for the given data type or data
family instance.
Since: 2
deriveTextShow2
deriveTextShow2 automatically generates a TextShowClass instance declaration for a data
type, newtype, or data family instance that has at least two type variables.
This emulates what would (hypothetically) happen if you could attach a deriving
clause to the end of a data declaration. Examples:TextShowClass
{-# LANGUAGE TemplateHaskell #-}
import TextShow.TH
data OneOrNone a b = OneL a | OneR b | None
$(deriveTextShow2 ''OneOrNone) -- instance TextShow2 OneOrNone where ...
newtype WrappedBifunctor f a b = WrapBifunctor (f a b)
$(deriveTextShow2 ''WrappedBifunctor) -- instance TextShow2 f => TextShow2 (WrappedBifunctor f) where ...
The same restrictions that apply to deriveTextShow and deriveTextShow1 also apply
to deriveTextShow2, with some caveats:
- With
deriveTextShow2, the last type variables must both be of kind*. For other ones, type variables of kind*are assumed to require aTextShowClassconstraint, type variables of kind* -> *are assumed to require aTextShowClassconstraint, and type variables of kind* -> * -> *are assumed to require aTextShowClassconstraint. For more complicated scenarios, usemakeLiftShowbPrec2. - If using
-XDatatypeContexts, a datatype constraint cannot mention either of the last two type variables. For example,data Ord a => Illegal a b = Illegal a bcannot have a derivedTextShowClassinstance. - If either of the last two type variables is used within a data field of a constructor,
it must only be used in the last two arguments of the data type constructor. For
example,
data Legal a b = Legal (Int, Int, a, b)can have a derivedTextShowClassinstance, butdata Illegal a b = Illegal (a, b, a, b)cannot. - Data family instances must be able to eta-reduce the last two type variables. In other words, if you have a instance of the form:
data family Family a1 ... an t1 t2 data instance Family e1 ... e2 v1 v2 = ...
Then the following conditions must hold:
v1andv2must be distinct type variables.- Neither
v1notv2must be mentioned in any ofe1, ...,e2.
deriveTextShow2 :: Name -> Q [Dec] Source #
Generates a TextShowClass instance declaration for the given data type or data
family instance.
Since: 2
make- functions
There may be scenarios in which you want to show an arbitrary data type or data
family instance without having to make the type an instance of TextShowClass. For these
cases, this modules provides several functions (all prefixed with make-) that
splice the appropriate lambda expression into your source code. Example:
This is particularly useful for creating instances for sophisticated data types. For
example, deriveTextShow cannot infer the correct type context for
newtype HigherKinded f a = HigherKinded (f a), since f is of kind * -> *.
However, it is still possible to derive a TextShowClass instance for HigherKinded
without too much trouble using makeShowbPrec:
{-# LANGUAGE FlexibleContexts, TemplateHaskell #-}
import TextShow
import TextShow.TH
instance TextShow (f a) => TextShow (HigherKinded f a) where
showbPrec = $(makeShowbPrec ''HigherKinded)
makeShowt :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showt (without requiring a
TextShowClass instance).
Since: 2
makeShowtl :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showtl (without requiring a
TextShowClass instance).
Since: 2
makeShowtPrec :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showtPrec (without requiring a
TextShowClass instance).
Since: 2
makeShowtlPrec :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showtlPrec (without
requiring a TextShowClass instance).
Since: 2
makeShowtList :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showtList (without requiring a
TextShowClass instance).
Since: 2
makeShowtlList :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showtlList (without
requiring a TextShowClass instance).
Since: 2
makeShowb :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showb (without requiring a
TextShowClass instance).
Since: 2
makeShowbPrec :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showbPrec (without requiring a
TextShowClass instance).
Since: 2
makeShowbList :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showbList (without requiring a
TextShowClass instance).
Since: 2
makePrintT :: Name -> Q Exp Source #
Generates a lambda expression which behaves like printT (without requiring a
TextShowClass instance).
Since: 2
makePrintTL :: Name -> Q Exp Source #
Generates a lambda expression which behaves like printTL (without requiring a
TextShowClass instance).
Since: 2
makeHPrintT :: Name -> Q Exp Source #
Generates a lambda expression which behaves like hPrintT (without requiring a
TextShowClass instance).
Since: 2
makeHPrintTL :: Name -> Q Exp Source #
Generates a lambda expression which behaves like hPrintTL (without
requiring a TextShowClass instance).
Since: 2
makeLiftShowbPrec :: Name -> Q Exp Source #
Generates a lambda expression which behaves like liftShowbPrec (without
requiring a TextShowClass instance).
Since: 3
makeShowbPrec1 :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showbPrec1 (without
requiring a TextShowClass instance).
Since: 2
makeLiftShowbPrec2 :: Name -> Q Exp Source #
Generates a lambda expression which behaves like liftShowbPrec2 (without
requiring a TextShowClass instance).
Since: 3
makeShowbPrec2 :: Name -> Q Exp Source #
Generates a lambda expression which behaves like showbPrec2 (without
requiring a TextShowClass instance).
Since: 2
Options
Options that specify how to derive TextShow instances using Template Haskell.
Since: 3.4
Constructors
| Options | |
Fields
| |
Instances
| Data Options Source # | |
Defined in TextShow.Options Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Options -> c Options # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Options # toConstr :: Options -> Constr # dataTypeOf :: Options -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Options) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Options) # gmapT :: (forall b. Data b => b -> b) -> Options -> Options # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Options -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Options -> r # gmapQ :: (forall d. Data d => d -> u) -> Options -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Options -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Options -> m Options # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Options -> m Options # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Options -> m Options # | |
| Generic Options Source # | |
| Read Options Source # | |
| Show Options Source # | |
| Eq Options Source # | |
| Ord Options Source # | |
| TextShow Options Source # | |
Defined in TextShow.TH Methods showbPrec :: Int -> Options -> Builder Source # showb :: Options -> Builder Source # showbList :: [Options] -> Builder Source # showtPrec :: Int -> Options -> Text Source # showt :: Options -> Text Source # showtList :: [Options] -> Text Source # showtlPrec :: Int -> Options -> Text Source # showtl :: Options -> Text Source # showtlList :: [Options] -> Text Source # | |
| Lift Options Source # | |
| type Rep Options Source # | |
Defined in TextShow.Options type Rep Options = D1 ('MetaData "Options" "TextShow.Options" "text-show-3.11.1-2CbtgHLdbN66YALlBZwYkl" 'False) (C1 ('MetaCons "Options" 'PrefixI 'True) (S1 ('MetaSel ('Just "genTextMethods") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 GenTextMethods) :*: S1 ('MetaSel ('Just "emptyCaseBehavior") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool))) | |
defaultOptions :: Options Source #
Sensible default Options.
Since: 3.4
data GenTextMethods Source #
When should Template Haskell generate implementations for the methods of
TextShow which return Text?
Since: 3.4
Constructors
| AlwaysTextMethods | Always generate them. |
| SometimesTextMethods | Only generate when |
| NeverTextMethods | Never generate them under any circumstances. |
Instances
deriveTextShowOptions :: Options -> Name -> Q [Dec] Source #
Like deriveTextShow, but takes an Options argument.
Since: 3.4
deriveTextShow1Options :: Options -> Name -> Q [Dec] Source #
Like deriveTextShow1, but takes an Options argument.
Since: 3.4
deriveTextShow2Options :: Options -> Name -> Q [Dec] Source #
Like deriveTextShow2, but takes an Options argument.
Since: 3.4
Orphan instances
| TextShow GenTextMethods Source # | |
Methods showbPrec :: Int -> GenTextMethods -> Builder Source # showb :: GenTextMethods -> Builder Source # showbList :: [GenTextMethods] -> Builder Source # showtPrec :: Int -> GenTextMethods -> Text Source # showt :: GenTextMethods -> Text Source # showtList :: [GenTextMethods] -> Text Source # showtlPrec :: Int -> GenTextMethods -> Text Source # showtl :: GenTextMethods -> Text Source # showtlList :: [GenTextMethods] -> Text Source # | |
| TextShow Options Source # | |
Methods showbPrec :: Int -> Options -> Builder Source # showb :: Options -> Builder Source # showbList :: [Options] -> Builder Source # showtPrec :: Int -> Options -> Text Source # showt :: Options -> Text Source # showtList :: [Options] -> Text Source # showtlPrec :: Int -> Options -> Text Source # showtl :: Options -> Text Source # showtlList :: [Options] -> Text Source # | |