-- 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.3.1 -- | Functions "lifted" (roughly) to generic Haskell data types. -- -- Haskell data types have a fair amount of structure to them: -- -- -- -- 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 -- | Assertions on precise generic data representation. -- -- I like being real picky with my generic code, disallowing misuse at -- the type level. However, this makes it less flexible overall, and is a -- large chunk of the code I have to write over and over again. -- -- I mainly care about sanity checks, along the lines of "if the generic -- representations looks like this, type error out". So they don't make -- any term-level changes. -- -- So, instead of hiding these in generic type class instances, I put -- them in type family equations. Now we can turn these checks on and off -- -- and when they're on, you have to carry around that fact in your -- types. Fantastic! -- -- Checks are formed as Constraints, where a failure triggers a -- TypeError and a success goes to the empty constraint -- () (() :: Constraint as well as -- Type). -- -- These checks were always done on the type-level, but they were -- "inline" with the rest of the type class. By pulling them out, we -- *should* be incurring some compile-time performance penalty (albeit -- hopefully minor due to the simple nature of the checks), but making no -- change to runtime. module Generic.Data.Rep.Assert -- | Generic representation assertions, on the constructor level (bits that -- come after D1). data GCAssert -- | Is not an empty type (does not have 0 constructors) NoEmpty :: GCAssert -- | Is not a sum type (has 0 or 1 constructors) NoSum :: GCAssert -- | Is a sum type (has 0 or >2 constructors) NeedSum :: GCAssert -- | Convert a generic representation constructor-level assertion "label" -- to the assertion it represents, and make that assertion. type family ApplyGCAssert x a -- | Apply a list of generic representation constructor-level assertions. type family ApplyGCAsserts ls a type family GCNoEmpty a type family GCNoSum a type family GCNeedSum a -- | 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. -- -- Avoid orphan instances by defining custom empty types to use here. 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 cd cc (si :: Natural) tag gf gTraverseC :: GTraverseC cd cc si tag 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 cd cc si tag l, Generic.Data.Function.Traverse.Constructor.GTraverseC cd cc (si GHC.TypeNats.+ Generic.Data.Function.Traverse.Constructor.ProdArity r) tag r) => Generic.Data.Function.Traverse.Constructor.GTraverseC cd cc si tag (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 cd cc si tag (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 cd cc 0 tag 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 (opts :: SumOpts) cd tag gf gTraverseSum :: (GTraverseSum opts cd tag gf, GenericTraverseC tag pt) => PfxTagCfg pt -> GenericTraverseF tag (gf p) gTraverseSum' :: forall {p} cd tag gf pt. (GenericTraverseC tag pt, Alternative (GenericTraverseF tag), Monad (GenericTraverseF tag), GenericTraverseSum tag, GTraverseCSum cd tag gf, Datatype cd) => PfxTagCfg pt -> GenericTraverseF tag (gf p) class GTraverseCSum cd tag gf gTraverseCSum :: GTraverseCSum cd tag 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 cd tag (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.GTraverseSum opts cd tag (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 cd tag (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.GTraverseSum 'Generic.Data.Function.Common.AllowSingletonSum cd tag (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 cd tag l, Generic.Data.Function.Traverse.Sum.GTraverseCSum cd tag r) => Generic.Data.Function.Traverse.Sum.GTraverseCSum cd tag (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 cd cc 0 tag gf, GHC.Generics.Constructor cc) => Generic.Data.Function.Traverse.Sum.GTraverseCSum cd tag (GHC.Generics.C1 cc gf) instance forall k1 k2 k3 (cd :: k1) (tag :: k2) (cc :: GHC.Generics.Meta) (gf :: k3 -> GHC.Types.Type). Generic.Data.Function.Traverse.Sum.GTraverseSum 'Generic.Data.Function.Common.SumOnly cd tag (GHC.Generics.C1 cc gf) instance forall k1 k2 k3 (opts :: Generic.Data.Function.Common.SumOpts) (cd :: k1) (tag :: k2). Generic.Data.Function.Traverse.Sum.GTraverseSum opts cd tag GHC.Generics.V1 module Generic.Data.Function.Traverse.NonSum class GTraverseNonSum (cd :: Meta) tag gf gTraverseNonSum :: GTraverseNonSum cd tag gf => GenericTraverseF tag (gf p) 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 cd cc 0 tag gf) => Generic.Data.Function.Traverse.NonSum.GTraverseNonSum cd tag (GHC.Generics.C1 cc gf) instance forall k1 k2 (cd :: GHC.Generics.Meta) (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). Generic.Data.Function.Traverse.NonSum.GTraverseNonSum cd tag (l GHC.Generics.:+: r) instance forall k1 k2 (cd :: GHC.Generics.Meta) (tag :: k1). Generic.Data.Function.Traverse.NonSum.GTraverseNonSum 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. -- -- Avoid orphan instances by defining custom empty types to use here. 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. genericTraverseNonSum :: forall {cd} {gf} {k} asserts (tag :: k) a. (Generic a, Rep a ~ D1 cd gf, GTraverseNonSum cd tag gf, ApplyGCAsserts asserts gf, Functor (GenericTraverseF tag)) => GenericTraverseF tag a class GTraverseNonSum (cd :: Meta) 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. -- -- You must provide a configuration for how to handle constructors. genericTraverseSum :: forall {cd} {gf} opts asserts tag a pt. (Generic a, Rep a ~ D1 cd gf, GTraverseSum opts cd tag gf, ApplyGCAsserts asserts gf, GenericTraverseC tag pt, Functor (GenericTraverseF tag)) => PfxTagCfg pt -> GenericTraverseF tag a class GTraverseSum (opts :: SumOpts) cd tag 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. -- -- Avoid orphan instances by defining custom empty types to use here. 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 (opts :: SumOpts) tag f gFoldMapSum :: GFoldMapSum opts tag f => (String -> GenericFoldMapM tag) -> f p -> GenericFoldMapM tag -- | Sum type handler prefixing constructor contents with their mapped -- constructor name via a provided String -> m. -- -- TODO rename class GFoldMapCSum tag f gFoldMapCSum :: GFoldMapCSum tag f => (String -> GenericFoldMapM tag) -> f 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 opts tag (l GHC.Generics.:+: r) instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (f :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (GHC.Generics.C1 c f) => Generic.Data.Function.FoldMap.Sum.GFoldMapSum 'Generic.Data.Function.Common.AllowSingletonSum tag (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.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) (f :: 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 f) => Generic.Data.Function.FoldMap.Sum.GFoldMapCSum tag (GHC.Generics.C1 c f) instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (f :: k2 -> GHC.Types.Type). Generic.Data.Function.FoldMap.Sum.GFoldMapSum 'Generic.Data.Function.Common.SumOnly tag (GHC.Generics.C1 c f) instance forall k1 k2 (opts :: Generic.Data.Function.Common.SumOpts) (tag :: k1). Generic.Data.Function.FoldMap.Sum.GFoldMapSum opts tag 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 f gFoldMapNonSum :: GFoldMapNonSum tag f => f p -> GenericFoldMapM tag 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.NonSum.GFoldMapNonSum tag (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.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: -- -- -- -- Applying this to generic data types: -- -- -- -- 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. -- -- Avoid orphan instances by defining custom empty types to use here. 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 {cd} {gf} asserts tag a. (Generic a, Rep a ~ D1 cd gf, GFoldMapNonSum tag gf, ApplyGCAsserts asserts gf) => 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 f -- | 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 {cd} {gf} opts asserts tag a. (Generic a, Rep a ~ D1 cd gf, GFoldMapSum opts tag gf, ApplyGCAsserts asserts gf) => (String -> GenericFoldMapM tag) -> a -> GenericFoldMapM tag class GFoldMapSum (opts :: SumOpts) tag f -- | 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 {cd} {f} opts asserts a. (Generic a, Rep a ~ D1 cd f, GFoldMapSum opts Showly f, ApplyGCAsserts asserts f) => a -> String showGeneric' :: forall {cd} {f} asserts a. (Generic a, Rep a ~ D1 cd f, GFoldMapNonSum Showly f, ApplyGCAsserts asserts f) => 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 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 (opts :: SumOpts) tag gf gContraSum :: GContraSum opts tag 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.GContraSum opts tag (l GHC.Generics.:+: r) instance forall k1 k2 (tag :: k1) (c :: GHC.Generics.Meta) (g :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.Sum.GContraCSum tag (GHC.Generics.C1 c g) => Generic.Data.Function.Contra.Sum.GContraSum 'Generic.Data.Function.Common.AllowSingletonSum tag (GHC.Generics.C1 c g) 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) (c :: GHC.Generics.Meta) (g :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.Sum.GContraSum 'Generic.Data.Function.Common.SumOnly tag (GHC.Generics.C1 c g) instance forall k1 k2 (opts :: Generic.Data.Function.Common.SumOpts) (tag :: k1). Generic.Data.Function.Contra.Sum.GContraSum opts tag GHC.Generics.V1 module Generic.Data.Function.Contra.NonSum class GContraNonSum tag gf gContraNonSum :: GContraNonSum tag gf => GenericContraF tag (gf p) instance forall k1 k2 (tag :: k1) (g :: 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 g) => Generic.Data.Function.Contra.NonSum.GContraNonSum tag (GHC.Generics.C1 c g) instance forall k1 k2 (tag :: k1) (l :: k2 -> GHC.Types.Type) (r :: k2 -> GHC.Types.Type). Generic.Data.Function.Contra.NonSum.GContraNonSum tag (l GHC.Generics.:+: r) instance forall k1 k2 (tag :: k1). Generic.Data.Function.Contra.NonSum.GContraNonSum tag GHC.Generics.V1 module Generic.Data.Function.Contra 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 {cd} {gf} asserts tag a. (Generic a, Rep a ~ D1 cd gf, GContraNonSum tag gf, ApplyGCAsserts asserts gf, Contravariant (GenericContraF tag)) => 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 {cd} {gf} opts asserts tag a. (Generic a, Rep a ~ D1 cd gf, GContraSum opts tag gf, ApplyGCAsserts asserts gf, Contravariant (GenericContraF tag)) => GenericContraF tag String -> GenericContraF tag a class GContraSum (opts :: SumOpts) tag gf