content: {-# OPTIONS_GHC -Wno-noncanonical-monoid-instances #-}
  
  {-# LANGUAGE CPP                        #-}
  {-# LANGUAGE DataKinds                  #-}
  {-# LANGUAGE DeriveFunctor              #-}
  {-# LANGUAGE DeriveGeneric              #-}
  {-# LANGUAGE EmptyDataDeriving          #-}
  {-# LANGUAGE FlexibleContexts           #-}
  {-# LANGUAGE FlexibleInstances          #-}
  {-# LANGUAGE GADTs                      #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE InstanceSigs               #-}
  {-# LANGUAGE MagicHash                  #-}
  {-# LANGUAGE NoImplicitPrelude          #-}
  {-# LANGUAGE PolyKinds                  #-}
  {-# LANGUAGE ScopedTypeVariables        #-}
  {-# LANGUAGE StandaloneDeriving         #-}
  {-# LANGUAGE StandaloneKindSignatures   #-}
  {-# LANGUAGE Trustworthy                #-}
  {-# LANGUAGE TypeApplications           #-}
  {-# LANGUAGE TypeFamilies               #-}
  {-# LANGUAGE TypeOperators              #-}
  {-# LANGUAGE UndecidableInstances       #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  GHC.Internal.Generics
  -- Copyright   :  (c) Universiteit Utrecht 2010-2011, University of Oxford 2012-2014
  -- License     :  see libraries/base/LICENSE
  --
  -- Maintainer  :  libraries@haskell.org
  -- Stability   :  internal
  -- Portability :  non-portable
  --
  -- @since base-4.6.0.0
  --
  -- If you're using @GHC.Generics@, you should consider using the
  -- <http://hackage.haskell.org/package/generic-deriving> package, which
  -- contains many useful generic functions.
  
  module GHC.Internal.Generics  (
  -- * Introduction
  --
  -- |
  --
  -- Datatype-generic functions are based on the idea of converting values of
  -- a datatype @T@ into corresponding values of a (nearly) isomorphic type @'Rep' T@.
  -- The type @'Rep' T@ is
  -- built from a limited set of type constructors, all provided by this module. A
  -- datatype-generic function is then an overloaded function with instances
  -- for most of these type constructors, together with a wrapper that performs
  -- the mapping between @T@ and @'Rep' T@. By using this technique, we merely need
  -- a few generic instances in order to implement functionality that works for any
  -- representable type.
  --
  -- Representable types are collected in the 'Generic' class, which defines the
  -- associated type 'Rep' as well as conversion functions 'from' and 'to'.
  -- Typically, you will not define 'Generic' instances by hand, but have the compiler
  -- derive them for you.
  
  -- ** Representing datatypes
  --
  -- |
  --
  -- The key to defining your own datatype-generic functions is to understand how to
  -- represent datatypes using the given set of type constructors.
  --
  -- Let us look at an example first:
  --
  -- @
  -- data Tree a = Leaf a | Node (Tree a) (Tree a)
  --   deriving 'Generic'
  -- @
  --
  -- The above declaration (which requires the language pragma @DeriveGeneric@)
  -- causes the following representation to be generated:
  --
  -- @
  -- instance 'Generic' (Tree a) where
  --   type 'Rep' (Tree a) =
  --     'D1' ('MetaData \"Tree\" \"Main\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"Leaf\" 'PrefixI 'False)
  --          ('S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                 ('Rec0' a))
  --        ':+:'
  --        'C1' ('MetaCons \"Node\" 'PrefixI 'False)
  --          ('S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                ('Rec0' (Tree a))
  --           ':*:'
  --           'S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                ('Rec0' (Tree a))))
  --   ...
  -- @
  --
  -- /Hint:/ You can obtain information about the code being generated from GHC by passing
  -- the @-ddump-deriv@ flag. In GHCi, you can expand a type family such as 'Rep' using
  -- the @:kind!@ command.
  --
  -- This is a lot of information! However, most of it is actually merely meta-information
  -- that makes names of datatypes and constructors and more available on the type level.
  --
  -- Here is a reduced representation for @Tree@ with nearly all meta-information removed,
  -- for now keeping only the most essential aspects:
  --
  -- @
  -- instance 'Generic' (Tree a) where
  --   type 'Rep' (Tree a) =
  --     'Rec0' a
  --     ':+:'
  --     ('Rec0' (Tree a) ':*:' 'Rec0' (Tree a))
  -- @
  --
  -- The @Tree@ datatype has two constructors. The representation of individual constructors
  -- is combined using the binary type constructor ':+:'.
  --
  -- The first constructor consists of a single field, which is the parameter @a@. This is
  -- represented as @'Rec0' a@.
  --
  -- The second constructor consists of two fields. Each is a recursive field of type @Tree a@,
  -- represented as @'Rec0' (Tree a)@. Representations of individual fields are combined using
  -- the binary type constructor ':*:'.
  --
  -- Now let us explain the additional tags being used in the complete representation:
  --
  --    * The @'S1' ('MetaSel 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness
  --      'DecidedLazy)@ tag indicates several things. The @'Nothing@ indicates
  --      that there is no record field selector associated with this field of
  --      the constructor (if there were, it would have been marked @'Just
  --      \"recordName\"@ instead). The other types contain meta-information on
  --      the field's strictness:
  --
  --      * There is no @{\-\# UNPACK \#-\}@ or @{\-\# NOUNPACK \#-\}@ annotation
  --        in the source, so it is tagged with @'NoSourceUnpackedness@.
  --
  --      * There is no strictness (@!@) or laziness (@~@) annotation in the
  --        source, so it is tagged with @'NoSourceStrictness@.
  --
  --      * The compiler infers that the field is lazy, so it is tagged with
  --        @'DecidedLazy@. Bear in mind that what the compiler decides may be
  --        quite different from what is written in the source. See
  --        'DecidedStrictness' for a more detailed explanation.
  --
  --      The @'MetaSel@ type is also an instance of the type class 'Selector',
  --      which can be used to obtain information about the field at the value
  --      level.
  --
  --    * The @'C1' ('MetaCons \"Leaf\" 'PrefixI 'False)@ and
  --      @'C1' ('MetaCons \"Node\" 'PrefixI 'False)@ invocations indicate that the enclosed part is
  --      the representation of the first and second constructor of datatype @Tree@, respectively.
  --      Here, the meta-information regarding constructor names, fixity and whether
  --      it has named fields or not is encoded at the type level. The @'MetaCons@
  --      type is also an instance of the type class 'Constructor'. This type class can be used
  --      to obtain information about the constructor at the value level.
  --
  --    * The @'D1' ('MetaData \"Tree\" \"Main\" \"package-name\" 'False)@ tag
  --      indicates that the enclosed part is the representation of the
  --      datatype @Tree@. Again, the meta-information is encoded at the type level.
  --      The @'MetaData@ type is an instance of class 'Datatype', which
  --      can be used to obtain the name of a datatype, the module it has been
  --      defined in, the package it is located under, and whether it has been
  --      defined using @data@ or @newtype@ at the value level.
  
  -- ** Derived and fundamental representation types
  --
  -- |
  --
  -- There are many datatype-generic functions that do not distinguish between positions that
  -- are parameters or positions that are recursive calls. There are also many datatype-generic
  -- functions that do not care about the names of datatypes and constructors at all. To keep
  -- the number of cases to consider in generic functions in such a situation to a minimum,
  -- it turns out that many of the type constructors introduced above are actually synonyms,
  -- defining them to be variants of a smaller set of constructors.
  
  -- *** Individual fields of constructors: 'K1'
  --
  -- |
  --
  -- The type constructor 'Rec0' is a variant of 'K1':
  --
  -- @
  -- type 'Rec0' = 'K1' 'R'
  -- @
  --
  -- Here, 'R' is a type-level proxy that does not have any associated values.
  --
  -- There used to be another variant of 'K1' (namely @Par0@), but it has since
  -- been deprecated.
  
  -- *** Meta information: 'M1'
  --
  -- |
  --
  -- The type constructors 'S1', 'C1' and 'D1' are all variants of 'M1':
  --
  -- @
  -- type 'S1' = 'M1' 'S'
  -- type 'C1' = 'M1' 'C'
  -- type 'D1' = 'M1' 'D'
  -- @
  --
  -- The types 'S', 'C' and 'D' are once again type-level proxies, just used to create
  -- several variants of 'M1'.
  
  -- *** Additional generic representation type constructors
  --
  -- |
  --
  -- Next to 'K1', 'M1', ':+:' and ':*:' there are a few more type constructors that occur
  -- in the representations of other datatypes.
  
  -- **** Empty datatypes: 'V1'
  --
  -- |
  --
  -- For empty datatypes, 'V1' is used as a representation. For example,
  --
  -- @
  -- data Empty deriving 'Generic'
  -- @
  --
  -- yields
  --
  -- @
  -- instance 'Generic' Empty where
  --   type 'Rep' Empty =
  --     'D1' ('MetaData \"Empty\" \"Main\" \"package-name\" 'False) 'V1'
  -- @
  
  -- **** Constructors without fields: 'U1'
  --
  -- |
  --
  -- If a constructor has no arguments, then 'U1' is used as its representation. For example
  -- the representation of 'Bool' is
  --
  -- @
  -- instance 'Generic' Bool where
  --   type 'Rep' Bool =
  --     'D1' ('MetaData \"Bool\" \"Data.Bool\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"False\" 'PrefixI 'False) 'U1' ':+:' 'C1' ('MetaCons \"True\" 'PrefixI 'False) 'U1')
  -- @
  
  -- *** Representation of types with many constructors or many fields
  --
  -- |
  --
  -- As ':+:' and ':*:' are just binary operators, one might ask what happens if the
  -- datatype has more than two constructors, or a constructor with more than two
  -- fields. The answer is simple: the operators are used several times, to combine
  -- all the constructors and fields as needed. However, users /should not rely on
  -- a specific nesting strategy/ for ':+:' and ':*:' being used. The compiler is
  -- free to choose any nesting it prefers. (In practice, the current implementation
  -- tries to produce a more-or-less balanced nesting, so that the traversal of
  -- the structure of the datatype from the root to a particular component can be
  -- performed in logarithmic rather than linear time.)
  
  -- ** Defining datatype-generic functions
  --
  -- |
  --
  -- A datatype-generic function comprises two parts:
  --
  --    1. /Generic instances/ for the function, implementing it for most of the representation
  --       type constructors introduced above.
  --
  --    2. A /wrapper/ that for any datatype that is in `Generic`, performs the conversion
  --       between the original value and its `Rep`-based representation and then invokes the
  --       generic instances.
  --
  -- As an example, let us look at a function @encode@ that produces a naive, but lossless
  -- bit encoding of values of various datatypes. So we are aiming to define a function
  --
  -- @
  -- encode :: 'Generic' a => a -> [Bool]
  -- @
  --
  -- where we use 'Bool' as our datatype for bits.
  --
  -- For part 1, we define a class @Encode'@. Perhaps surprisingly, this class is parameterized
  -- over a type constructor @f@ of kind @* -> *@. This is a technicality: all the representation
  -- type constructors operate with kind @* -> *@ as base kind. But the type argument is never
  -- being used. This may be changed at some point in the future. The class has a single method,
  -- and we use the type we want our final function to have, but we replace the occurrences of
  -- the generic type argument @a@ with @f p@ (where the @p@ is any argument; it will not be used).
  --
  -- > class Encode' f where
  -- >   encode' :: f p -> [Bool]
  --
  -- With the goal in mind to make @encode@ work on @Tree@ and other datatypes, we now define
  -- instances for the representation type constructors 'V1', 'U1', ':+:', ':*:', 'K1', and 'M1'.
  
  -- *** Definition of the generic representation types
  --
  -- |
  --
  -- In order to be able to do this, we need to know the actual definitions of these types:
  --
  -- @
  -- data    'V1'        p                       -- lifted version of Empty
  -- data    'U1'        p = 'U1'                  -- lifted version of ()
  -- data    (':+:') f g p = 'L1' (f p) | 'R1' (g p) -- lifted version of 'Either'
  -- data    (':*:') f g p = (f p) ':*:' (g p)     -- lifted version of (,)
  -- newtype 'K1'    i c p = 'K1' { 'unK1' :: c }    -- a container for a c
  -- newtype 'M1'  i t f p = 'M1' { 'unM1' :: f p }  -- a wrapper
  -- @
  --
  -- So, 'U1' is just the unit type, ':+:' is just a binary choice like 'Either',
  -- ':*:' is a binary pair like the pair constructor @(,)@, and 'K1' is a value
  -- of a specific type @c@, and 'M1' wraps a value of the generic type argument,
  -- which in the lifted world is an @f p@ (where we do not care about @p@).
  
  -- *** Generic instances
  --
  -- |
  --
  -- To deal with the 'V1' case, we use the following code (which requires the pragma @EmptyCase@):
  --
  -- @
  -- instance Encode' 'V1' where
  --   encode' x = case x of { }
  -- @
  --
  -- There are no values of type @V1 p@ to pass, so it is impossible for this
  -- function to be invoked. One can ask why it is useful to define an instance
  -- for 'V1' at all in this case? Well, an empty type can be used as an argument
  -- to a non-empty type, and you might still want to encode the resulting type.
  -- As a somewhat contrived example, consider @[Empty]@, which is not an empty
  -- type, but contains just the empty list. The 'V1' instance ensures that we
  -- can call the generic function on such types.
  --
  -- There is exactly one value of type 'U1', so encoding it requires no
  -- knowledge, and we can use zero bits:
  --
  -- @
  -- instance Encode' 'U1' where
  --   encode' 'U1' = []
  -- @
  --
  -- In the case for ':+:', we produce 'False' or 'True' depending on whether
  -- the constructor of the value provided is located on the left or on the right:
  --
  -- @
  -- instance (Encode' f, Encode' g) => Encode' (f ':+:' g) where
  --   encode' ('L1' x) = False : encode' x
  --   encode' ('R1' x) = True  : encode' x
  -- @
  --
  -- (Note that this encoding strategy may not be reliable across different
  -- versions of GHC. Recall that the compiler is free to choose any nesting
  -- of ':+:' it chooses, so if GHC chooses @(a ':+:' b) ':+:' c@, then the
  -- encoding for @a@ would be @[False, False]@, @b@ would be @[False, True]@,
  -- and @c@ would be @[True]@. However, if GHC chooses @a ':+:' (b ':+:' c)@,
  -- then the encoding for @a@ would be @[False]@, @b@ would be @[True, False]@,
  -- and @c@ would be @[True, True]@.)
  --
  -- In the case for ':*:', we append the encodings of the two subcomponents:
  --
  -- @
  -- instance (Encode' f, Encode' g) => Encode' (f ':*:' g) where
  --   encode' (x ':*:' y) = encode' x ++ encode' y
  -- @
  --
  -- The case for 'K1' is rather interesting. Here, we call the final function
  -- @encode@ that we yet have to define, recursively. We will use another type
  -- class @Encode@ for that function:
  --
  -- @
  -- instance (Encode c) => Encode' ('K1' i c) where
  --   encode' ('K1' x) = encode x
  -- @
  --
  -- Note how we can define a uniform instance for 'M1', because we completely
  -- disregard all meta-information:
  --
  -- @
  -- instance (Encode' f) => Encode' ('M1' i t f) where
  --   encode' ('M1' x) = encode' x
  -- @
  --
  -- Unlike in 'K1', the instance for 'M1' refers to @encode'@, not @encode@.
  
  -- *** The wrapper and generic default
  --
  -- |
  --
  -- We now define class @Encode@ for the actual @encode@ function:
  --
  -- @
  -- class Encode a where
  --   encode :: a -> [Bool]
  --   default encode :: (Generic a, Encode' (Rep a)) => a -> [Bool]
  --   encode x = encode' ('from' x)
  -- @
  --
  -- The incoming @x@ is converted using 'from', then we dispatch to the
  -- generic instances using @encode'@. We use this as a default definition
  -- for @encode@. We need the @default encode@ signature because ordinary
  -- Haskell default methods must not introduce additional class constraints,
  -- but our generic default does.
  --
  -- Defining a particular instance is now as simple as saying
  --
  -- @
  -- instance (Encode a) => Encode (Tree a)
  -- @
  --
  -- The generic default is being used. In the future, it will hopefully be
  -- possible to use @deriving Encode@ as well, but GHC does not yet support
  -- that syntax for this situation.
  --
  -- Having @Encode@ as a class has the advantage that we can define
  -- non-generic special cases, which is particularly useful for abstract
  -- datatypes that have no structural representation. For example, given
  -- a suitable integer encoding function @encodeInt@, we can define
  --
  -- @
  -- instance Encode Int where
  --   encode = encodeInt
  -- @
  
  -- *** Omitting generic instances
  --
  -- |
  --
  -- It is not always required to provide instances for all the generic
  -- representation types, but omitting instances restricts the set of
  -- datatypes the functions will work for:
  --
  --    * If no ':+:' instance is given, the function may still work for
  --      empty datatypes or datatypes that have a single constructor,
  --      but will fail on datatypes with more than one constructor.
  --
  --    * If no ':*:' instance is given, the function may still work for
  --      datatypes where each constructor has just zero or one field,
  --      in particular for enumeration types.
  --
  --    * If no 'K1' instance is given, the function may still work for
  --      enumeration types, where no constructor has any fields.
  --
  --    * If no 'V1' instance is given, the function may still work for
  --      any datatype that is not empty.
  --
  --    * If no 'U1' instance is given, the function may still work for
  --      any datatype where each constructor has at least one field.
  --
  -- An 'M1' instance is always required (but it can just ignore the
  -- meta-information, as is the case for @encode@ above).
  #if 0
  -- *** Using meta-information
  --
  -- |
  --
  -- TODO
  #endif
  -- ** Generic constructor classes
  --
  -- |
  --
  -- Datatype-generic functions as defined above work for a large class
  -- of datatypes, including parameterized datatypes. (We have used @Tree@
  -- as our example above, which is of kind @* -> *@.) However, the
  -- 'Generic' class ranges over types of kind @*@, and therefore, the
  -- resulting generic functions (such as @encode@) must be parameterized
  -- by a generic type argument of kind @*@.
  --
  -- What if we want to define generic classes that range over type
  -- constructors (such as 'Data.Functor.Functor',
  -- 'Data.Traversable.Traversable', or 'Data.Foldable.Foldable')?
  
  -- *** The 'Generic1' class
  --
  -- |
  --
  -- Like 'Generic', there is a class 'Generic1' that defines a
  -- representation 'Rep1' and conversion functions 'from1' and 'to1',
  -- only that 'Generic1' ranges over types of kind @* -> *@. (More generally,
  -- it can range over types of kind @k -> *@, for any kind @k@, if the
  -- @PolyKinds@ extension is enabled. More on this later.)
  -- The 'Generic1' class is also derivable.
  --
  -- The representation 'Rep1' is ever so slightly different from 'Rep'.
  -- Let us look at @Tree@ as an example again:
  --
  -- @
  -- data Tree a = Leaf a | Node (Tree a) (Tree a)
  --   deriving 'Generic1'
  -- @
  --
  -- The above declaration causes the following representation to be generated:
  --
  -- @
  -- instance 'Generic1' Tree where
  --   type 'Rep1' Tree =
  --     'D1' ('MetaData \"Tree\" \"Main\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"Leaf\" 'PrefixI 'False)
  --          ('S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                'Par1')
  --        ':+:'
  --        'C1' ('MetaCons \"Node\" 'PrefixI 'False)
  --          ('S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                ('Rec1' Tree)
  --           ':*:'
  --           'S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --                ('Rec1' Tree)))
  --   ...
  -- @
  --
  -- The representation reuses 'D1', 'C1', 'S1' (and thereby 'M1') as well
  -- as ':+:' and ':*:' from 'Rep'. (This reusability is the reason that we
  -- carry around the dummy type argument for kind-@*@-types, but there are
  -- already enough different names involved without duplicating each of
  -- these.)
  --
  -- What's different is that we now use 'Par1' to refer to the parameter
  -- (and that parameter, which used to be @a@), is not mentioned explicitly
  -- by name anywhere; and we use 'Rec1' to refer to a recursive use of @Tree a@.
  
  -- *** Representation of @* -> *@ types
  --
  -- |
  --
  -- Unlike 'Rec0', the 'Par1' and 'Rec1' type constructors do not
  -- map to 'K1'. They are defined directly, as follows:
  --
  -- @
  -- newtype 'Par1'   p = 'Par1' { 'unPar1' ::   p } -- gives access to parameter p
  -- newtype 'Rec1' f p = 'Rec1' { 'unRec1' :: f p } -- a wrapper
  -- @
  --
  -- In 'Par1', the parameter @p@ is used for the first time, whereas 'Rec1' simply
  -- wraps an application of @f@ to @p@.
  --
  -- Note that 'K1' (in the guise of 'Rec0') can still occur in a 'Rep1' representation,
  -- namely when the datatype has a field that does not mention the parameter.
  --
  -- The declaration
  --
  -- @
  -- data WithInt a = WithInt Int a
  --   deriving 'Generic1'
  -- @
  --
  -- yields
  --
  -- @
  -- instance 'Generic1' WithInt where
  --   type 'Rep1' WithInt =
  --     'D1' ('MetaData \"WithInt\" \"Main\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"WithInt\" 'PrefixI 'False)
  --         ('S1' ('MetaSel 'Nothing
  --                         'NoSourceUnpackedness
  --                         'NoSourceStrictness
  --                         'DecidedLazy)
  --               ('Rec0' Int)
  --          ':*:'
  --          'S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --               'Par1'))
  -- @
  --
  -- If the parameter @a@ appears underneath a composition of other type constructors,
  -- then the representation involves composition, too:
  --
  -- @
  -- data Rose a = Fork a [Rose a]
  -- @
  --
  -- yields
  --
  -- @
  -- instance 'Generic1' Rose where
  --   type 'Rep1' Rose =
  --     'D1' ('MetaData \"Rose\" \"Main\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"Fork\" 'PrefixI 'False)
  --         ('S1' ('MetaSel 'Nothing
  --                         'NoSourceUnpackedness
  --                         'NoSourceStrictness
  --                         'DecidedLazy)
  --               'Par1'
  --          ':*:'
  --          'S1' ('MetaSel 'Nothing
  --                          'NoSourceUnpackedness
  --                          'NoSourceStrictness
  --                          'DecidedLazy)
  --               ([] ':.:' 'Rec1' Rose)))
  -- @
  --
  -- where
  --
  -- @
  -- newtype (':.:') f g p = 'Comp1' { 'unComp1' :: f (g p) }
  -- @
  
  -- *** Representation of @k -> *@ types
  --
  -- |
  --
  -- The 'Generic1' class can be generalized to range over types of kind
  -- @k -> *@, for any kind @k@. To do so, derive a 'Generic1' instance with the
  -- @PolyKinds@ extension enabled. For example, the declaration
  --
  -- @
  -- data Proxy (a :: k) = Proxy deriving 'Generic1'
  -- @
  --
  -- yields a slightly different instance depending on whether @PolyKinds@ is
  -- enabled. If compiled without @PolyKinds@, then @'Rep1' Proxy :: * -> *@, but
  -- if compiled with @PolyKinds@, then @'Rep1' Proxy :: k -> *@.
  
  -- *** Representation of unlifted types
  --
  -- |
  --
  -- If one were to attempt to derive a Generic instance for a datatype with an
  -- unlifted argument (for example, 'Int#'), one might expect the occurrence of
  -- the 'Int#' argument to be marked with @'Rec0' 'Int#'@. This won't work,
  -- though, since 'Int#' is of an unlifted kind, and 'Rec0' expects a type of
  -- kind @*@.
  --
  -- One solution would be to represent an occurrence of 'Int#' with 'Rec0 Int'
  -- instead. With this approach, however, the programmer has no way of knowing
  -- whether the 'Int' is actually an 'Int#' in disguise.
  --
  -- Instead of reusing 'Rec0', a separate data family 'URec' is used to mark
  -- occurrences of common unlifted types:
  --
  -- @
  -- data family URec a p
  --
  -- data instance 'URec' ('Ptr' ()) p = 'UAddr'   { 'uAddr#'   :: 'Addr#'   }
  -- data instance 'URec' 'Char'     p = 'UChar'   { 'uChar#'   :: 'Char#'   }
  -- data instance 'URec' 'Double'   p = 'UDouble' { 'uDouble#' :: 'Double#' }
  -- data instance 'URec' 'Int'      p = 'UFloat'  { 'uFloat#'  :: 'Float#'  }
  -- data instance 'URec' 'Float'    p = 'UInt'    { 'uInt#'    :: 'Int#'    }
  -- data instance 'URec' 'Word'     p = 'UWord'   { 'uWord#'   :: 'Word#'   }
  -- @
  --
  -- Several type synonyms are provided for convenience:
  --
  -- @
  -- type 'UAddr'   = 'URec' ('Ptr' ())
  -- type 'UChar'   = 'URec' 'Char'
  -- type 'UDouble' = 'URec' 'Double'
  -- type 'UFloat'  = 'URec' 'Float'
  -- type 'UInt'    = 'URec' 'Int'
  -- type 'UWord'   = 'URec' 'Word'
  -- @
  --
  -- The declaration
  --
  -- @
  -- data IntHash = IntHash Int#
  --   deriving 'Generic'
  -- @
  --
  -- yields
  --
  -- @
  -- instance 'Generic' IntHash where
  --   type 'Rep' IntHash =
  --     'D1' ('MetaData \"IntHash\" \"Main\" \"package-name\" 'False)
  --       ('C1' ('MetaCons \"IntHash\" 'PrefixI 'False)
  --         ('S1' ('MetaSel 'Nothing
  --                         'NoSourceUnpackedness
  --                         'NoSourceStrictness
  --                         'DecidedLazy)
  --               'UInt'))
  -- @
  --
  -- Currently, only the six unlifted types listed above are generated, but this
  -- may be extended to encompass more unlifted types in the future.
  #if 0
  -- *** Limitations
  --
  -- |
  --
  -- /TODO/
  --
  -- /TODO:/ Also clear up confusion about 'Rec0' and 'Rec1' not really indicating recursion.
  --
  #endif
  -----------------------------------------------------------------------------
  
    -- * Generic representation types
      V1, U1(..), Par1(..), Rec1(..), K1(..), M1(..)
    , (:+:)(..), (:*:)(..), (:.:)(..)
  
    -- ** Unboxed representation types
    , URec(..)
    , type UAddr, type UChar, type UDouble
    , type UFloat, type UInt, type UWord
  
    -- ** Synonyms for convenience
    , Rec0, R
    , D1, C1, S1, D, C, S
  
    -- * Meta-information
    , Datatype(..), Constructor(..), Selector(..)
    , Fixity(..), FixityI(..), Associativity(..), prec
    , SourceUnpackedness(..), SourceStrictness(..), DecidedStrictness(..)
    , Meta(..)
  
    -- * Generic type classes
    , Generic(..)
    , Generic1(..)
  
    -- * Generic wrapper
    , Generically(..)
    , Generically1(..)
    ) where
  
  -- We use some base types
  import GHC.Internal.Data.Either     ( Either (..) )
  import GHC.Internal.Data.Maybe      ( Maybe(..), fromMaybe )
  import GHC.Internal.Data.Ord        ( Down(..) )
  import GHC.Internal.Bignum.Integer ( Integer, integerToInt )
  import GHC.Internal.Prim        ( Addr#, Char#, Double#, Float#, Int#, Word# )
  import GHC.Internal.Ptr         ( Ptr(..) )
  import GHC.Internal.Types
  
  -- Needed for instances
  import GHC.Internal.Ix      ( Ix )
  import GHC.Internal.Base    ( Alternative(..), Applicative(..), Functor(..)
                     , Monad(..), MonadPlus(..), NonEmpty(..), String, coerce
                     , Semigroup(..), Monoid(..), Void )
  import GHC.Internal.Classes ( Eq(..), Ord(..) )
  import GHC.Internal.Enum    ( Bounded, Enum )
  import GHC.Internal.Read    ( Read(..) )
  import GHC.Internal.Show    ( Show(..), showString, showChar, showParen, appPrec )
  import GHC.Internal.Stack.Types ( SrcLoc(..) )
  import GHC.Internal.Tuple   (Solo (..))
  import GHC.Internal.Unicode ( GeneralCategory(..) )
  import GHC.Internal.Fingerprint.Type ( Fingerprint(..) )
  
  -- Needed for metadata
  import GHC.Internal.Data.Proxy   ( Proxy(..) )
  import GHC.Internal.TypeLits ( KnownSymbol, KnownNat, Nat, symbolVal, natVal )
  
  --------------------------------------------------------------------------------
  -- Representation types
  --------------------------------------------------------------------------------
  
  -- | Void: used for datatypes without constructors
  data V1 (p :: k)
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Read     -- ^ @since base-4.9.0.0
             , Show     -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.12.0.0
  instance Semigroup (V1 p) where
    v <> _ = v
  
  -- | Unit: used for constructors without arguments
  data U1 (p :: k) = U1
    deriving ( Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.9.0.0
  instance Eq (U1 p) where
    _ == _ = True
  
  -- | @since base-4.7.0.0
  instance Ord (U1 p) where
    compare _ _ = EQ
  
  -- | @since base-4.9.0.0
  deriving instance Read (U1 p)
  
  -- | @since base-4.9.0.0
  instance Show (U1 p) where
    showsPrec _ _ = showString "U1"
  
  -- | @since base-4.9.0.0
  instance Functor U1 where
    fmap _ _ = U1
  
  -- | @since base-4.9.0.0
  instance Applicative U1 where
    pure _ = U1
    _ <*> _ = U1
    liftA2 _ _ _ = U1
  
  -- | @since base-4.9.0.0
  instance Alternative U1 where
    empty = U1
    _ <|> _ = U1
  
  -- | @since base-4.9.0.0
  instance Monad U1 where
    _ >>= _ = U1
  
  -- | @since base-4.9.0.0
  instance MonadPlus U1
  
  -- | @since base-4.12.0.0
  instance Semigroup (U1 p) where
    _ <> _ = U1
  
  -- | @since base-4.12.0.0
  instance Monoid (U1 p) where
    mempty = U1
  
  -- | Used for marking occurrences of the parameter
  newtype Par1 p = Par1 { unPar1 :: p }
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.9.0.0
  instance Applicative Par1 where
    pure = Par1
    (<*>) = coerce
    liftA2 = coerce
  
  -- | @since base-4.9.0.0
  instance Monad Par1 where
    Par1 x >>= f = f x
  
  -- | @since base-4.12.0.0
  deriving instance Semigroup p => Semigroup (Par1 p)
  
  -- | @since base-4.12.0.0
  deriving instance Monoid p => Monoid (Par1 p)
  
  -- | Recursive calls of kind @* -> *@ (or kind @k -> *@, when @PolyKinds@
  -- is enabled)
  newtype Rec1 (f :: k -> Type) (p :: k) = Rec1 { unRec1 :: f p }
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.9.0.0
  deriving instance Applicative f => Applicative (Rec1 f)
  
  -- | @since base-4.9.0.0
  deriving instance Alternative f => Alternative (Rec1 f)
  
  -- | @since base-4.9.0.0
  instance Monad f => Monad (Rec1 f) where
    Rec1 x >>= f = Rec1 (x >>= \a -> unRec1 (f a))
  
  -- | @since base-4.9.0.0
  deriving instance MonadPlus f => MonadPlus (Rec1 f)
  
  -- | @since base-4.12.0.0
  deriving instance Semigroup (f p) => Semigroup (Rec1 f p)
  
  -- | @since base-4.12.0.0
  deriving instance Monoid (f p) => Monoid (Rec1 f p)
  
  -- | Constants, additional parameters and recursion of kind @*@
  newtype K1 (i :: Type) c (p :: k) = K1 { unK1 :: c }
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.12.0.0
  instance Monoid c => Applicative (K1 i c) where
    pure _ = K1 mempty
    liftA2 = \_ -> coerce (mappend :: c -> c -> c)
    (<*>) = coerce (mappend :: c -> c -> c)
  
  -- | @since base-4.12.0.0
  deriving instance Semigroup c => Semigroup (K1 i c p)
  
  -- | @since base-4.12.0.0
  deriving instance Monoid c => Monoid (K1 i c p)
  
  -- | @since base-4.9.0.0
  deriving instance Applicative f => Applicative (M1 i c f)
  
  -- | @since base-4.9.0.0
  deriving instance Alternative f => Alternative (M1 i c f)
  
  -- | @since base-4.9.0.0
  deriving instance Monad f => Monad (M1 i c f)
  
  -- | @since base-4.9.0.0
  deriving instance MonadPlus f => MonadPlus (M1 i c f)
  
  -- | @since base-4.12.0.0
  deriving instance Semigroup (f p) => Semigroup (M1 i c f p)
  
  -- | @since base-4.12.0.0
  deriving instance Monoid (f p) => Monoid (M1 i c f p)
  
  -- | Meta-information (constructor names, etc.)
  newtype M1 (i :: Type) (c :: Meta) (f :: k -> Type) (p :: k) =
      M1 { unM1 :: f p }
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Sums: encode choice between constructors
  infixr 5 :+:
  data (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k) = L1 (f p) | R1 (g p)
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Products: encode multiple arguments to constructors
  infixr 6 :*:
  data (:*:) (f :: k -> Type) (g :: k -> Type) (p :: k) = f p :*: g p
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.9.0.0
  instance (Applicative f, Applicative g) => Applicative (f :*: g) where
    pure a = pure a :*: pure a
    (f :*: g) <*> (x :*: y) = (f <*> x) :*: (g <*> y)
    liftA2 f (a :*: b) (x :*: y) = liftA2 f a x :*: liftA2 f b y
  
  -- | @since base-4.9.0.0
  instance (Alternative f, Alternative g) => Alternative (f :*: g) where
    empty = empty :*: empty
    (x1 :*: y1) <|> (x2 :*: y2) = (x1 <|> x2) :*: (y1 <|> y2)
  
  -- | @since base-4.9.0.0
  instance (Monad f, Monad g) => Monad (f :*: g) where
    (m :*: n) >>= f = (m >>= \a -> fstP (f a)) :*: (n >>= \a -> sndP (f a))
      where
        fstP (a :*: _) = a
        sndP (_ :*: b) = b
  
  -- | @since base-4.9.0.0
  instance (MonadPlus f, MonadPlus g) => MonadPlus (f :*: g)
  
  -- | @since base-4.12.0.0
  instance (Semigroup (f p), Semigroup (g p)) => Semigroup ((f :*: g) p) where
    (x1 :*: y1) <> (x2 :*: y2) = (x1 <> x2) :*: (y1 <> y2)
  
  -- | @since base-4.12.0.0
  instance (Monoid (f p), Monoid (g p)) => Monoid ((f :*: g) p) where
    mempty = mempty :*: mempty
  
  -- | Composition of functors
  infixr 7 :.:
  newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) =
      Comp1 { unComp1 :: f (g p) }
    deriving ( Eq       -- ^ @since base-4.7.0.0
             , Ord      -- ^ @since base-4.7.0.0
             , Read     -- ^ @since base-4.7.0.0
             , Show     -- ^ @since base-4.7.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.9.0.0
  instance (Applicative f, Applicative g) => Applicative (f :.: g) where
    pure x = Comp1 (pure (pure x))
    Comp1 f <*> Comp1 x = Comp1 (liftA2 (<*>) f x)
    liftA2 f (Comp1 x) (Comp1 y) = Comp1 (liftA2 (liftA2 f) x y)
  
  -- | @since base-4.9.0.0
  instance (Alternative f, Applicative g) => Alternative (f :.: g) where
    empty = Comp1 empty
    (<|>) = coerce ((<|>) :: f (g a) -> f (g a) -> f (g a)) ::
      forall a . (f :.: g) a -> (f :.: g) a -> (f :.: g) a
  
  -- | @since base-4.12.0.0
  deriving instance Semigroup (f (g p)) => Semigroup ((f :.: g) p)
  
  -- | @since base-4.12.0.0
  deriving instance Monoid (f (g p)) => Monoid ((f :.: g) p)
  
  -- | Constants of unlifted kinds
  --
  -- @since base-4.9.0.0
  data family URec (a :: Type) (p :: k)
  
  -- | Used for marking occurrences of 'Addr#'
  --
  -- @since base-4.9.0.0
  data instance URec (Ptr ()) (p :: k) = UAddr { uAddr# :: Addr# }
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | @since base-4.21.0.0
  instance Show (UAddr p) where
    -- This Show instance would be equivalent to what deriving Show would generate,
    -- but because deriving Show doesn't support Addr# fields we define it manually.
    showsPrec d (UAddr x) =
      showParen (d > appPrec)
        (\y -> showString "UAddr {uAddr# = " (showsPrec 0 (Ptr x) (showChar '}' y)))
  
  -- | Used for marking occurrences of 'Char#'
  --
  -- @since base-4.9.0.0
  data instance URec Char (p :: k) = UChar { uChar# :: Char# }
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Show     -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Used for marking occurrences of 'Double#'
  --
  -- @since base-4.9.0.0
  data instance URec Double (p :: k) = UDouble { uDouble# :: Double# }
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Show     -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Used for marking occurrences of 'Float#'
  --
  -- @since base-4.9.0.0
  data instance URec Float (p :: k) = UFloat { uFloat# :: Float# }
    deriving ( Eq, Ord, Show
             , Functor  -- ^ @since base-4.9.0.0
             , Generic
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Used for marking occurrences of 'Int#'
  --
  -- @since base-4.9.0.0
  data instance URec Int (p :: k) = UInt { uInt# :: Int# }
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Show     -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Used for marking occurrences of 'Word#'
  --
  -- @since base-4.9.0.0
  data instance URec Word (p :: k) = UWord { uWord# :: Word# }
    deriving ( Eq       -- ^ @since base-4.9.0.0
             , Ord      -- ^ @since base-4.9.0.0
             , Show     -- ^ @since base-4.9.0.0
             , Functor  -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.9.0.0
             , Generic1 -- ^ @since base-4.9.0.0
             )
  
  -- | Type synonym for @'URec' 'Addr#'@
  --
  -- @since base-4.9.0.0
  type UAddr   = URec (Ptr ())
  -- | Type synonym for @'URec' 'Char#'@
  --
  -- @since base-4.9.0.0
  type UChar   = URec Char
  
  -- | Type synonym for @'URec' 'Double#'@
  --
  -- @since base-4.9.0.0
  type UDouble = URec Double
  
  -- | Type synonym for @'URec' 'Float#'@
  --
  -- @since base-4.9.0.0
  type UFloat  = URec Float
  
  -- | Type synonym for @'URec' 'Int#'@
  --
  -- @since base-4.9.0.0
  type UInt    = URec Int
  
  -- | Type synonym for @'URec' 'Word#'@
  --
  -- @since base-4.9.0.0
  type UWord   = URec Word
  
  -- | Tag for K1: recursion (of kind @Type@)
  data R
  
  -- | Type synonym for encoding recursion (of kind @Type@)
  type Rec0  = K1 R
  
  -- | Tag for M1: datatype
  data D
  -- | Tag for M1: constructor
  data C
  -- | Tag for M1: record selector
  data S
  
  -- | Type synonym for encoding meta-information for datatypes
  type D1 = M1 D
  
  -- | Type synonym for encoding meta-information for constructors
  type C1 = M1 C
  
  -- | Type synonym for encoding meta-information for record selectors
  type S1 = M1 S
  
  -- | Class for datatypes that represent datatypes
  class Datatype d where
    -- | The name of the datatype (unqualified)
    datatypeName :: t d (f :: k -> Type) (a :: k) -> [Char]
    -- | The fully-qualified name of the module where the type is declared
    moduleName   :: t d (f :: k -> Type) (a :: k) -> [Char]
    -- | The package name of the module where the type is declared
    --
    -- @since base-4.9.0.0
    packageName :: t d (f :: k -> Type) (a :: k) -> [Char]
    -- | Marks if the datatype is actually a newtype
    --
    -- @since base-4.7.0.0
    isNewtype    :: t d (f :: k -> Type) (a :: k) -> Bool
    isNewtype _ = False
  
  -- | @since base-4.9.0.0
  instance (KnownSymbol n, KnownSymbol m, KnownSymbol p, SingI nt)
      => Datatype ('MetaData n m p nt) where
    datatypeName _ = symbolVal (Proxy :: Proxy n)
    moduleName   _ = symbolVal (Proxy :: Proxy m)
    packageName  _ = symbolVal (Proxy :: Proxy p)
    isNewtype    _ = fromSing  (sing  :: Sing nt)
  
  -- | Class for datatypes that represent data constructors
  class Constructor c where
    -- | The name of the constructor
    conName :: t c (f :: k -> Type) (a :: k) -> [Char]
  
    -- | The fixity of the constructor
    conFixity :: t c (f :: k -> Type) (a :: k) -> Fixity
    conFixity _ = Prefix
  
    -- | Marks if this constructor is a record
    conIsRecord :: t c (f :: k -> Type) (a :: k) -> Bool
    conIsRecord _ = False
  
  -- | @since base-4.9.0.0
  instance (KnownSymbol n, SingI f, SingI r)
      => Constructor ('MetaCons n f r) where
    conName     _ = symbolVal (Proxy :: Proxy n)
    conFixity   _ = fromSing  (sing  :: Sing f)
    conIsRecord _ = fromSing  (sing  :: Sing r)
  
  -- | Datatype to represent the fixity of a constructor. An infix
  -- | declaration directly corresponds to an application of 'Infix'.
  data Fixity = Prefix | Infix Associativity Int
    deriving ( Eq       -- ^ @since base-4.6.0.0
             , Show     -- ^ @since base-4.6.0.0
             , Ord      -- ^ @since base-4.6.0.0
             , Read     -- ^ @since base-4.6.0.0
             , Generic  -- ^ @since base-4.7.0.0
             )
  
  -- | This variant of 'Fixity' appears at the type level.
  --
  -- @since base-4.9.0.0
  data FixityI = PrefixI | InfixI Associativity Nat
  
  -- | Get the precedence of a fixity value.
  prec :: Fixity -> Int
  prec Prefix      = 10
  prec (Infix _ n) = n
  
  -- | Datatype to represent the associativity of a constructor
  data Associativity = LeftAssociative
                     | RightAssociative
                     | NotAssociative
    deriving ( Eq       -- ^ @since base-4.6.0.0
             , Show     -- ^ @since base-4.6.0.0
             , Ord      -- ^ @since base-4.6.0.0
             , Read     -- ^ @since base-4.6.0.0
             , Enum     -- ^ @since base-4.9.0.0
             , Bounded  -- ^ @since base-4.9.0.0
             , Ix       -- ^ @since base-4.9.0.0
             , Generic  -- ^ @since base-4.7.0.0
             )
  
  -- | The unpackedness of a field as the user wrote it in the source code. For
  -- example, in the following data type:
  --
  -- @
  -- data E = ExampleConstructor     Int
  --            {\-\# NOUNPACK \#-\} Int
  --            {\-\#   UNPACK \#-\} Int
  -- @
  --
  -- The fields of @ExampleConstructor@ have 'NoSourceUnpackedness',
  -- 'SourceNoUnpack', and 'SourceUnpack', respectively.
  --
  -- @since base-4.9.0.0
  data SourceUnpackedness = NoSourceUnpackedness
                          | SourceNoUnpack
                          | SourceUnpack
    deriving ( Eq      -- ^ @since base-4.9.0.0
             , Show    -- ^ @since base-4.9.0.0
             , Ord     -- ^ @since base-4.9.0.0
             , Read    -- ^ @since base-4.9.0.0
             , Enum    -- ^ @since base-4.9.0.0
             , Bounded -- ^ @since base-4.9.0.0
             , Ix      -- ^ @since base-4.9.0.0
             , Generic -- ^ @since base-4.9.0.0
             )
  
  -- | The strictness of a field as the user wrote it in the source code. For
  -- example, in the following data type:
  --
  -- @
  -- data E = ExampleConstructor Int ~Int !Int
  -- @
  --
  -- The fields of @ExampleConstructor@ have 'NoSourceStrictness',
  -- 'SourceLazy', and 'SourceStrict', respectively.
  --
  -- @since base-4.9.0.0
  data SourceStrictness = NoSourceStrictness
                        | SourceLazy
                        | SourceStrict
    deriving ( Eq      -- ^ @since base-4.9.0.0
             , Show    -- ^ @since base-4.9.0.0
             , Ord     -- ^ @since base-4.9.0.0
             , Read    -- ^ @since base-4.9.0.0
             , Enum    -- ^ @since base-4.9.0.0
             , Bounded -- ^ @since base-4.9.0.0
             , Ix      -- ^ @since base-4.9.0.0
             , Generic -- ^ @since base-4.9.0.0
             )
  
  -- | The strictness that GHC infers for a field during compilation. Whereas
  -- there are nine different combinations of 'SourceUnpackedness' and
  -- 'SourceStrictness', the strictness that GHC decides will ultimately be one
  -- of lazy, strict, or unpacked. What GHC decides is affected both by what the
  -- user writes in the source code and by GHC flags. As an example, consider
  -- this data type:
  --
  -- @
  -- data E = ExampleConstructor {\-\# UNPACK \#-\} !Int !Int Int
  -- @
  --
  -- * If compiled without optimization or other language extensions, then the
  --   fields of @ExampleConstructor@ will have 'DecidedStrict', 'DecidedStrict',
  --   and 'DecidedLazy', respectively.
  --
  -- * If compiled with @-XStrictData@ enabled, then the fields will have
  --   'DecidedStrict', 'DecidedStrict', and 'DecidedStrict', respectively.
  --
  -- * If compiled with @-O2@ enabled, then the fields will have 'DecidedUnpack',
  --   'DecidedStrict', and 'DecidedLazy', respectively.
  --
  -- @since base-4.9.0.0
  data DecidedStrictness = DecidedLazy
                         | DecidedStrict
                         | DecidedUnpack
    deriving ( Eq      -- ^ @since base-4.9.0.0
             , Show    -- ^ @since base-4.9.0.0
             , Ord     -- ^ @since base-4.9.0.0
             , Read    -- ^ @since base-4.9.0.0
             , Enum    -- ^ @since base-4.9.0.0
             , Bounded -- ^ @since base-4.9.0.0
             , Ix      -- ^ @since base-4.9.0.0
             , Generic -- ^ @since base-4.9.0.0
             )
  
  -- | Class for datatypes that represent records
  class Selector s where
    -- | The name of the selector
    selName :: t s (f :: k -> Type) (a :: k) -> [Char]
    -- | The selector's unpackedness annotation (if any)
    --
    -- @since base-4.9.0.0
    selSourceUnpackedness :: t s (f :: k -> Type) (a :: k) -> SourceUnpackedness
    -- | The selector's strictness annotation (if any)
    --
    -- @since base-4.9.0.0
    selSourceStrictness :: t s (f :: k -> Type) (a :: k) -> SourceStrictness
    -- | The strictness that the compiler inferred for the selector
    --
    -- @since base-4.9.0.0
    selDecidedStrictness :: t s (f :: k -> Type) (a :: k) -> DecidedStrictness
  
  -- | @since base-4.9.0.0
  instance (SingI mn, SingI su, SingI ss, SingI ds)
      => Selector ('MetaSel mn su ss ds) where
    selName _ = fromMaybe "" (fromSing (sing :: Sing mn))
    selSourceUnpackedness _ = fromSing (sing :: Sing su)
    selSourceStrictness   _ = fromSing (sing :: Sing ss)
    selDecidedStrictness  _ = fromSing (sing :: Sing ds)
  
  -- | Representable types of kind @*@.
  -- This class is derivable in GHC with the @DeriveGeneric@ flag on.
  --
  -- A 'Generic' instance must satisfy the following laws:
  --
  -- @
  -- 'from' . 'to' ≡ 'Prelude.id'
  -- 'to' . 'from' ≡ 'Prelude.id'
  -- @
  class Generic a where
    -- | Generic representation type
    type Rep a :: Type -> Type
    -- | Convert from the datatype to its representation
    from  :: a -> (Rep a) x
    -- | Convert from the representation to the datatype
    to    :: (Rep a) x -> a
  
  
  -- | Representable types of kind @* -> *@ (or kind @k -> *@, when @PolyKinds@
  -- is enabled).
  -- This class is derivable in GHC with the @DeriveGeneric@ flag on.
  --
  -- A 'Generic1' instance must satisfy the following laws:
  --
  -- @
  -- 'from1' . 'to1' ≡ 'Prelude.id'
  -- 'to1' . 'from1' ≡ 'Prelude.id'
  -- @
  class Generic1 (f :: k -> Type) where
    -- | Generic representation type
    type Rep1 f :: k -> Type
    -- | Convert from the datatype to its representation
    from1  :: f a -> (Rep1 f) a
    -- | Convert from the representation to the datatype
    to1    :: (Rep1 f) a -> f a
  
  --------------------------------------------------------------------------------
  -- 'Generic' wrapper
  --------------------------------------------------------------------------------
  
  -- | A datatype whose instances are defined generically, using the
  -- 'Generic' representation. 'Generically1' is a higher-kinded version
  -- of 'Generically' that uses 'Generic1'.
  --
  -- Generic instances can be derived via @'Generically' A@ using
  -- @-XDerivingVia@.
  --
  -- @
  -- {-# LANGUAGE DeriveGeneric      #-}
  -- {-# LANGUAGE DerivingStrategies #-}
  -- {-# LANGUAGE DerivingVia        #-}
  --
  -- import GHC.Generics (Generic)
  --
  -- data V4 a = V4 a a a a
  --   deriving stock Generic
  --
  --   deriving (Semigroup, Monoid)
  --   via Generically (V4 a)
  -- @
  --
  -- This corresponds to 'Semigroup' and 'Monoid' instances defined by
  -- pointwise lifting:
  --
  -- @
  -- instance Semigroup a => Semigroup (V4 a) where
  --   (<>) :: V4 a -> V4 a -> V4 a
  --   V4 a1 b1 c1 d1 <> V4 a2 b2 c2 d2 =
  --     V4 (a1 <> a2) (b1 <> b2) (c1 <> c2) (d1 <> d2)
  --
  -- instance Monoid a => Monoid (V4 a) where
  --   mempty :: V4 a
  --   mempty = V4 mempty mempty mempty mempty
  -- @
  --
  -- Historically this required modifying the type class to include
  -- generic method definitions (@-XDefaultSignatures@) and deriving it
  -- with the @anyclass@ strategy (@-XDeriveAnyClass@). Having a /via
  -- type/ like 'Generically' decouples the instance from the type
  -- class.
  --
  -- @since base-4.17.0.0
  newtype Generically a = Generically a
  
  -- | @since base-4.17.0.0
  instance (Generic a, Semigroup (Rep a ())) => Semigroup (Generically a) where
    (<>) :: Generically a -> Generically a -> Generically a
    Generically a <> Generically b = Generically (to (from a <> from b :: Rep a ()))
  
  -- | @since base-4.17.0.0
  instance (Generic a, Monoid (Rep a ())) => Monoid (Generically a) where
    mempty :: Generically a
    mempty = Generically (to (mempty :: Rep a ()))
  
    mappend :: Generically a -> Generically a -> Generically a
    mappend = (<>)
  
  -- | A type whose instances are defined generically, using the
  -- 'Generic1' representation. 'Generically1' is a higher-kinded
  -- version of 'Generically' that uses 'Generic'.
  --
  -- Generic instances can be derived for type constructors via
  -- @'Generically1' F@ using @-XDerivingVia@.
  --
  -- @
  -- {-# LANGUAGE DeriveGeneric      #-}
  -- {-# LANGUAGE DerivingStrategies #-}
  -- {-# LANGUAGE DerivingVia        #-}
  --
  -- import GHC.Generics (Generic)
  --
  -- data V4 a = V4 a a a a
  --   deriving stock (Functor, Generic1)
  --
  --   deriving Applicative
  --   via Generically1 V4
  -- @
  --
  -- This corresponds to 'Applicative' instances defined by pointwise
  -- lifting:
  --
  -- @
  -- instance Applicative V4 where
  --   pure :: a -> V4 a
  --   pure a = V4 a a a a
  --
  --   liftA2 :: (a -> b -> c) -> (V4 a -> V4 b -> V4 c)
  --   liftA2 (·) (V4 a1 b1 c1 d1) (V4 a2 b2 c2 d2) =
  --     V4 (a1 · a2) (b1 · b2) (c1 · c2) (d1 · d2)
  -- @
  --
  -- Historically this required modifying the type class to include
  -- generic method definitions (@-XDefaultSignatures@) and deriving it
  -- with the @anyclass@ strategy (@-XDeriveAnyClass@). Having a /via
  -- type/ like 'Generically1' decouples the instance from the type
  -- class.
  --
  -- @since base-4.17.0.0
  type    Generically1 :: forall k. (k -> Type) -> (k -> Type)
  newtype Generically1 f a where
    Generically1 :: forall {k} f a. f a -> Generically1 @k f a
  
  -- | @since base-4.18.0.0
  instance (Generic1 f, Eq (Rep1 f a)) => Eq (Generically1 f a) where
     Generically1 x == Generically1 y = from1 x == from1 y
     Generically1 x /= Generically1 y = from1 x /= from1 y
  
  -- | @since base-4.18.0.0
  instance (Generic1 f, Ord (Rep1 f a)) => Ord (Generically1 f a) where
     Generically1 x `compare` Generically1 y = from1 x `compare` from1 y
  
  -- | @since base-4.17.0.0
  instance (Generic1 f, Functor (Rep1 f)) => Functor (Generically1 f) where
    fmap :: (a -> a') -> (Generically1 f a -> Generically1 f a')
    fmap f (Generically1 as) = Generically1
      (to1 (fmap f (from1 as)))
  
    (<$) :: a -> Generically1 f b -> Generically1 f a
    a <$ Generically1 as = Generically1
      (to1 (a <$ from1 as))
  
  -- | @since base-4.17.0.0
  instance (Generic1 f, Applicative (Rep1 f)) => Applicative (Generically1 f) where
    pure :: a -> Generically1 f a
    pure a = Generically1
      (to1 (pure a))
  
    (<*>) :: Generically1 f (a1 -> a2) -> Generically1 f a1 -> Generically1 f a2
    Generically1 fs <*> Generically1 as = Generically1
      (to1 (from1 fs <*> from1 as))
  
    liftA2 :: (a1 -> a2 -> a3)
           -> (Generically1 f a1 -> Generically1 f a2 -> Generically1 f a3)
    liftA2 (·) (Generically1 as) (Generically1 bs) = Generically1
      (to1 (liftA2 (·) (from1 as) (from1 bs)))
  
  -- | @since base-4.17.0.0
  instance (Generic1 f, Alternative (Rep1 f)) => Alternative (Generically1 f) where
    empty :: Generically1 f a
    empty = Generically1
      (to1 empty)
  
    (<|>) :: Generically1 f a -> Generically1 f a -> Generically1 f a
    Generically1 as1 <|> Generically1 as2 = Generically1
      (to1 (from1 as1 <|> from1 as2))
  
  --------------------------------------------------------------------------------
  -- Meta-data
  --------------------------------------------------------------------------------
  
  -- | Datatype to represent metadata associated with a datatype (@MetaData@),
  -- constructor (@MetaCons@), or field selector (@MetaSel@).
  --
  -- * In @MetaData n m p nt@, @n@ is the datatype's name, @m@ is the module in
  --   which the datatype is defined, @p@ is the package in which the datatype
  --   is defined, and @nt@ is @'True@ if the datatype is a @newtype@.
  --
  -- * In @MetaCons n f s@, @n@ is the constructor's name, @f@ is its fixity,
  --   and @s@ is @'True@ if the constructor contains record selectors.
  --
  -- * In @MetaSel mn su ss ds@, if the field uses record syntax, then @mn@ is
  --   'Just' the record name. Otherwise, @mn@ is 'Nothing'. @su@ and @ss@ are
  --   the field's unpackedness and strictness annotations, and @ds@ is the
  --   strictness that GHC infers for the field.
  --
  -- @since base-4.9.0.0
  data Meta = MetaData Symbol Symbol Symbol Bool
            | MetaCons Symbol FixityI Bool
            | MetaSel  (Maybe Symbol)
                       SourceUnpackedness SourceStrictness DecidedStrictness
  
  --------------------------------------------------------------------------------
  -- Derived instances
  --------------------------------------------------------------------------------
  
  -- | @since base-4.8.0.0
  deriving instance Generic Void
  
  -- | @since base-4.6.0.0
  deriving instance Generic [a]
  
  -- | @since base-4.6.0.0
  deriving instance Generic (NonEmpty a)
  
  -- | @since base-4.6.0.0
  deriving instance Generic (Maybe a)
  
  -- | @since base-4.6.0.0
  deriving instance Generic (Either a b)
  
  -- | @since base-4.6.0.0
  deriving instance Generic Bool
  
  -- | @since base-4.6.0.0
  deriving instance Generic Ordering
  
  -- | @since base-4.6.0.0
  deriving instance Generic (Proxy t)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ()
  
  -- | @since base-4.15
  deriving instance Generic (Solo a)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,) a b)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,,) a b c)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,,,) a b c d)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,,,,) a b c d e)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,,,,,) a b c d e f)
  
  -- | @since base-4.6.0.0
  deriving instance Generic ((,,,,,,) a b c d e f g)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,) a b c d e f g h)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,) a b c d e f g h i)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,) a b c d e f g h i j)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,,) a b c d e f g h i j k)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,,,) a b c d e f g h i j k l)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,,,,) a b c d e f g h i j k l m)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,,,,,) a b c d e f g h i j k l m n)
  
  -- | @since base-4.16.0.0
  deriving instance Generic ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o)
  
  -- | @since base-4.12.0.0
  deriving instance Generic (Down a)
  
  -- | @since base-4.15.0.0
  deriving instance Generic SrcLoc
  
  -- | @since base-4.15.0.0
  deriving instance Generic GeneralCategory
  
  -- | @since base-4.15.0.0
  deriving instance Generic Fingerprint
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 []
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 NonEmpty
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 Maybe
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 (Either a)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 Proxy
  
  -- | @since base-4.15
  deriving instance Generic1 Solo
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,) a)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,,) a b)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,,,) a b c)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,,,,) a b c d)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,,,,,) a b c d e)
  
  -- | @since base-4.6.0.0
  deriving instance Generic1 ((,,,,,,) a b c d e f)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,) a b c d e f g)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,) a b c d e f g h)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,) a b c d e f g h i)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,,) a b c d e f g h i j)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,,,) a b c d e f g h i j k)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,,,,) a b c d e f g h i j k l)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m)
  
  -- | @since base-4.16.0.0
  deriving instance Generic1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n)
  
  -- | @since base-4.12.0.0
  deriving instance Generic1 Down
  
  --------------------------------------------------------------------------------
  -- Copied from the singletons package
  --------------------------------------------------------------------------------
  
  -- | The singleton kind-indexed data family.
  data family Sing (a :: k)
  
  -- | A 'SingI' constraint is essentially an implicitly-passed singleton.
  class SingI (a :: k) where
    -- | Produce the singleton explicitly. You will likely need the @ScopedTypeVariables@
    -- extension to use this method the way you want.
    sing :: Sing a
  
  -- | The 'SingKind' class is essentially a /kind/ class. It classifies all kinds
  -- for which singletons are defined. The class supports converting between a singleton
  -- type and the base (unrefined) type which it is built from.
  class SingKind k where
    -- | Get a base type from a proxy for the promoted kind. For example,
    -- @DemoteRep Bool@ will be the type @Bool@.
    type DemoteRep k :: Type
  
    -- | Convert a singleton to its unrefined version.
    fromSing :: Sing (a :: k) -> DemoteRep k
  
  -- Singleton symbols
  data instance Sing (s :: Symbol) where
    SSym :: KnownSymbol s => Sing s
  
  -- | @since base-4.9.0.0
  instance KnownSymbol a => SingI a where sing = SSym
  
  -- | @since base-4.9.0.0
  instance SingKind Symbol where
    type DemoteRep Symbol = String
    fromSing (SSym :: Sing s) = symbolVal (Proxy :: Proxy s)
  
  -- Singleton booleans
  data instance Sing (a :: Bool) where
    STrue  :: Sing 'True
    SFalse :: Sing 'False
  
  -- | @since base-4.9.0.0
  instance SingI 'True  where sing = STrue
  
  -- | @since base-4.9.0.0
  instance SingI 'False where sing = SFalse
  
  -- | @since base-4.9.0.0
  instance SingKind Bool where
    type DemoteRep Bool = Bool
    fromSing STrue  = True
    fromSing SFalse = False
  
  -- Singleton Maybe
  data instance Sing (b :: Maybe a) where
    SNothing :: Sing 'Nothing
    SJust    :: Sing a -> Sing ('Just a)
  
  -- | @since base-4.9.0.0
  instance            SingI 'Nothing  where sing = SNothing
  
  -- | @since base-4.9.0.0
  instance SingI a => SingI ('Just a) where sing = SJust sing
  
  -- | @since base-4.9.0.0
  instance SingKind a => SingKind (Maybe a) where
    type DemoteRep (Maybe a) = Maybe (DemoteRep a)
    fromSing SNothing  = Nothing
    fromSing (SJust a) = Just (fromSing a)
  
  -- Singleton Fixity
  data instance Sing (a :: FixityI) where
    SPrefix :: Sing 'PrefixI
    SInfix  :: Sing a -> Integer -> Sing ('InfixI a n)
  
  -- | @since base-4.9.0.0
  instance SingI 'PrefixI where sing = SPrefix
  
  -- | @since base-4.9.0.0
  instance (SingI a, KnownNat n) => SingI ('InfixI a n) where
    sing = SInfix (sing :: Sing a) (natVal (Proxy :: Proxy n))
  
  -- | @since base-4.9.0.0
  instance SingKind FixityI where
    type DemoteRep FixityI = Fixity
    fromSing SPrefix      = Prefix
    fromSing (SInfix a n) = Infix (fromSing a) (integerToInt n)
  
  -- Singleton Associativity
  data instance Sing (a :: Associativity) where
    SLeftAssociative  :: Sing 'LeftAssociative
    SRightAssociative :: Sing 'RightAssociative
    SNotAssociative   :: Sing 'NotAssociative
  
  -- | @since base-4.9.0.0
  instance SingI 'LeftAssociative  where sing = SLeftAssociative
  
  -- | @since base-4.9.0.0
  instance SingI 'RightAssociative where sing = SRightAssociative
  
  -- | @since base-4.9.0.0
  instance SingI 'NotAssociative   where sing = SNotAssociative
  
  -- | @since base-4.0.0.0
  instance SingKind Associativity where
    type DemoteRep Associativity = Associativity
    fromSing SLeftAssociative  = LeftAssociative
    fromSing SRightAssociative = RightAssociative
    fromSing SNotAssociative   = NotAssociative
  
  -- Singleton SourceUnpackedness
  data instance Sing (a :: SourceUnpackedness) where
    SNoSourceUnpackedness :: Sing 'NoSourceUnpackedness
    SSourceNoUnpack       :: Sing 'SourceNoUnpack
    SSourceUnpack         :: Sing 'SourceUnpack
  
  -- | @since base-4.9.0.0
  instance SingI 'NoSourceUnpackedness where sing = SNoSourceUnpackedness
  
  -- | @since base-4.9.0.0
  instance SingI 'SourceNoUnpack       where sing = SSourceNoUnpack
  
  -- | @since base-4.9.0.0
  instance SingI 'SourceUnpack         where sing = SSourceUnpack
  
  -- | @since base-4.9.0.0
  instance SingKind SourceUnpackedness where
    type DemoteRep SourceUnpackedness = SourceUnpackedness
    fromSing SNoSourceUnpackedness = NoSourceUnpackedness
    fromSing SSourceNoUnpack       = SourceNoUnpack
    fromSing SSourceUnpack         = SourceUnpack
  
  -- Singleton SourceStrictness
  data instance Sing (a :: SourceStrictness) where
    SNoSourceStrictness :: Sing 'NoSourceStrictness
    SSourceLazy         :: Sing 'SourceLazy
    SSourceStrict       :: Sing 'SourceStrict
  
  -- | @since base-4.9.0.0
  instance SingI 'NoSourceStrictness where sing = SNoSourceStrictness
  
  -- | @since base-4.9.0.0
  instance SingI 'SourceLazy         where sing = SSourceLazy
  
  -- | @since base-4.9.0.0
  instance SingI 'SourceStrict       where sing = SSourceStrict
  
  -- | @since base-4.9.0.0
  instance SingKind SourceStrictness where
    type DemoteRep SourceStrictness = SourceStrictness
    fromSing SNoSourceStrictness = NoSourceStrictness
    fromSing SSourceLazy         = SourceLazy
    fromSing SSourceStrict       = SourceStrict
  
  -- Singleton DecidedStrictness
  data instance Sing (a :: DecidedStrictness) where
    SDecidedLazy   :: Sing 'DecidedLazy
    SDecidedStrict :: Sing 'DecidedStrict
    SDecidedUnpack :: Sing 'DecidedUnpack
  
  -- | @since base-4.9.0.0
  instance SingI 'DecidedLazy   where sing = SDecidedLazy
  
  -- | @since base-4.9.0.0
  instance SingI 'DecidedStrict where sing = SDecidedStrict
  
  -- | @since base-4.9.0.0
  instance SingI 'DecidedUnpack where sing = SDecidedUnpack
  
  -- | @since base-4.9.0.0
  instance SingKind DecidedStrictness where
    type DemoteRep DecidedStrictness = DecidedStrictness
    fromSing SDecidedLazy   = DecidedLazy
    fromSing SDecidedStrict = DecidedStrict
    fromSing SDecidedUnpack = DecidedUnpack
  