-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Generic programming library for generalised deriving.
--
-- This package offers a version of GHC.Generics with two
-- important improvements:
--
--
-- - The to, from, to1, and from1
-- methods have multiplicity-polymorphic types, allowing them to be used
-- with either traditional Haskell code or linearly typed code.
-- - The representations used for Generic1 are modified
-- slightly. As a result, to1 and from1 never need to
-- use fmap. This can greatly improve performance, and it
-- is necessary to support multiplicity polymorphism. A smaller
-- change, approximately as proposed by spl, reduces the number of
-- instances that must be written to actually use Generic1 for
-- deriving instances of other classes.
--
--
-- For more details, see the Generics.Linear documentation.
--
-- This library is organized as follows:
--
--
-- - Generics.Linear defines the core functionality for
-- generics, including the multiplicity-polymorphic Generic(1)
-- classes and a replacement for the :.: composition type.
-- - Generics.Linear.TH implements Template Haskell
-- functionality for deriving instances of Generic(1).
-- - Generics.Linear.Unsafe.ViaGHCGenerics offers
-- DerivingVia targets to derive Generic and
-- Generic1 instances from
-- GHC.Generics.GHC.Generics.Generic. Because
-- these instances necessarily use unsafe coercions, their use will
-- likely inhibit full optimization of code using them.
--
--
-- Educational code: the educational modules exported by
-- generic-deriving have been copied into the
-- tests/Generic/Deriving directory in this repository, with the
-- very few modifications required to accommodate the differences between
-- the Generic1 representations here and in base. All
-- the same caveats apply as in the originals; see that package's
-- README.
@package linear-generics
@version 0.2
-- | This module contains Template Haskell code that can be used to
-- automatically generate the boilerplate code for the generic deriving
-- library.
--
-- To use these functions, pass the name of a data type as an argument:
--
--
-- {-# LANGUAGE TemplateHaskell #-}
--
-- data Example a = Example Int Char a
-- $(deriveGeneric ''Example) -- Derives Generic instance
-- $(deriveGeneric1 ''Example) -- Derives Generic1 instance
-- $(deriveGenericAnd1 ''Example) -- Derives Generic and Generic1 instances
--
--
-- This code can also be used with data families. To derive for a data
-- family instance, pass the name of one of the instance's constructors:
--
--
-- {-# LANGUAGE FlexibleInstances, TemplateHaskell, TypeFamilies #-}
--
-- data family Family a b
-- newtype instance Family Char x = FamilyChar Char
-- data instance Family Bool x = FamilyTrue | FamilyFalse
--
-- $(deriveGeneric 'FamilyChar) -- instance Generic (Family Char b) where ...
-- $(deriveGeneric1 'FamilyTrue) -- instance Generic1 (Family Bool) where ...
-- -- Alternatively, one could type $(deriveGeneric1 'FamilyFalse)
--
--
-- General usage notes
--
-- Template Haskell imposes some fairly harsh limitations on ordering and
-- visibility within a module. In most cases, classes derived generically
-- will need to be derived using StandaloneDeriving after
-- the deriveGeneric* invocation. For example, if
-- Generically is a class that uses a GenericClass
-- constraint for its instances, then you cannot write
--
--
-- data Fish = Fish
-- deriving Show via (Generically Fish)
--
-- $(deriveGeneric 'Fish)
--
--
-- You must instead write
--
--
-- data Fish = Fish
--
-- $(deriveGeneric 'Fish)
--
-- deriving via Generically Fish
-- instance Show Fish
--
--
-- Furthermore, types defined after a deriveGeneric* invocation
-- are not visible before that invocation. This may require some careful
-- ordering, especially in the case of mutually recursive types. For
-- example, the following will not compile:
--
--
-- data Foo = Foo | Bar Baz
-- $(deriveGeneric 'Foo)
--
-- data Baz = Baz Int Foo
-- $(deriveGeneric 'Baz)
--
--
-- Instead, you must write
--
--
-- data Foo = Foo | Bar Baz
-- data Baz = Baz Int Foo
--
-- $(deriveGeneric 'Foo)
-- $(deriveGeneric 'Baz)
--
module Generics.Linear.TH
-- | Given the name of a type or data family constructor, derive a
-- GenericClass instance.
deriveGeneric :: Name -> Q [Dec]
-- | Given the name of a type or data family constructor, derive a
-- GenericClass instance.
deriveGeneric1 :: Name -> Q [Dec]
-- | Given the name of a type or data family constructor, derive a
-- GenericClass instance and a GenericClass instance.
deriveGenericAnd1 :: Name -> Q [Dec]
-- | Multiplicity polymorphic versions of
-- GHC.Generics.Generic and
-- GHC.Generics.Generic1. Generic is
-- otherwise identical to the standard version. Generic1 is
-- similar, but with modifications that make it more efficient, as well
-- as supporting linearity.
--
-- This module re-exports everything in GHC.Generics except
-- Generic, Generic1, Rec1, and :.:. The
-- Generic1 representations here don't need Rec1. We expose
-- our own, identical, :.:. This allows users to instantiate their
-- Generic1-based generic-deriving classes so they can be used
-- with both GHC.Generics and this package.
--
-- In addition to the usual generic types, we export one called
-- MP1 for use with nonlinear and multiplicity polymorphic fields.
-- Nonlinear generic-deriving classes should almost always handle
-- MP1 without restriction. Some linear generic-deriving classes
-- will need to constrain its m parameter to be 'One.
module Generics.Linear
-- | Generic is exactly the same as
-- GHC.Generics.Generic except that to and
-- from are multiplicity polymorphic. This means they will work
-- equally well in traditional Haskell code and in linearly typed code.
class Generic a where {
type Rep a :: Type -> Type;
}
to :: forall p m. Generic a => Rep a p %m -> a
from :: forall p m. Generic a => a %m -> Rep a p
-- | Generic1 is similar to
-- GHC.Generics.Generic1, but has a few
-- differences.
--
-- Multiplicity polymorphism
--
-- As with Generic, the to1 and from1 methods
-- are multiplicity polymorphic.
--
-- Differences in Rep1 representation
--
-- Rec1 is not used
--
-- Given a type like
--
--
-- newtype Foo a = Foo (Maybe a)
--
--
-- where a single type constructor (here Maybe) is applied to
-- the parameter, GHC.Generics represents the field as
-- Rec1 Maybe. We instead represent it using Par1 :.:
-- Maybe. It is expected that very few real-life uses of
-- GHC.Generics will break as a result, and this simplification
-- means that users don't have to write Rec1 instances for their
-- generic-deriving classes.
--
-- Compositions associate in the opposite order
--
-- Given a type like
--
--
-- newtype Bar a = Bar (Maybe [Either e a])
--
--
-- where multiple type constructors are layered around the parameter,
-- "GHC.Generics@ represents the field as
--
--
-- Maybe :.: ([] :.: Rec1 (Either e))
--
--
-- We instead represent it as
--
--
-- ((Par1 :.: Maybe) :.: []) :.: Either e
--
--
-- Doing it this way prevents to1 and from1 from having to
-- fmap newtype constructors through the composed types, which can
-- be a considerable performance improvement and enables multiplicity
-- polymorphism.
--
-- In most cases, modifying generic-deriving classes to accommodate this
-- change is simple: just swap which side of the composition is treated
-- as a generic representation and which as a base type. In a few cases,
-- more restructuring will be needed, which will require using different
-- generic-deriving classes than for GHC.Generics.
--
-- Difference in specificity
--
-- Users of type application will need to be aware that the kind
-- parameter for Generic1 is marked as inferred, whereas for
-- GHC.Generics.Generic1 it is marked as
-- specified. So you should use, for example, to1 @Maybe rather
-- than to1 @_ @Maybe.
class Generic1 (f :: k -> Type) where {
type Rep1 f :: k -> Type;
}
to1 :: forall p m. Generic1 f => Rep1 f p %m -> f p
from1 :: forall p m. Generic1 f => f p %m -> Rep1 f p
-- | The composition operator for types. We use our own here because for
-- many classes, it's possible to share generic deriving classes between
-- GHC.Generics and Generics.Linear by just instantiating
-- them for both composition operators (and MP1).
newtype ( f :.: g ) x
Comp1 :: f (g x) -> (:.:) f g x
[unComp1] :: (:.:) f g x -> f (g x)
infixl 7 :.:
-- | Types with nonlinear or multiplicity-polymorphic fields should use
-- MP1 under S1. Unfortunately, Template Haskell (and
-- GHC Generics) currently lack any support for such types, so their
-- instances must currently be written entirely manually. We may add some
-- functions to ease the pain at some point.
--
-- Generic-deriving classes that do not involve linear types should treat
-- MP1 m much as they treat M1: dig through it to get
-- to the meat. Unfortunately, some futzing about may be necessary to
-- convince the type checker that multiplicities work out.
--
-- Generic-deriving classes that use linear types may have to treat
-- MP1 m specially. In particular, they may need to constrain
-- m to be 'One or 'Many, or to match some other
-- type variable.
data MP1 :: forall k. Multiplicity -> (k -> Type) -> k -> Type
[MP1] :: f a -> MP1 m f a
-- | Extract the value from an MP1.
unMP1 :: MP1 m f a %n -> f a
-- | Class for datatypes that represent datatypes
class Datatype (d :: k)
-- | The name of the datatype (unqualified)
datatypeName :: forall k1 t (f :: k1 -> Type) (a :: k1). Datatype d => t d f a -> [Char]
-- | The fully-qualified name of the module where the type is declared
moduleName :: forall k1 t (f :: k1 -> Type) (a :: k1). Datatype d => t d f a -> [Char]
-- | The package name of the module where the type is declared
packageName :: forall k1 t (f :: k1 -> Type) (a :: k1). Datatype d => t d f a -> [Char]
-- | Marks if the datatype is actually a newtype
isNewtype :: forall k1 t (f :: k1 -> Type) (a :: k1). Datatype d => t d f a -> Bool
-- | Class for datatypes that represent data constructors
class Constructor (c :: k)
-- | The name of the constructor
conName :: forall k1 t (f :: k1 -> Type) (a :: k1). Constructor c => t c f a -> [Char]
-- | The fixity of the constructor
conFixity :: forall k1 t (f :: k1 -> Type) (a :: k1). Constructor c => t c f a -> Fixity
-- | Marks if this constructor is a record
conIsRecord :: forall k1 t (f :: k1 -> Type) (a :: k1). Constructor c => t c f a -> Bool
-- | Class for datatypes that represent records
class Selector (s :: k)
-- | The name of the selector
selName :: forall k1 t (f :: k1 -> Type) (a :: k1). Selector s => t s f a -> [Char]
-- | The selector's unpackedness annotation (if any)
selSourceUnpackedness :: forall k1 t (f :: k1 -> Type) (a :: k1). Selector s => t s f a -> SourceUnpackedness
-- | The selector's strictness annotation (if any)
selSourceStrictness :: forall k1 t (f :: k1 -> Type) (a :: k1). Selector s => t s f a -> SourceStrictness
-- | The strictness that the compiler inferred for the selector
selDecidedStrictness :: forall k1 t (f :: k1 -> Type) (a :: k1). Selector s => t s f a -> DecidedStrictness
-- | Void: used for datatypes without constructors
data V1 (p :: k)
-- | Unit: used for constructors without arguments
data U1 (p :: k)
U1 :: U1 (p :: k)
-- | Used for marking occurrences of the parameter
newtype Par1 p
Par1 :: p -> Par1 p
[unPar1] :: Par1 p -> p
-- | Constants, additional parameters and recursion of kind *
newtype K1 i c (p :: k)
K1 :: c -> K1 i c (p :: k)
[unK1] :: K1 i c (p :: k) -> c
-- | Meta-information (constructor names, etc.)
newtype M1 i (c :: Meta) (f :: k -> Type) (p :: k)
M1 :: f p -> M1 i (c :: Meta) (f :: k -> Type) (p :: k)
[unM1] :: M1 i (c :: Meta) (f :: k -> Type) (p :: k) -> f p
-- | Sums: encode choice between constructors
data ( (f :: k -> Type) :+: (g :: k -> Type) ) (p :: k)
L1 :: f p -> (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k)
R1 :: g p -> (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k)
infixr 5 :+:
-- | Products: encode multiple arguments to constructors
data ( (f :: k -> Type) :*: (g :: k -> Type) ) (p :: k)
(:*:) :: f p -> g p -> (:*:) (f :: k -> Type) (g :: k -> Type) (p :: k)
infixr 6 :*:
infixr 6 :*:
-- | Tag for K1: recursion (of kind Type)
data R
-- | Tag for M1: datatype
data D
-- | Tag for M1: constructor
data C
-- | Tag for M1: record selector
data S
-- | Type synonym for encoding recursion (of kind Type)
type Rec0 = K1 R :: Type -> k -> Type
-- | Type synonym for encoding meta-information for datatypes
type D1 = M1 D :: Meta -> k -> Type -> k -> Type
-- | Type synonym for encoding meta-information for constructors
type C1 = M1 C :: Meta -> k -> Type -> k -> Type
-- | Type synonym for encoding meta-information for record selectors
type S1 = M1 S :: Meta -> k -> Type -> k -> Type
-- | Constants of unlifted kinds
data family URec a (p :: k)
-- | Type synonym for URec Addr#
type UAddr = URec Ptr () :: k -> Type
-- | Type synonym for URec Char#
type UChar = URec Char :: k -> Type
-- | Type synonym for URec Double#
type UDouble = URec Double :: k -> Type
-- | Type synonym for URec Float#
type UFloat = URec Float :: k -> Type
-- | Type synonym for URec Int#
type UInt = URec Int :: k -> Type
-- | Type synonym for URec Word#
type UWord = URec Word :: k -> Type
-- | 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.
data SourceUnpackedness
NoSourceUnpackedness :: SourceUnpackedness
SourceNoUnpack :: SourceUnpackedness
SourceUnpack :: SourceUnpackedness
-- | 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.
data SourceStrictness
NoSourceStrictness :: SourceStrictness
SourceLazy :: SourceStrictness
SourceStrict :: SourceStrictness
-- | 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.
--
data Meta
MetaData :: Symbol -> Symbol -> Symbol -> Bool -> Meta
MetaCons :: Symbol -> FixityI -> Bool -> Meta
MetaSel :: Maybe Symbol -> SourceUnpackedness -> SourceStrictness -> DecidedStrictness -> Meta
-- | This variant of Fixity appears at the type level.
data FixityI
PrefixI :: FixityI
InfixI :: Associativity -> Nat -> FixityI
-- | Datatype to represent the fixity of a constructor. An infix |
-- declaration directly corresponds to an application of Infix.
data Fixity
Prefix :: Fixity
Infix :: Associativity -> Int -> Fixity
-- | 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.
--
data DecidedStrictness
DecidedLazy :: DecidedStrictness
DecidedStrict :: DecidedStrictness
DecidedUnpack :: DecidedStrictness
-- | Datatype to represent the associativity of a constructor
data Associativity
LeftAssociative :: Associativity
RightAssociative :: Associativity
NotAssociative :: Associativity
-- | Get the precedence of a fixity value.
prec :: Fixity -> Int
-- | DerivingVia targets to instantiate Generic and
-- Generic1, both using
-- GHC.Generics.Generic.
--
-- Caution
module Generics.Linear.Unsafe.ViaGHCGenerics
-- | When a is an instance of
-- GHC.Generics.Generic, GHCGenerically a
-- is an instance of Generic.
--
-- Warnings
--
-- GHCGenerically is intended for use as a DerivingVia
-- target. Most other uses of its Generic instance will be quite
-- wrong.
--
-- GHCGenerically must not be used with datatypes that
-- have nonlinear or linearity-polymorphic fields. Doing so will produce
-- completely bogus results, breaking the linearity rules.
--
-- GHCGenerically is otherwise safe to use with derived
-- GHC.Generics.Generic instances, which are
-- linear. If you choose to use it with a hand-written instance, you
-- should check that the underlying instance is linear.
--
-- Example
--
--
-- data Foo a = Bar a (Either Int a) | Baz (Maybe a) Int
-- deriving stock (Show, GHC.Generics.Generic)
-- deriving Generic via GHCGenerically (Foo a)
--
newtype GHCGenerically a
GHCGenerically :: a -> GHCGenerically a
[unGHCGenerically] :: GHCGenerically a -> a
-- | When f a is an instance of
-- GHC.Generics.Generic for all a,
-- GHCGenerically1 f is an instance of Generic1.
--
-- Warning
--
-- GHCGenerically1 is intended for use as a DerivingVia
-- target. Most other uses of its Generic1 instance will be quite
-- wrong.
--
-- GHCGenerically1 must not be used with datatypes that
-- have nonlinear or linearity-polymorphic fields. Doing so will produce
-- completely bogus results, breaking the linearity rules.
--
-- GHCGenerically1 is otherwise safe to use with derived
-- GHC.Generics.Generic instances, which are
-- linear. If you choose to use it with a hand-written instance, you
-- should check that the underlying instance is linear.
--
-- Example
--
--
-- data Foo a = Bar a (Either Int a) | Baz (Maybe a) Int
-- deriving stock (Show, GHC.Generics.Generic)
-- deriving Generic1 via GHCGenerically1 Foo
--
newtype GHCGenerically1 f a
GHCGenerically1 :: f a -> GHCGenerically1 f a
[unGHCGenerically1] :: GHCGenerically1 f a -> f a
instance forall k (f :: k -> *). (forall (a :: k). GHC.Generics.Generic (f a)) => Generics.Linear.Class.Generic1 (Generics.Linear.Unsafe.ViaGHCGenerics.GHCGenerically1 f)
instance GHC.Generics.Generic a => Generics.Linear.Class.Generic (Generics.Linear.Unsafe.ViaGHCGenerics.GHCGenerically a)