Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This package provides the general mechanism for defining field and branch aliases for algebraic datatypes.
Aliases can be defined for multiple contexts (json serialization, orms...).
Each of those contexts is termed a Rubric
, basically a marker datakind
used to namespace the aliases.
This module should only be imported if you want to define your own adapter
package for some new Rubric
. See ByOtherNames.Aeson for a concrete example.
Synopsis
- data Aliases rep a
- zipAliasesWith :: (a -> b -> c) -> Aliases rep a -> Aliases rep b -> Aliases rep c
- data AliasList names a
- aliasListBegin :: forall names a rep. AliasTree names rep '[] => AliasList names a -> Aliases rep a
- alias :: forall name a names. a -> AliasList names a -> AliasList (name ': names) a
- aliasListEnd :: AliasList '[] a
- class Rubric k where
- class (Rubric k, Generic r) => Aliased k r where
- class GHasDatatypeName rep where
- class GHasFieldNames rep where
- gGetFieldNames :: Aliases rep String
- class GRecord (c :: Type -> Constraint) rep where
- gToRecord :: Applicative m => Aliases rep a -> (forall v. c v => a -> m v) -> m (rep z)
- gFromRecord :: Aliases rep a -> (forall v. c v => a -> v -> o) -> rep z -> Aliases rep o
- gRecordEnum :: Aliases rep a -> (forall v. c v => Proxy v -> o) -> Aliases rep (a, o)
- class GHasBranchNames rep where
- gGetBranchNames :: Aliases rep String
- class GSum (c :: Type -> Constraint) rep where
- gToSum :: (Functor n, Applicative m2) => Aliases rep a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v. c v => m1 v) -> (forall v. c v => m2 v) -> Aliases rep (n (rep z))
- gFromSum :: Aliases rep a -> (forall v. c v => v -> o) -> rep z -> (a, [o])
- gSumEnum :: Aliases rep a -> (forall v. c v => Proxy v -> o) -> Aliases rep (a, [o])
- data Slots m1 m2 v
- = ZeroSlots v
- | SingleSlot (m1 v)
- | ManySlots (m2 v)
- data Symbol
Aliases
This datatype carries the field aliases and matches the structure of the generic Rep' shape.
Instances
FunctorWithIndex String (Aliases rep) Source # | Indexed by the field or branch names. |
FoldableWithIndex String (Aliases rep) Source # | |
Defined in ByOtherNames.Internal ifoldMap :: Monoid m => (String -> a -> m) -> Aliases rep a -> m # ifoldMap' :: Monoid m => (String -> a -> m) -> Aliases rep a -> m # ifoldr :: (String -> a -> b -> b) -> b -> Aliases rep a -> b # ifoldl :: (String -> b -> a -> b) -> b -> Aliases rep a -> b # ifoldr' :: (String -> a -> b -> b) -> b -> Aliases rep a -> b # ifoldl' :: (String -> b -> a -> b) -> b -> Aliases rep a -> b # | |
TraversableWithIndex String (Aliases rep) Source # | |
Defined in ByOtherNames.Internal | |
Functor (Aliases rep) Source # | |
Foldable (Aliases rep) Source # | |
Defined in ByOtherNames.Internal fold :: Monoid m => Aliases rep m -> m # foldMap :: Monoid m => (a -> m) -> Aliases rep a -> m # foldMap' :: Monoid m => (a -> m) -> Aliases rep a -> m # foldr :: (a -> b -> b) -> b -> Aliases rep a -> b # foldr' :: (a -> b -> b) -> b -> Aliases rep a -> b # foldl :: (b -> a -> b) -> b -> Aliases rep a -> b # foldl' :: (b -> a -> b) -> b -> Aliases rep a -> b # foldr1 :: (a -> a -> a) -> Aliases rep a -> a # foldl1 :: (a -> a -> a) -> Aliases rep a -> a # toList :: Aliases rep a -> [a] # null :: Aliases rep a -> Bool # length :: Aliases rep a -> Int # elem :: Eq a => a -> Aliases rep a -> Bool # maximum :: Ord a => Aliases rep a -> a # minimum :: Ord a => Aliases rep a -> a # | |
Traversable (Aliases rep) Source # | |
Defined in ByOtherNames.Internal |
data AliasList names a Source #
An intermediate datatype for specifying the aliases. See
aliasListBegin
, alias
and aliasListEnd
.
aliasListBegin :: forall names a rep. AliasTree names rep '[] => AliasList names a -> Aliases rep a Source #
Define the aliases for a type by listing them.
See also alias
and aliasListEnd
.
The type of the argument is indexed by a list of Symbol
s, while the
type of the result is indexed by a generic Rep
.
Example for a record:
>>>
:{
data Foo = Foo {aa :: Int, bb :: Bool} deriving (Read, Show, Generic) fieldAliases :: Aliases (Rep Foo) String fieldAliases = aliasListBegin $ alias @"aa" "alias1" $ alias @"bb" "alias2" $ aliasListEnd :}
Example for a sum:
>>>
:{
data Bar = Aa Int | Bb deriving (Read, Show, Generic) branchAliases :: Aliases (Rep Bar) String branchAliases = aliasListBegin $ alias @"Aa" "alias1" $ alias @"Bb" "alias2" $ aliasListEnd :}
alias :: forall name a names. a -> AliasList names a -> AliasList (name ': names) a Source #
Add an alias to an AliasList
.
TYPE APPLICATION REQUIRED! You must provide the field/branch name using a type application.
aliasListEnd :: AliasList '[] a Source #
The empty AliasList
.
Rubrics
Typeclass for marker datakinds used as rubrics, for classifying aliases according to their use.
The associated type family AliasType
gives the type of the aliases.
Rubric
s are needed when defining helper newtypes for use with -XDerivingVia
. Because
Aliases
are defined at the value level, we need a way to relate the aliases with
the datatype during deriving.
Instances
Rubric 'JSON Source # | The aliases will be of type Data.Aeson.Key. |
Defined in ByOtherNames.Aeson |
class (Rubric k, Generic r) => Aliased k r where Source #
Typeclass for datatypes r
that have aliases for some Rubric
k
.
Generic helpers
These generic helpers allow you to define typeclass instances for your datatypes in one go, without having to divide your logic across auxiliary instances, or deal with types of the generic representation like GHC.Generics.D1.
You still need to use GHC.Generics.Rep, from
, and to
.
class GHasDatatypeName rep where Source #
Given a datatype's Rep
, obtain the datatype's name.
Instances
KnownSymbol datatypeName => GHasDatatypeName (D1 ('MetaData datatypeName m p nt) (C1 y prod) :: k -> Type) Source # | |
Defined in ByOtherNames.Internal |
class GHasFieldNames rep where Source #
Given a datatype's Rep
, obtain its field names, assuming the datatype is a record.
gGetFieldNames :: Aliases rep String Source #
Instances
(GHasFieldNames left, GHasFieldNames right) => GHasFieldNames (left :*: right) Source # | |
Defined in ByOtherNames.Internal | |
GHasFieldNames prod => GHasFieldNames (D1 x (C1 y prod)) Source # | |
Defined in ByOtherNames.Internal | |
KnownSymbol fieldName => GHasFieldNames (S1 ('MetaSel ('Just fieldName) unpackedness strictness laziness) (Rec0 v)) Source # | |
Defined in ByOtherNames.Internal |
class GRecord (c :: Type -> Constraint) rep where Source #
Helper typeclass for defining typeclass instances for record types.
Parameterized by a constraint c
that each field of the record must satisfy, and by
the generic Rep
of the record.
:: Applicative m | |
=> Aliases rep a | Field aliases. |
-> (forall v. c v => a -> m v) | |
-> m (rep z) |
Builds a parser for the entire generic Rep
out of parsers for each field.
Returns an uniform representation of each field's value in a record.
Useful for serializing.
Decorates an Aliases
value with values derived from the type of the corresponding fields.
Instances
(GRecord c left, GRecord c right) => GRecord c (left :*: right) Source # | |
Defined in ByOtherNames.Internal gToRecord :: Applicative m => Aliases (left :*: right) a -> (forall v. c v => a -> m v) -> m ((left :*: right) z) Source # gFromRecord :: Aliases (left :*: right) a -> (forall v. c v => a -> v -> o) -> (left :*: right) z -> Aliases (left :*: right) o Source # gRecordEnum :: Aliases (left :*: right) a -> (forall v. c v => Proxy v -> o) -> Aliases (left :*: right) (a, o) Source # | |
c v => GRecord c (S1 x (Rec0 v)) Source # | |
Defined in ByOtherNames.Internal gToRecord :: Applicative m => Aliases (S1 x (Rec0 v)) a -> (forall v0. c v0 => a -> m v0) -> m (S1 x (Rec0 v) z) Source # gFromRecord :: Aliases (S1 x (Rec0 v)) a -> (forall v0. c v0 => a -> v0 -> o) -> S1 x (Rec0 v) z -> Aliases (S1 x (Rec0 v)) o Source # gRecordEnum :: Aliases (S1 x (Rec0 v)) a -> (forall v0. c v0 => Proxy v0 -> o) -> Aliases (S1 x (Rec0 v)) (a, o) Source # | |
GRecord c prod => GRecord c (D1 x (C1 y prod)) Source # | |
Defined in ByOtherNames.Internal gToRecord :: Applicative m => Aliases (D1 x (C1 y prod)) a -> (forall v. c v => a -> m v) -> m (D1 x (C1 y prod) z) Source # gFromRecord :: Aliases (D1 x (C1 y prod)) a -> (forall v. c v => a -> v -> o) -> D1 x (C1 y prod) z -> Aliases (D1 x (C1 y prod)) o Source # gRecordEnum :: Aliases (D1 x (C1 y prod)) a -> (forall v. c v => Proxy v -> o) -> Aliases (D1 x (C1 y prod)) (a, o) Source # |
class GHasBranchNames rep where Source #
Given a datatype's Rep
, obtain its brach names, assuming the datatype is a sum.
gGetBranchNames :: Aliases rep String Source #
Instances
(GHasBranchNames left, GHasBranchNames right) => GHasBranchNames (left :+: right) Source # | |
Defined in ByOtherNames.Internal | |
GHasBranchNames (left :+: right) => GHasBranchNames (D1 x (left :+: right)) Source # | |
Defined in ByOtherNames.Internal | |
KnownSymbol branchName => GHasBranchNames (C1 ('MetaCons branchName fixity sels) y) Source # | |
Defined in ByOtherNames.Internal |
class GSum (c :: Type -> Constraint) rep where Source #
Helper typeclass for defining typeclass instances for sum types.
Parameterized by a constraint c
that each field in each branch of the sum must satisfy, and by
the generic Rep
of the sum.
:: (Functor n, Applicative m2) | |
=> Aliases rep a | Branch aliases. |
-> (forall b. a -> Slots m1 m2 b -> n b) | Convert a parser for a branch's fields into a parser for the branch. |
-> (forall v. c v => m1 v) | Parser for when there's only one field in a branch. |
-> (forall v. c v => m2 v) | Parser for when there's more than one field in a branch. |
-> Aliases rep (n (rep z)) |
Builds a parser for the entire generic Rep
.
:: Aliases rep a | Branch aliases. |
-> (forall v. c v => v -> o) | |
-> rep z | |
-> (a, [o]) |
Returns the annotation corresponding to the current branch, along with an uniform representation of the branch field's values.
Useful for serializing.
Decorates an Aliases
value with values derived from the type of each branch's fields.
Instances
GSumSlots c (left :*: right) => GSum c (C1 x (left :*: right)) Source # | |
Defined in ByOtherNames.Internal gToSum :: (Functor n, Applicative m2) => Aliases (C1 x (left :*: right)) a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v. c v => m1 v) -> (forall v. c v => m2 v) -> Aliases (C1 x (left :*: right)) (n (C1 x (left :*: right) z)) Source # gFromSum :: Aliases (C1 x (left :*: right)) a -> (forall v. c v => v -> o) -> C1 x (left :*: right) z -> (a, [o]) Source # gSumEnum :: Aliases (C1 x (left :*: right)) a -> (forall v. c v => Proxy v -> o) -> Aliases (C1 x (left :*: right)) (a, [o]) Source # | |
c v => GSum c (C1 x (S1 y (Rec0 v))) Source # | |
Defined in ByOtherNames.Internal gToSum :: (Functor n, Applicative m2) => Aliases (C1 x (S1 y (Rec0 v))) a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v0. c v0 => m1 v0) -> (forall v1. c v1 => m2 v1) -> Aliases (C1 x (S1 y (Rec0 v))) (n (C1 x (S1 y (Rec0 v)) z)) Source # gFromSum :: Aliases (C1 x (S1 y (Rec0 v))) a -> (forall v0. c v0 => v0 -> o) -> C1 x (S1 y (Rec0 v)) z -> (a, [o]) Source # gSumEnum :: Aliases (C1 x (S1 y (Rec0 v))) a -> (forall v0. c v0 => Proxy v0 -> o) -> Aliases (C1 x (S1 y (Rec0 v))) (a, [o]) Source # | |
GSum c (C1 x (U1 :: Type -> Type)) Source # | |
Defined in ByOtherNames.Internal gToSum :: (Functor n, Applicative m2) => Aliases (C1 x U1) a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v. c v => m1 v) -> (forall v. c v => m2 v) -> Aliases (C1 x U1) (n (C1 x U1 z)) Source # gFromSum :: Aliases (C1 x U1) a -> (forall v. c v => v -> o) -> C1 x U1 z -> (a, [o]) Source # gSumEnum :: Aliases (C1 x U1) a -> (forall v. c v => Proxy v -> o) -> Aliases (C1 x U1) (a, [o]) Source # | |
(GSum c left, GSum c right) => GSum c (left :+: right) Source # | |
Defined in ByOtherNames.Internal gToSum :: (Functor n, Applicative m2) => Aliases (left :+: right) a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v. c v => m1 v) -> (forall v. c v => m2 v) -> Aliases (left :+: right) (n ((left :+: right) z)) Source # gFromSum :: Aliases (left :+: right) a -> (forall v. c v => v -> o) -> (left :+: right) z -> (a, [o]) Source # gSumEnum :: Aliases (left :+: right) a -> (forall v. c v => Proxy v -> o) -> Aliases (left :+: right) (a, [o]) Source # | |
GSum c (left :+: right) => GSum c (D1 x (left :+: right)) Source # | |
Defined in ByOtherNames.Internal gToSum :: (Functor n, Applicative m2) => Aliases (D1 x (left :+: right)) a -> (forall b. a -> Slots m1 m2 b -> n b) -> (forall v. c v => m1 v) -> (forall v. c v => m2 v) -> Aliases (D1 x (left :+: right)) (n (D1 x (left :+: right) z)) Source # gFromSum :: Aliases (D1 x (left :+: right)) a -> (forall v. c v => v -> o) -> D1 x (left :+: right) z -> (a, [o]) Source # gSumEnum :: Aliases (D1 x (left :+: right)) a -> (forall v. c v => Proxy v -> o) -> Aliases (D1 x (left :+: right)) (a, [o]) Source # |
Helper for defining branch parsers.
v
is some part of a generic Rep
, m1
is some parser type for when there's a single
field in the branch, and m2
is some parser type for when there's more than one field
in the branch.
m1
and m2
might be the same type.
ZeroSlots v | |
SingleSlot (m1 v) | |
ManySlots (m2 v) |
Re-exports
(Kind) This is the kind of type-level symbols. Declared here because class IP needs it
Instances
SingKind Symbol | Since: base-4.9.0.0 |
Defined in GHC.Generics type DemoteRep Symbol | |
KnownSymbol a => SingI (a :: Symbol) | Since: base-4.9.0.0 |
Defined in GHC.Generics sing :: Sing a | |
KnownSymbol fieldName => GHasFieldNames (S1 ('MetaSel ('Just fieldName) unpackedness strictness laziness) (Rec0 v)) Source # | |
Defined in ByOtherNames.Internal | |
IsRecord (M1 S ('MetaSel ('Nothing :: Maybe Symbol) u ss ds) f) False | |
Defined in Data.Aeson.Types.Generic | |
type DemoteRep Symbol | |
Defined in GHC.Generics | |
data Sing (s :: Symbol) | |
Defined in GHC.Generics |