-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Familiar functions lifted to generic data types
--
-- Please see README.md.
@package generic-data-functions
@version 0.4.1
-- | Functions "lifted" (roughly) to generic Haskell data types.
--
-- Haskell data types have a fair amount of structure to them:
--
--
-- - Multiple constructors (sums)
-- - Multiple fields (products)
-- - Constructor names must be unique
-- - Fields are ordered left-to-right (or top-to-bottom)
--
--
-- We leverage this structure to provide parameterized generic functions,
-- where the user only handles the base case (individual fields). Such
-- generics are very relevant for simplistic usages like boring type
-- folds and serializing tasks. No need to bash out 50 lines of arcane
-- type algebra -- just write a single instance and you're golden.
--
-- Sum types introduce choice, which brings an extra layer of complexity.
-- For this reason, most functions provide a sum type version and a
-- non-sum type version. Sum type generic functions will require a bit
-- more information, like some extra definitions or instances. Using the
-- wrong one will result in a clear type error.
module Generic.Data.Function
module Generic.Data.Function.Common
data SumOpts
-- | Only "proper" sum types are permitted, no singletons.
SumOnly :: SumOpts
-- | Treat a single constructor as a sum type still.
AllowSingletonSum :: SumOpts
-- | Handy generics utils.
module Generic.Data.Function.Util.Generic
-- | datatypeName without the value (only used as a proxy). Lets us
-- push our undefineds into one place.
datatypeName' :: forall d. Datatype d => String
-- | conName without the value (only used as a proxy). Lets us push
-- our undefineds into one place.
conName' :: forall c. Constructor c => String
-- | selName without the value (only used as a proxy). Lets us push
-- our undefineds into one place.
selName' :: forall s. Selector s => String
-- | Get the record name for a selector if present.
--
-- On the type level, a 'Maybe Symbol' is stored for record names. But
-- the reification is done using fromMaybe "". So we have to
-- inspect the resulting string to determine whether the field uses
-- record syntax or not. (Silly.)
selName'' :: forall s. Selector s => Maybe String
-- | Handy typenat utils.
module Generic.Data.Function.Util.TypeNats
natVal'' :: forall n. KnownNat n => Natural
natValInt :: forall n. KnownNat n => Int
-- | Common descriptions for common generic data representation errors.
-- Type level (compile time) and term level (runtime).
--
-- TODO: if this package ever expands, these deserve plenty of attention,
-- like generic-optics has.
--
-- Runtime errors are a bit meatier because it's easy to do so, and I
-- don't want people to see them more than once (really you should use
-- the typing support).
module Generic.Data.Rep.Error
wrapE :: String -> String -> String
-- | Common type error string for when you attempt to use a generic
-- instance at an empty data type (e.g. Void, V1).
type ENoEmpty = 'Text "Requested generic instance disallows empty data type"
eNoEmpty :: String
-- | Common type error string for when GHC is asked to derive a non-sum
-- instance, but the data type in question turns out to be a sum data
-- type.
--
-- No need to add the data type name here, since GHC's context includes
-- the surrounding instance declaration.
type EUnexpectedSum = 'Text "Cannot derive non-sum generic instance for sum data type"
eNoSum :: String
-- | Common type error string for when GHC is asked to derive a sum
-- instance, but the data type in question turns out to be a non-sum data
-- type.
--
-- No need to add the data type name here, since GHC's context includes
-- the surrounding instance declaration.
type EUnexpectedNonSum = 'Text "Refusing to derive sum generic instance for non-sum data type"
eNeedSum :: String
-- | Wrappers for "free" generics, where the base case is handled for you.
module Generic.Data.Wrappers
-- | Free generic wrapper where any field emits a type error.
--
-- Useful for generic functions on void or enum types.
data NoRec0 (a :: k)
type ENoRec0 = 'Text "Cannot use generic function on NoRec0-wrapped type containing fields"
-- | Free generic wrapper where every field does "nothing" (e.g.
-- mempty.)
--
-- Maybe useful for testing?
data EmptyRec0 (a :: k)
module Generic.Data.Function.Traverse.Constructor
-- | Implementation enumeration type class for generic traverse.
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericTraverse tag where {
-- | The target Applicative to traverse to.
type GenericTraverseF tag :: Type -> Type;
-- | The type class providing the action in traverse for permitted
-- types.
type GenericTraverseC tag a :: Constraint;
}
-- | The action in traverse (first argument).
--
-- We include data type metadata because this function is useful for
-- monadic parsers, which can record it in error messages. (We don't do
-- it for foldMap because it's pure.)
genericTraverseAction :: (GenericTraverse tag, GenericTraverseC tag a) => String -> String -> Maybe String -> Natural -> GenericTraverseF tag a
class GTraverseC tag cd cc (si :: Natural) gf
gTraverseC :: GTraverseC tag cd cc si gf => GenericTraverseF tag (gf p)
type family ProdArity (f :: Type -> Type) :: Natural
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (cc :: k3) (si :: GHC.Num.Natural.Natural) (l :: GHC.Types.Type -> GHC.Types.Type) (r :: GHC.Types.Type -> GHC.Types.Type). (GHC.Base.Applicative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc si l, Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc (si GHC.TypeNats.+ Generic.Data.Function.Traverse.Constructor.ProdArity r) r) => Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc si (l GHC.Generics.:*: r)
instance forall k1 k2 k3 k4 (tag :: k1) a (si :: GHC.TypeNats.Nat) (cs :: GHC.Generics.Meta) (cc :: k2) (cd :: k3). (Generic.Data.Function.Traverse.Constructor.GenericTraverse tag, Generic.Data.Function.Traverse.Constructor.GenericTraverseC tag a, GHC.Base.Functor (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), GHC.TypeNats.KnownNat si, GHC.Generics.Selector cs, GHC.Generics.Constructor cc, GHC.Generics.Datatype cd) => Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc si (GHC.Generics.S1 cs (GHC.Generics.Rec0 a))
instance forall k1 k2 k3 k4 (tag :: k1) (cd :: k2) (cc :: k3). GHC.Base.Applicative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag) => Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc 0 GHC.Generics.U1
instance Generic.Data.Function.Traverse.Constructor.GenericTraverse (Generic.Data.Wrappers.NoRec0 f)
instance Generic.Data.Function.Traverse.Constructor.GenericTraverse (Generic.Data.Wrappers.EmptyRec0 f)
module Generic.Data.Function.Traverse.Sum
-- | Sum type monads that can be generically traversed.
--
-- We use Alternative to handle "which constructor" checking on
-- the term level.
class GenericTraverse tag => GenericTraverseSum tag
-- | Try to parse a prefix tag of type pt.
--
-- Relevant metadata is provided as arguments.
genericTraverseSumPfxTagAction :: (GenericTraverseSum tag, GenericTraverseC tag pt) => String -> GenericTraverseF tag pt
-- | Parse error due to no constructor matching the parsed prefix tag.
--
-- Relevant metadata is provided as arguments.
genericTraverseSumNoMatchingCstrAction :: GenericTraverseSum tag => String -> [String] -> Text -> GenericTraverseF tag a
-- | How to use a type as a prefix tag in a generic sum type parser.
data PfxTagCfg a
PfxTagCfg :: (String -> a) -> (a -> a -> Bool) -> (a -> Text) -> PfxTagCfg a
-- | How to turn a constructor name into a prefix tag.
[pfxTagCfgFromCstr] :: PfxTagCfg a -> String -> a
-- | How to compare prefix tags for equality.
--
-- By shoving this into our generic derivation config, we can avoid
-- adding an insidious Eq constraint. In general, you will want to
-- set this to (==).
[pfxTagCfgEq] :: PfxTagCfg a -> a -> a -> Bool
-- | Make a prefix tag human-readable. show is often appropriate.
[pfxTagCfgShow] :: PfxTagCfg a -> a -> Text
class GTraverseSum tag (opts :: SumOpts) gf
gTraverseSum :: (GTraverseSum tag opts gf, GenericTraverseC tag pt) => PfxTagCfg pt -> GenericTraverseF tag (gf p)
class GTraverseSumD tag cd (opts :: SumOpts) gf
gTraverseSumD :: (GTraverseSumD tag cd opts gf, GenericTraverseC tag pt) => PfxTagCfg pt -> GenericTraverseF tag (gf p)
gTraverseSumD' :: forall {p} tag cd gf pt. (GenericTraverseC tag pt, Alternative (GenericTraverseF tag), Monad (GenericTraverseF tag), GenericTraverseSum tag, GTraverseCSum tag cd gf, Datatype cd) => PfxTagCfg pt -> GenericTraverseF tag (gf p)
class GTraverseCSum tag cd gf
gTraverseCSum :: GTraverseCSum tag cd gf => PfxTagCfg pt -> pt -> GenericTraverseF tag (gf p)
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (l :: k3 -> GHC.Types.Type) (r :: k3 -> GHC.Types.Type) (opts :: Generic.Data.Function.Common.SumOpts). (Generic.Data.Function.Traverse.Sum.GenericTraverseSum tag, Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd (l GHC.Generics.:+: r), GHC.Generics.Datatype cd, GHC.Base.Alternative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), GHC.Base.Monad (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag)) => Generic.Data.Function.Traverse.Sum.GTraverseSumD tag cd opts (l GHC.Generics.:+: r)
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (cc :: GHC.Generics.Meta) (gf :: k3 -> GHC.Types.Type). (Generic.Data.Function.Traverse.Sum.GenericTraverseSum tag, Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd (GHC.Generics.C1 cc gf), GHC.Generics.Datatype cd, GHC.Base.Alternative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), GHC.Base.Monad (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag)) => Generic.Data.Function.Traverse.Sum.GTraverseSumD tag cd 'Generic.Data.Function.Common.AllowSingletonSum (GHC.Generics.C1 cc gf)
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (l :: k3 -> GHC.Types.Type) (r :: k3 -> GHC.Types.Type). (GHC.Base.Alternative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd l, Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd r) => Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd (l GHC.Generics.:+: r)
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (cc :: GHC.Generics.Meta) (gf :: k3 -> GHC.Types.Type). (GHC.Base.Alternative (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc 0 gf, GHC.Generics.Constructor cc) => Generic.Data.Function.Traverse.Sum.GTraverseCSum tag cd (GHC.Generics.C1 cc gf)
instance forall k1 k2 (tag :: k1) (cd :: GHC.Generics.Meta) (opts :: Generic.Data.Function.Common.SumOpts) (gf :: k2 -> GHC.Types.Type). (Generic.Data.Function.Traverse.Sum.GTraverseSumD tag cd opts gf, GHC.Base.Functor (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag)) => Generic.Data.Function.Traverse.Sum.GTraverseSum tag opts (GHC.Generics.D1 cd gf)
instance forall k1 k2 k3 (tag :: k1) (cd :: k2) (cc :: GHC.Generics.Meta) (gf :: k3 -> GHC.Types.Type). Generic.Data.Function.Traverse.Sum.GTraverseSumD tag cd 'Generic.Data.Function.Common.SumOnly (GHC.Generics.C1 cc gf)
instance forall k1 k2 k3 (opts :: k1) (tag :: k2) (cd :: Generic.Data.Function.Common.SumOpts). Generic.Data.Function.Traverse.Sum.GTraverseSumD opts tag cd GHC.Generics.V1
module Generic.Data.Function.Traverse.NonSum
class GTraverseNonSum tag gf
gTraverseNonSum :: GTraverseNonSum tag gf => GenericTraverseF tag (gf p)
class GTraverseNonSumD tag (cd :: Meta) gf
gTraverseNonSumD :: GTraverseNonSumD tag cd gf => GenericTraverseF tag (gf p)
instance forall k1 k2 (tag :: k1) (cd :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). (GHC.Base.Functor (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), Generic.Data.Function.Traverse.NonSum.GTraverseNonSumD tag cd gf) => Generic.Data.Function.Traverse.NonSum.GTraverseNonSum tag (GHC.Generics.D1 cd gf)
instance forall k1 k2 (tag :: k1) (cd :: GHC.Generics.Meta) (cc :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). (GHC.Base.Functor (Generic.Data.Function.Traverse.Constructor.GenericTraverseF tag), Generic.Data.Function.Traverse.Constructor.GTraverseC tag cd cc 0 gf) => Generic.Data.Function.Traverse.NonSum.GTraverseNonSumD tag cd (GHC.Generics.C1 cc gf)
instance forall k1 k2 (cd :: k1) (tag :: GHC.Generics.Meta) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). Generic.Data.Function.Traverse.NonSum.GTraverseNonSumD cd tag (l GHC.Generics.:+: r)
instance forall k1 k2 (cd :: k1) (tag :: GHC.Generics.Meta). Generic.Data.Function.Traverse.NonSum.GTraverseNonSumD cd tag GHC.Generics.V1
-- | traverse for generic data types.
--
-- TODO This is harder to conceptualize than generic foldMap. No
-- nice clean explanation yet.
--
-- This function can provide generic support for simple parser-esque
-- types.
module Generic.Data.Function.Traverse
-- | Implementation enumeration type class for generic traverse.
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericTraverse tag where {
-- | The target Applicative to traverse to.
type GenericTraverseF tag :: Type -> Type;
-- | The type class providing the action in traverse for permitted
-- types.
type GenericTraverseC tag a :: Constraint;
}
-- | The action in traverse (first argument).
--
-- We include data type metadata because this function is useful for
-- monadic parsers, which can record it in error messages. (We don't do
-- it for foldMap because it's pure.)
genericTraverseAction :: (GenericTraverse tag, GenericTraverseC tag a) => String -> String -> Maybe String -> Natural -> GenericTraverseF tag a
-- | Generic traverse over a term of non-sum data type f a,
-- where f is set by the tag you pass.
genericTraverseNonSum :: forall {k} (tag :: k) a. (Generic a, Functor (GenericTraverseF tag), GTraverseNonSum tag (Rep a)) => GenericTraverseF tag a
class GTraverseNonSum tag gf
-- | Sum type monads that can be generically traversed.
--
-- We use Alternative to handle "which constructor" checking on
-- the term level.
class GenericTraverse tag => GenericTraverseSum tag
-- | Try to parse a prefix tag of type pt.
--
-- Relevant metadata is provided as arguments.
genericTraverseSumPfxTagAction :: (GenericTraverseSum tag, GenericTraverseC tag pt) => String -> GenericTraverseF tag pt
-- | Parse error due to no constructor matching the parsed prefix tag.
--
-- Relevant metadata is provided as arguments.
genericTraverseSumNoMatchingCstrAction :: GenericTraverseSum tag => String -> [String] -> Text -> GenericTraverseF tag a
-- | How to use a type as a prefix tag in a generic sum type parser.
data PfxTagCfg a
PfxTagCfg :: (String -> a) -> (a -> a -> Bool) -> (a -> Text) -> PfxTagCfg a
-- | How to turn a constructor name into a prefix tag.
[pfxTagCfgFromCstr] :: PfxTagCfg a -> String -> a
-- | How to compare prefix tags for equality.
--
-- By shoving this into our generic derivation config, we can avoid
-- adding an insidious Eq constraint. In general, you will want to
-- set this to (==).
[pfxTagCfgEq] :: PfxTagCfg a -> a -> a -> Bool
-- | Make a prefix tag human-readable. show is often appropriate.
[pfxTagCfgShow] :: PfxTagCfg a -> a -> Text
-- | Generic traverse over a term of sum data type f a,
-- where f is set by the tag you pass.
--
-- You must provide a configuration for how to handle constructors.
genericTraverseSum :: forall {k} (tag :: k) opts a pt. (Generic a, Functor (GenericTraverseF tag), GTraverseSum tag opts (Rep a), GenericTraverseC tag pt) => PfxTagCfg pt -> GenericTraverseF tag a
class GTraverseSum tag (opts :: SumOpts) gf
-- | Construct a prefix tag config using existing Eq and Show
-- instances.
--
-- The user only needs to provide the constructor name parser.
eqShowPfxTagCfg :: (Eq a, Show a) => (String -> a) -> PfxTagCfg a
module Generic.Data.Function.FoldMap.Constructor
-- | Implementation enumeration type class for generic foldMap.
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericFoldMap tag where {
-- | The target Monoid to foldMap to.
type GenericFoldMapM tag :: Type;
-- | The type class providing the map function in foldMap for
-- permitted types.
type GenericFoldMapC tag a :: Constraint;
}
-- | The map function in foldMap (first argument).
genericFoldMapF :: (GenericFoldMap tag, GenericFoldMapC tag a) => a -> GenericFoldMapM tag
-- | foldMap on individual constructors (products).
class GFoldMapC tag f
gFoldMapC :: GFoldMapC tag f => f p -> GenericFoldMapM tag
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (GHC.Base.Semigroup (Generic.Data.Function.FoldMap.Constructor.GenericFoldMapM tag), Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag l, Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag r) => Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag (l GHC.Generics.:*: r)
instance forall k1 k2 (tag :: k1) a (c :: GHC.Generics.Meta). (Generic.Data.Function.FoldMap.Constructor.GenericFoldMap tag, Generic.Data.Function.FoldMap.Constructor.GenericFoldMapC tag a) => Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag (GHC.Generics.S1 c (GHC.Generics.Rec0 a))
instance forall k1 k2 (tag :: k1). GHC.Base.Monoid (Generic.Data.Function.FoldMap.Constructor.GenericFoldMapM tag) => Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag GHC.Generics.U1
instance Generic.Data.Function.FoldMap.Constructor.GenericFoldMap (Generic.Data.Wrappers.NoRec0 m)
instance GHC.Base.Monoid m => Generic.Data.Function.FoldMap.Constructor.GenericFoldMap (Generic.Data.Wrappers.EmptyRec0 m)
-- | foldMap for sum types, where constructors are encoded by index
-- (distance from first/leftmost constructor) in a single byte, which is
-- prepended to their contents.
--
-- TODO. Clumsy and limited. And yet, still handy enough I think.
module Generic.Data.Function.FoldMap.SumConsByte
class GFoldMapSumConsByte tag f
gFoldMapSumConsByte :: GFoldMapSumConsByte tag f => (Word8 -> GenericFoldMapM tag) -> f p -> GenericFoldMapM tag
-- | Sum type handler handling constructors only. Useful if you handle
-- constructor prefixes elsewhere.
class GFoldMapCSumCtr tag f
gFoldMapCSumCtr :: GFoldMapCSumCtr tag f => f p -> GenericFoldMapM tag
class GFoldMapCSumCtrArityByte tag (arity :: Natural) f
gFoldMapCSumCtrArityByte :: GFoldMapCSumCtrArityByte tag arity f => (Word8 -> GenericFoldMapM tag) -> f p -> GenericFoldMapM tag
type family SumArity (a :: Type -> Type) :: Natural
type FitsInByte n = FitsInByteResult (n <=? 255)
type family FitsInByteResult (b :: Bool) :: Constraint
type family TypeErrorMessage (a :: Symbol) :: Constraint
instance forall k (l :: GHC.Types.Type -> GHC.Types.Type) (r :: GHC.Types.Type -> GHC.Types.Type) (tag :: k). (Generic.Data.Function.FoldMap.SumConsByte.FitsInByte (Generic.Data.Function.FoldMap.SumConsByte.SumArity (l GHC.Generics.:+: r)), Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtrArityByte tag 0 (l GHC.Generics.:+: r), Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtr tag (l GHC.Generics.:+: r), GHC.Base.Semigroup (Generic.Data.Function.FoldMap.Constructor.GenericFoldMapM tag)) => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapSumConsByte tag (l GHC.Generics.:+: r)
instance forall k (tag :: k) (arity :: GHC.Num.Natural.Natural) (l :: GHC.Types.Type -> GHC.Types.Type) (r :: GHC.Types.Type -> GHC.Types.Type). (Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtrArityByte tag arity l, Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtrArityByte tag (arity GHC.TypeNats.+ Generic.Data.Function.FoldMap.SumConsByte.SumArity l) r) => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtrArityByte tag arity (l GHC.Generics.:+: r)
instance forall k1 k2 (arity :: GHC.TypeNats.Nat) (tag :: k1) (c :: GHC.Generics.Meta) (f :: k2 -> GHC.Types.Type). GHC.TypeNats.KnownNat arity => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtrArityByte tag arity (GHC.Generics.C1 c f)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtr tag l, Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtr tag r) => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtr tag (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1) (f :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag f => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapCSumCtr tag (GHC.Generics.C1 c f)
instance forall k1 k2 (tag :: k1) (f :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Generic.Data.Function.FoldMap.SumConsByte.GFoldMapSumConsByte tag f => Generic.Data.Function.FoldMap.SumConsByte.GFoldMapSumConsByte tag (GHC.Generics.D1 c f)
instance forall k1 k2 (m :: k1) (c :: GHC.Generics.Meta) (f :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.SumConsByte.GFoldMapSumConsByte m (GHC.Generics.C1 c f)
instance forall k1 k2 (m :: k1). Generic.Data.Function.FoldMap.SumConsByte.GFoldMapSumConsByte m GHC.Generics.V1
-- | foldMap for sum types where constructors are encoded by mapping
-- the constructor name.
--
-- Note that constructor names are unique per type. So as long as your
-- mapping function similarly outputs unique values of your monoid for
-- each constructor, you should be able to "reverse" the process (e.g.
-- for generic traverse).
module Generic.Data.Function.FoldMap.Sum
class GFoldMapSum tag (opts :: SumOpts) gf
gFoldMapSum :: GFoldMapSum tag opts gf => (String -> GenericFoldMapM tag) -> gf p -> GenericFoldMapM tag
-- | Sum type handler prefixing constructor contents with their mapped
-- constructor name via a provided String -> m.
--
-- TODO rename
class GFoldMapCSum tag gf
gFoldMapCSum :: GFoldMapCSum tag gf => (String -> GenericFoldMapM tag) -> gf p -> GenericFoldMapM tag
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type) (opts :: Generic.Data.Function.Common.SumOpts). Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (l GHC.Generics.:+: r) => Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag opts (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (GHC.Generics.C1 c gf) => Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag 'Generic.Data.Function.Common.AllowSingletonSum (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag l, Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag r) => Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). (GHC.Base.Semigroup (Generic.Data.Function.FoldMap.Constructor.GenericFoldMapM tag), GHC.Generics.Constructor c, Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag gf) => Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (opts :: Generic.Data.Function.Common.SumOpts) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag opts gf => Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag opts (GHC.Generics.D1 c gf)
instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag 'Generic.Data.Function.Common.SumOnly (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (opts :: Generic.Data.Function.Common.SumOpts). Generic.Data.Function.FoldMap.Sum.GFoldMapSum tag opts GHC.Generics.V1
module Generic.Data.Function.FoldMap.NonSum
-- | foldMap over generic product data types.
--
-- Take a generic representation, map each field in the data type to a
-- Monoid, and combine the results with (<>).
class GFoldMapNonSum tag gf
gFoldMapNonSum :: GFoldMapNonSum tag gf => gf p -> GenericFoldMapM tag
instance forall k1 k2 (tag :: k1) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum tag gf => Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum tag (GHC.Generics.D1 c gf)
instance forall k1 k2 (tag :: k1) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). Generic.Data.Function.FoldMap.Constructor.GFoldMapC tag gf => Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum tag (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum tag (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1). Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum tag GHC.Generics.V1
-- | foldMap for generic data types.
--
-- foldMap can be considered a two-step process:
--
--
-- - map every element a of a t a (where
-- Foldable t) to some Monoid m
-- - combine elements using (<>)
--
--
-- Applying this to generic data types:
--
--
-- - map every field of a constructor to some Monoid
-- m
-- - combine elements using (<>)
--
--
-- Field mappings are handled using a per-monoid type class. You need a
-- monoid m with an associated type class which has a function
-- a -> m. Write a GenericFoldMap instance for your
-- monoid which points to your type class. If a field type doesn't have a
-- matching instance, the generic instance emits a type error.
--
-- Sum types (with multiple constructors) are handled by
-- (<>)-ing the constructor with its contents (in that
-- order). You must provide a String -> m function for
-- mapping constructor names. If you need custom sum type handling, you
-- may write your own and still leverage the individual constructor
-- generics.
--
-- This function can provide generic support for simple fold-y operations
-- like serialization.
module Generic.Data.Function.FoldMap
-- | Implementation enumeration type class for generic foldMap.
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericFoldMap tag where {
-- | The target Monoid to foldMap to.
type GenericFoldMapM tag :: Type;
-- | The type class providing the map function in foldMap for
-- permitted types.
type GenericFoldMapC tag a :: Constraint;
}
-- | The map function in foldMap (first argument).
genericFoldMapF :: (GenericFoldMap tag, GenericFoldMapC tag a) => a -> GenericFoldMapM tag
-- | Generic foldMap over a term of non-sum data type a.
--
-- a must have exactly one constructor.
genericFoldMapNonSum :: forall {k} (tag :: k) a. (Generic a, GFoldMapNonSum tag (Rep a)) => a -> GenericFoldMapM tag
-- | foldMap over generic product data types.
--
-- Take a generic representation, map each field in the data type to a
-- Monoid, and combine the results with (<>).
class GFoldMapNonSum tag gf
-- | Generic foldMap over a term of sum data type a.
--
-- You must provide a function for mapping constructor names to monoidal
-- values.
--
-- This is the most generic option, but depending on your string
-- manipulation may be slower.
genericFoldMapSum :: forall {k} (tag :: k) opts a. (Generic a, GFoldMapSum tag opts (Rep a)) => (String -> GenericFoldMapM tag) -> a -> GenericFoldMapM tag
class GFoldMapSum tag (opts :: SumOpts) gf
-- | Generic foldMap over a term of sum data type a where
-- constructors are mapped to their index (distance from first/leftmost
-- constructor)
--
-- a must have at least two constructors.
--
-- You must provide a function for mapping bytes to monoidal values.
--
-- This should be fairly fast, but sadly I think it's slower than the
-- generics in store and binary/cereal libraries.
genericFoldMapSumConsByte :: forall tag a. (Generic a, GFoldMapSumConsByte tag (Rep a)) => (Word8 -> GenericFoldMapM tag) -> a -> GenericFoldMapM tag
class GFoldMapSumConsByte tag f
module Generic.Data.Function.Example
data X
X1 :: X
X2 :: X
data Y
Y :: Y
newtype Showly
Showly :: [String] -> Showly
[unShowly] :: Showly -> [String]
showGeneric :: forall opts a. (Generic a, GFoldMapSum Showly opts (Rep a)) => a -> String
showGeneric' :: forall a. (Generic a, GFoldMapNonSum Showly (Rep a)) => a -> String
instance GHC.Generics.Generic Generic.Data.Function.Example.X
instance GHC.Generics.Generic Generic.Data.Function.Example.Y
instance GHC.Base.Monoid Generic.Data.Function.Example.Showly
instance GHC.Base.Semigroup Generic.Data.Function.Example.Showly
instance Generic.Data.Function.FoldMap.Constructor.GenericFoldMap Generic.Data.Function.Example.Showly
module Generic.Data.Function.Contra.Constructor
-- | TODO
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericContra tag where {
type GenericContraF tag :: Type -> Type;
type GenericContraC tag a :: Constraint;
}
genericContraF :: (GenericContra tag, GenericContraC tag a, Divisible (GenericContraF tag)) => GenericContraF tag a
class GContraC tag gf
gContraC :: GContraC tag gf => GenericContraF tag (gf p)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (Data.Functor.Contravariant.Divisible.Divisible (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.Constructor.GContraC tag l, Generic.Data.Function.Contra.Constructor.GContraC tag r) => Generic.Data.Function.Contra.Constructor.GContraC tag (l GHC.Generics.:*: r)
instance forall k1 k2 (tag :: k1) a (c :: GHC.Generics.Meta). (Data.Functor.Contravariant.Divisible.Divisible (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.Constructor.GenericContra tag, Generic.Data.Function.Contra.Constructor.GenericContraC tag a) => Generic.Data.Function.Contra.Constructor.GContraC tag (GHC.Generics.S1 c (GHC.Generics.Rec0 a))
instance forall k1 k2 (tag :: k1). Data.Functor.Contravariant.Divisible.Divisible (Generic.Data.Function.Contra.Constructor.GenericContraF tag) => Generic.Data.Function.Contra.Constructor.GContraC tag GHC.Generics.U1
instance Generic.Data.Function.Contra.Constructor.GenericContra (Generic.Data.Wrappers.NoRec0 f)
instance Generic.Data.Function.Contra.Constructor.GenericContra (Generic.Data.Wrappers.EmptyRec0 f)
module Generic.Data.Function.Contra.Sum
class GContraSum tag (opts :: SumOpts) gf
gContraSum :: GContraSum tag opts gf => GenericContraF tag String -> GenericContraF tag (gf p)
class GContraSumD tag (opts :: SumOpts) gf
gContraSumD :: GContraSumD tag opts gf => GenericContraF tag String -> GenericContraF tag (gf p)
class GContraCSum tag gf
gContraCSum :: GContraCSum tag gf => GenericContraF tag String -> GenericContraF tag (gf p)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type) (opts :: Generic.Data.Function.Common.SumOpts). Generic.Data.Function.Contra.Sum.GContraCSum tag (l GHC.Generics.:+: r) => Generic.Data.Function.Contra.Sum.GContraSumD tag opts (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1) (cc :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.Sum.GContraCSum tag (GHC.Generics.C1 cc gf) => Generic.Data.Function.Contra.Sum.GContraSumD tag 'Generic.Data.Function.Common.AllowSingletonSum (GHC.Generics.C1 cc gf)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). (Data.Functor.Contravariant.Divisible.Decidable (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.Sum.GContraCSum tag l, Generic.Data.Function.Contra.Sum.GContraCSum tag r) => Generic.Data.Function.Contra.Sum.GContraCSum tag (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). (Data.Functor.Contravariant.Divisible.Divisible (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.Constructor.GContraC tag gf, GHC.Generics.Constructor c) => Generic.Data.Function.Contra.Sum.GContraCSum tag (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (opts :: Generic.Data.Function.Common.SumOpts) (gf :: k2 -> GHC.Types.Type) (cd :: GHC.Generics.Meta). (Generic.Data.Function.Contra.Sum.GContraSumD tag opts gf, Data.Functor.Contravariant.Contravariant (Generic.Data.Function.Contra.Constructor.GenericContraF tag)) => Generic.Data.Function.Contra.Sum.GContraSum tag opts (GHC.Generics.D1 cd gf)
instance forall k1 k2 (tag :: k1) (cc :: GHC.Generics.Meta) (gf :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.Sum.GContraSumD tag 'Generic.Data.Function.Common.SumOnly (GHC.Generics.C1 cc gf)
instance forall k1 k2 (tag :: k1) (opts :: Generic.Data.Function.Common.SumOpts). Generic.Data.Function.Contra.Sum.GContraSumD tag opts GHC.Generics.V1
module Generic.Data.Function.Contra.NonSum
class GContraNonSum tag gf
gContraNonSum :: GContraNonSum tag gf => GenericContraF tag (gf p)
class GContraNonSumD tag gf
gContraNonSumD :: GContraNonSumD tag gf => GenericContraF tag (gf p)
instance forall k1 k2 (tag :: k1) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). (Data.Functor.Contravariant.Contravariant (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.NonSum.GContraNonSumD tag gf) => Generic.Data.Function.Contra.NonSum.GContraNonSum tag (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (gf :: k2 -> GHC.Types.Type) (c :: GHC.Generics.Meta). (Data.Functor.Contravariant.Contravariant (Generic.Data.Function.Contra.Constructor.GenericContraF tag), Generic.Data.Function.Contra.Constructor.GContraC tag gf) => Generic.Data.Function.Contra.NonSum.GContraNonSumD tag (GHC.Generics.C1 c gf)
instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.NonSum.GContraNonSumD tag (l GHC.Generics.:+: r)
instance forall k1 k2 (tag :: k1). Generic.Data.Function.Contra.NonSum.GContraNonSumD tag GHC.Generics.V1
module Generic.Data.Function.Contra
-- | TODO
--
-- The type variable is uninstantiated, used purely as a tag. Good types
-- include the type class used inside (providing you define the type
-- class/it's not an orphan instance), or a custom void data type. See
-- the binrep library on Hackage for an example.
class GenericContra tag where {
type GenericContraF tag :: Type -> Type;
type GenericContraC tag a :: Constraint;
}
genericContraF :: (GenericContra tag, GenericContraC tag a, Divisible (GenericContraF tag)) => GenericContraF tag a
-- | Generic contra over a term of non-sum data type a.
--
-- a must have exactly one constructor.
genericContraNonSum :: forall {k} (tag :: k) a. (Generic a, Contravariant (GenericContraF tag), GContraNonSum tag (Rep a)) => GenericContraF tag a
class GContraNonSum tag gf
-- | Generic contra over a term of sum data type a.
--
-- You must provide a contra function for constructor names.
--
-- This is the most generic option, but depending on your string
-- manipulation may be slower.
genericContraSum :: forall {k} (tag :: k) opts a. (Generic a, Contravariant (GenericContraF tag), GContraSum tag opts (Rep a)) => GenericContraF tag String -> GenericContraF tag a
class GContraSum tag (opts :: SumOpts) gf