Safe Haskell | None |
---|---|

Language | Haskell2010 |

Surgery for generic data types: remove and insert constructors and fields.

Functions in this module are expected to be used with visible type
applications. Surgeries have a lot of type parameters, but usually only the
first one to three type arguments need to be passed via `TypeApplications`

.
Functions are documented with informal "functional dependencies",
clarifying which type parameters can be inferred from which others
(click on "Details" under each function to see those).

Remember that not all parameters to the left of a functional dependency arrow need to be annotated explicitly to determine those on the right. Some can also be inferred from the context.

Note that constructors and fields are indexed from zero.

## Synopsis

- data Data (r :: Type -> Type) p
- toData :: Generic a => a -> Data (Rep a) p
- fromData :: Generic a => Data (Rep a) p -> a
- data OR (l :: k -> Type) (x :: k)
- toOR :: forall a l x. (Generic a, ToORRep a l) => a -> OR l x
- fromOR' :: forall f l x. FromOR f l => OR l x -> Data f x
- toOR' :: forall f l x. ToOR f l => Data f x -> OR l x
- fromOR :: forall a l x. (Generic a, FromORRep a l) => OR l x -> a
- type OROf a = OR (Linearize (Rep a)) ()
- toORLazy :: forall a l x. (Generic a, ToORRepLazy a l) => a -> OR l x
- fromORLazy :: forall a l x. (Generic a, FromORRepLazy a l) => OR l x -> a
- type OROfLazy a = OR (Linearize (Lazify (Rep a))) ()
- removeCField :: forall n t lt l x. RmvCField n t lt l => OR lt x -> (t, OR l x)
- insertCField :: forall n t lt l x. InsCField n t lt l => (t, OR l x) -> OR lt x
- insertCField' :: forall n t lt l x. InsCField n t lt l => t -> OR l x -> OR lt x
- modifyCField :: forall n t t' lt lt' l x. ModCField n t t' lt lt' l => (t -> t') -> OR lt x -> OR lt' x
- removeRField :: forall fd n t lt l x. RmvRField fd n t lt l => OR lt x -> (t, OR l x)
- insertRField :: forall fd n t lt l x. InsRField fd n t lt l => (t, OR l x) -> OR lt x
- insertRField' :: forall fd n t lt l x. InsRField fd n t lt l => t -> OR l x -> OR lt x
- modifyRField :: forall fd n t t' lt lt' l x. ModRField fd n t t' lt lt' l => (t -> t') -> OR lt x -> OR lt' x
- removeConstr :: forall c n t lc l x. RmvConstr c n t lc l => OR lc x -> Either t (OR l x)
- insertConstr :: forall c n t lc l x. InsConstr c n t lc l => Either t (OR l x) -> OR lc x
- modifyConstr :: forall c n t t' lc lc' l x. ModConstr c n t t' lc lc' l => (t -> t') -> OR lc x -> OR lc' x
- removeConstrT :: forall c n t lc l x. RmvConstrT c n t lc l => OR lc x -> Either t (OR l x)
- insertConstrT :: forall c n t lc l x. InsConstrT c n t lc l => Either t (OR l x) -> OR lc x
- modifyConstrT :: forall c n t t' lc lc' l x. ModConstrT c n t t' lc lc' l => (t -> t') -> OR lc x -> OR lc' x
- type MajorSurgery k = MajorSurgery_ k
- class Perform_ r s => Perform (r :: k -> Type) (s :: MajorSurgery k)
- type Operate (f :: k -> Type) (s :: MajorSurgery k) = Operate_ f s
- data (:>>) :: MajorSurgery k -> MajorSurgery k -> MajorSurgery k
- data IdSurgery :: MajorSurgery k
- data InsertField (n :: Nat) (fd :: Maybe Symbol) (t :: Type) :: MajorSurgery k
- data RemoveField (n :: Nat) (a :: Type) :: MajorSurgery k
- data RemoveRField (fd :: Symbol) (a :: Type) :: MajorSurgery k
- data InsertConstrAt (c :: sym) (n :: Nat) (t :: ty) :: MajorSurgery k
- data RemoveConstr (c :: Symbol) (t :: Type) :: MajorSurgery k
- data Suture :: MajorSurgery k
- type ToORRep a l = ToOR (Rep a) l
- type ToOR f l = (GLinearize f, Linearize f ~ l, f ~ Arborify l)
- type ToORRepLazy a l = ToORLazy (Rep a) l
- type ToORLazy f l = (ToOR (Lazify f) l, Coercible f (Arborify l))
- type FromORRep a l = FromOR (Rep a) l
- type FromOR f l = (GArborify f, Linearize f ~ l, f ~ Arborify l)
- type FromORRepLazy a l = FromORLazy (Rep a) l
- type FromORLazy f l = (FromOR (Lazify f) l, Coercible (Arborify l) f)
- type RmvCField n t lt l = (GRemoveField n t lt l, CFieldSurgery n t lt l)
- type InsCField n t lt l = (GInsertField n t l lt, CFieldSurgery n t lt l)
- type ModCField n t t' lt lt' l = (RmvCField n t lt l, InsCField n t' lt' l)
- type RmvRField fd n t lt l = (GRemoveField n t lt l, RFieldSurgery fd n t lt l)
- type InsRField fd n t lt l = (GInsertField n t l lt, RFieldSurgery fd n t lt l)
- type ModRField fd n t t' lt lt' l = (RmvRField fd n t lt l, InsRField fd n t' lt' l)
- type RmvConstr c n t lc l = (GRemoveConstr n t lc l, ConstrSurgery c n t lc l (Eval (ConstrAt n lc)))
- type InsConstr c n (t :: Type) lc l = (GInsertConstr n t l lc, ConstrSurgery c n t lc l (Eval (ConstrAt n lc)))
- type ModConstr c n t t' lc lc' l = (RmvConstr c n t lc l, InsConstr c n t' lc' l)
- type RmvConstrT c n t lc l = (RmvConstr c n t lc l, IsTuple (Arity (Eval (ConstrAt n lc))) t)
- type InsConstrT c n t lc l = (InsConstr c n t lc l, IsTuple (Arity (Eval (ConstrAt n lc))) t)
- type ModConstrT c n t t' lc lc' l = (ModConstr c n t t' lc lc' l, IsTuple (Arity (Eval (ConstrAt n lc))) t, IsTuple (Arity (Eval (ConstrAt n lc'))) t')

# Surgeries from generic-data and generic-lens

The library generic-data has a Generic.Data.Microsurgery module (since 0.4.0.0) to modify some metadata of generic representations.

If you only want to *update* fields, rather than remove or insert them,
see also the documentation in the above module, on making surgeries out of
generic-lens.

# Synthetic data types

data Data (r :: Type -> Type) p #

Synthetic data type.

A wrapper to view a generic `Rep`

as the datatype it's supposed to
represent, without needing a declaration.

## Instances

Monad r => Monad (Data r) | |

Functor r => Functor (Data r) | |

Applicative r => Applicative (Data r) | |

Foldable r => Foldable (Data r) | |

Defined in Generic.Data.Internal.Data fold :: Monoid m => Data r m -> m # foldMap :: Monoid m => (a -> m) -> Data r a -> m # foldr :: (a -> b -> b) -> b -> Data r a -> b # foldr' :: (a -> b -> b) -> b -> Data r a -> b # foldl :: (b -> a -> b) -> b -> Data r a -> b # foldl' :: (b -> a -> b) -> b -> Data r a -> b # foldr1 :: (a -> a -> a) -> Data r a -> a # foldl1 :: (a -> a -> a) -> Data r a -> a # elem :: Eq a => a -> Data r a -> Bool # maximum :: Ord a => Data r a -> a # minimum :: Ord a => Data r a -> a # | |

Traversable r => Traversable (Data r) | |

Contravariant r => Contravariant (Data r) | |

Eq1 r => Eq1 (Data r) | |

Ord1 r => Ord1 (Data r) | |

Defined in Generic.Data.Internal.Data | |

GShow1 r => Show1 (Data r) | |

Alternative r => Alternative (Data r) | |

MonadPlus r => MonadPlus (Data r) | |

Generic1 (Data r :: Type -> Type) | |

GBounded r => Bounded (Data r p) | |

GEnum StandardEnum r => Enum (Data r p) | |

Defined in Generic.Data.Internal.Data | |

Eq (r p) => Eq (Data r p) | |

Ord (r p) => Ord (Data r p) | |

Defined in Generic.Data.Internal.Data | |

(GShow1 r, Show p) => Show (Data r p) | |

(Functor r, Contravariant r) => Generic (Data r p) | |

Semigroup (r p) => Semigroup (Data r p) | |

Monoid (r p) => Monoid (Data r p) | |

type Rep1 (Data r :: Type -> Type) | |

Defined in Generic.Data.Internal.Data | |

type Rep (Data r p) | |

Defined in Generic.Data.Internal.Data |

toData :: Generic a => a -> Data (Rep a) p #

Conversion between a generic type and the synthetic type made using its
representation. Inverse of `fromData`

.

# Surgeries

## Getting into the operating room

data OR (l :: k -> Type) (x :: k) Source #

*A sterile Operating Room, where generic data comes to be altered.*

Generic representation in a simplified shape `l`

at the type level
(reusing the constructors from GHC.Generics for convenience).
This representation makes it easy to modify fields and constructors.

We may also refer to the representation `l`

as a "row" of constructors,
if it represents a sum type, otherwise it is a "row" of unnamed fields or
record fields for single-constructor types.

`x`

corresponds to the last parameter of `Rep`

, and is currently ignored by
this module (no support for `Generic1`

).

### General sketch

toOR surgeries fromOR' data MyType --------> OR (Rep MyType) ----------> OR alteredRep ---------> Data alteredRep | | myGenericFun :: Generic a => a -> a fromOR surgeries toOR' v data MyType <-------- OR (Rep MyType) <---------- OR alteredRep <--------- Data alteredRep

If instead `myGenericFun`

is only a consumer of `a`

(resp. producer),
then you only need the top half of the diagram (resp. bottom half).
For example, in aeson:
`genericToJSON`

(consumer), `genericParseJSON`

(producer).

toOR :: forall a l x. (Generic a, ToORRep a l) => a -> OR l x Source #

*Move fresh data to the Operating Room, where surgeries can be applied.*

Convert a generic type to a generic representation.

When inserting or removing fields, there may be a mismatch with strict/unpacked fields.
To work around this, you can switch to `toORLazy`

, if your operations don't care about
dealing with a normalized `Rep`

(in which all the strictness annotations have been
replaced with lazy defaults).

### Details

fromOR' :: forall f l x. FromOR f l => OR l x -> Data f x Source #

*Move altered data out of the Operating Room, to be consumed by*
*some generic function.*

Convert a generic representation to a "synthetic" type that behaves like a generic type.

### Details

#### Type parameters

f :: k ->`Type`

--`Generic`

representation (proper) l :: k ->`Type`

-- Generic representation (simplified) x :: k -- Ignored

#### Functional dependencies

f -> l l -> f

#### Implementation details

The synthesized representation is made of balanced binary trees, corresponding closely to what GHC would generate for an actual data type.

That structure assumed by at least one piece of code out there (`aeson`

).

fromOR :: forall a l x. (Generic a, FromORRep a l) => OR l x -> a Source #

*Move restored data out of the Operating Room and back to the real*
*world.*

The inverse of `toOR`

.

It may be useful to annotate the output type of `fromOR`

,
since the rest of the type depends on it and the only way to infer it
otherwise is from the context. The following annotations are possible:

`fromOR`

::`OROf`

a -> a`fromOR`

@a -- with TypeApplications

When inserting or removing fields, there may be a mismatch with strict/unpacked fields.
To work around this, you can switch to `fromORLazy`

, if your operations don't care
about dealing with a normalized `Rep`

(in which all the strictness annotations have
been replaced with lazy defaults).

### Details

toORLazy :: forall a l x. (Generic a, ToORRepLazy a l) => a -> OR l x Source #

*Move normalized data to the Operating Room, where surgeries can be applied.*

Convert a generic type to a generic representation, in which all the strictness annotations have been normalized to lazy defaults.

This variant is useful when one needs to operate on fields whose `Rep`

has different
strictness annotations than the ones used by `DefaultMetaSel`

.

### Details

fromORLazy :: forall a l x. (Generic a, FromORRepLazy a l) => OR l x -> a Source #

*Move normalized data out of the Operating Room and back to the real*
*world.*

The inverse of `toORLazy`

.

It may be useful to annotate the output type of `fromORLazy`

,
since the rest of the type depends on it and the only way to infer it
otherwise is from the context. The following annotations are possible:

`fromORLazy`

::`OROfLazy`

a -> a`fromORLazy`

@a -- with TypeApplications

### Details

type OROfLazy a = OR (Linearize (Lazify (Rep a))) () Source #

The simplified and normalized generic representation type of type `a`

,
that `toORLazy`

and `fromORLazy`

convert to and from.

## Unnamed fields

removeCField :: forall n t lt l x. RmvCField n t lt l => OR lt x -> (t, OR l x) Source #

: remove the `removeCField`

@n @t`n`

-th field, of type `t`

, in a
non-record single-constructor type.

Inverse of `insertCField`

.

### Details

insertCField :: forall n t lt l x. InsCField n t lt l => (t, OR l x) -> OR lt x Source #

: insert a field of type `insertCField`

@n @t`t`

at position `n`

in a non-record single-constructor type.

Inverse of `removeCField`

.

### Details

insertCField' :: forall n t lt l x. InsCField n t lt l => t -> OR l x -> OR lt x Source #

Curried `insertCField`

.

modifyCField :: forall n t t' lt lt' l x. ModCField n t t' lt lt' l => (t -> t') -> OR lt x -> OR lt' x Source #

: modify the field at position `modifyCField`

@n @t @t'`n`

in a
non-record via a function `f :: t -> t'`

(changing the type of the field).

### Details

#### Type parameters

n ::`Nat`

-- Field position t ::`Type`

-- Initial field type t' ::`Type`

-- Final field type lt :: k ->`Type`

-- Row with initial field lt' :: k ->`Type`

-- Row with final field l :: k ->`Type`

-- Row without field x :: k -- Ignored

#### Signature

(t -> t') -- Field modification ->`OR`

lt x -- Data with field t ->`OR`

lt' x -- Data with field t'

#### Functional dependencies

n lt -> t l n lt' -> t' l n t l -> lt n t' l -> lt'

## Named fields (records)

removeRField :: forall fd n t lt l x. RmvRField fd n t lt l => OR lt x -> (t, OR l x) Source #

: remove the field `removeRField`

@"fdName" @n @t`fdName`

at position `n`

of type `t`

in a record type.

Inverse of `insertRField`

.

### Details

#### Type parameters

fd ::`Symbol`

-- Field name n ::`Nat`

-- Field position t ::`Type`

-- Field type lt :: k ->`Type`

-- Row with field l :: k ->`Type`

-- Row without field x :: k -- Ignored

#### Signature

`OR`

lt x -- Data with field -> (t,`OR`

l x) -- Field value × Data without field

#### Functional dependencies

fd lt -> n t l n lt -> fd t l fd n t l -> lt

insertRField :: forall fd n t lt l x. InsRField fd n t lt l => (t, OR l x) -> OR lt x Source #

: insert a field
named `insertRField`

@"fdName" @n @t`fdName`

of type `t`

at position `n`

in a record type.

Inverse of `removeRField`

.

### Details

#### Type parameters

fd ::`Symbol`

-- Field name n ::`Nat`

-- Field position t ::`Type`

-- Field type lt :: k ->`Type`

-- Row with field l :: k ->`Type`

-- Row without field x :: k -- Ignored

#### Signature

(t,`OR`

l x) -- Field value × Data without field ->`OR`

lt x -- Data with field

#### Functional dependencies

fd lt -> n t l n lt -> fd t l fd n t l -> lt

insertRField' :: forall fd n t lt l x. InsRField fd n t lt l => t -> OR l x -> OR lt x Source #

Curried `insertRField`

.

modifyRField :: forall fd n t t' lt lt' l x. ModRField fd n t t' lt lt' l => (t -> t') -> OR lt x -> OR lt' x Source #

: modify the field
`modifyRField`

@"fdName" @n @t @t'`fdName`

at position `n`

in a record via a function `f :: t -> t'`

(changing the type of the field).

### Details

#### Type parameters

fd ::`Symbol`

-- Field name n ::`Nat`

-- Field position t ::`Type`

-- Initial field type t' ::`Type`

-- Final field type lt :: k ->`Type`

-- Row with initial field lt' :: k ->`Type`

-- Row with final field l :: k ->`Type`

-- Row without field x :: k -- Ignored

#### Signature

(t -> t') -- Field modification ->`OR`

lt x -- Data with field t ->`OR`

lt' x -- Data with field t'

#### Functional dependencies

fd lt -> n t l fd lt' -> n t' l n lt -> fd t l n lt' -> fd t' l fd n t l -> lt fd n t' l -> lt'

## Constructors

A constructor is extracted to a "tuple", which can be any
`Generic`

single-constructor type with the same number of
fields.

Note that `()`

and `Identity`

can be used as an
empty and a singleton tuple type respectively.

removeConstr :: forall c n t lc l x. RmvConstr c n t lc l => OR lc x -> Either t (OR l x) Source #

: remove the `removeConstr`

@"C" @n @t`n`

-th constructor, named `C`

,
with contents isomorphic to the tuple `t`

.

Inverse of `insertConstr`

.

### Details

#### Type parameters

c ::`Symbol`

-- Constructor name t ::`Type`

-- Tuple type to hold c's contents n ::`Nat`

-- Constructor position lc :: k ->`Type`

-- Row with constructor l :: k ->`Type`

-- Row without constructor l_t :: k ->`Type`

-- Field row of constructor c x :: k -- Ignored

#### Signature

`OR`

lc x -- Data with constructor -> Either t (`OR`

l x) -- Constructor (as a tuple) | Data without constructor

#### Functional dependencies

c lc -> n l l_t n lc -> c l l_t c n l l_t -> lc

Note that there is no dependency to determine `t`

.

insertConstr :: forall c n t lc l x. InsConstr c n t lc l => Either t (OR l x) -> OR lc x Source #

: insert a constructor `insertConstr`

@"C" @n @t`C`

at position `n`

with contents isomorphic to the tuple `t`

.

Inverse of `removeConstr`

.

### Details

#### Type parameters

c ::`Symbol`

-- Constructor name t ::`Type`

-- Tuple type to hold c's contents n ::`Nat`

-- Constructor position lc :: k ->`Type`

-- Row with constructor l :: k ->`Type`

-- Row without constructor l_t :: k ->`Type`

-- Field row of constructor c x :: k -- Ignored

#### Signature

Either t (`OR`

l x) -- Constructor (as a tuple) | Data without constructor ->`OR`

lc x -- Data with constructor

#### Functional dependencies

c lc -> n l l_t n lc -> c l l_t c n l l_t -> lc

Note that there is no dependency to determine `t`

.

modifyConstr :: forall c n t t' lc lc' l x. ModConstr c n t t' lc lc' l => (t -> t') -> OR lc x -> OR lc' x Source #

: modify the `modifyConstr`

@"C" @n @t @t'`n`

-th constructor,
named `C`

, with contents isomorphic to the tuple `t`

, to another tuple `t'`

.

### Details

#### Type parameters

c ::`Symbol`

-- Constructor name t ::`Type`

-- Tuple type to hold c's initial contents t' ::`Type`

-- Tuple type to hold c's final contents n ::`Nat`

-- Constructor position lc :: k ->`Type`

-- Row with initial constructor lc' :: k ->`Type`

-- Row with final constructor l :: k ->`Type`

-- Row without constructor l_t :: k ->`Type`

-- Initial field row of constructor c l_t' :: k ->`Type`

-- Final field row of constructor c x :: k -- Ignored

#### Signature

(t -> t') -- Constructor modification ->`OR`

lc x -- Data with initial constructor ->`OR`

lc' x -- Data with final constructor

#### Functional dependencies

c lc -> n l l_t c lc' -> n l l_t' n lc -> c l l_t n lc' -> c l l_t' c n l l_t -> lc c n l l_t' -> lc'

Note that there is no dependency to determine `t`

and `t'`

.

### Constructors as tuples

removeConstrT :: forall c n t lc l x. RmvConstrT c n t lc l => OR lc x -> Either t (OR l x) Source #

A variant of `removeConstr`

that can infer the tuple type `t`

to hold
the contents of the removed constructor.

See `removeConstr`

.

### Details

#### Extra functional dependency

l_t -> t

insertConstrT :: forall c n t lc l x. InsConstrT c n t lc l => Either t (OR l x) -> OR lc x Source #

A variant of `insertConstr`

that can infer the tuple type `t`

to hold
the contents of the inserted constructor.

See `insertConstr`

.

### Details

#### Extra functional dependency

l_t -> t

modifyConstrT :: forall c n t t' lc lc' l x. ModConstrT c n t t' lc lc' l => (t -> t') -> OR lc x -> OR lc' x Source #

A variant of `modifyConstr`

that can infer the tuple types `t`

and `t'`

to
hold the contents of the inserted constructor.

See `modifyConstr`

.

### Details

#### Extra functional dependencies

l_t -> t l_t' -> t'

# Surgeries as type-level operations

Example usage: define a synthetic type which adds a `"key"`

field of type `Key`

to an existing record type.

-- Define the surgery to insert a field (key :: Key) -- as the first field (index 0) of a record. type InsertId = (`InsertField`

0 ('`Just`

"key") Key ::`MajorSurgery`

k) -- Define a newtype for synthetic (`Data`

) types obtained from a real type`a`

-- using the`InsertId`

surgery we just defined. newtype WithKey a = WithKey (`Data`

(`Operate`

(`Rep`

a) InsertId) ())

## Types and composition

### Implementation notes

The implementation of these type synonyms is hidden behind names suffixed with an underscore. Although they appear in the haddocks, these auxiliary names are internal and not exported by this module.

type MajorSurgery k = MajorSurgery_ k Source #

Kind of surgeries: operations on generic representations of types.

Treat this as an abstract kind (don't pay attention to its definition).

### Implementation details

The name `Surgery`

got taken first by generic-data.

`k`

is the kind of the extra parameter reserved for `Generic1`

,
which we just don't use.

class Perform_ r s => Perform (r :: k -> Type) (s :: MajorSurgery k) Source #

A constraint `Perform r s`

means that the surgery `s`

can be applied to
the generic representation `r`

.

## Instances

Perform_ r s => Perform (r :: k -> Type) (s :: MajorSurgery k) Source # | |

Defined in Generic.Data.Surgery.Internal |

data (:>>) :: MajorSurgery k -> MajorSurgery k -> MajorSurgery k infixl 1 Source #

Composition of surgeries (left-to-right).

### Note

Surgeries work on normalized representations, so `Operate`

, which applies
a surgery to a generic representation, inserts normalization steps before
and after the surgery. This means that

is not quite
the same as `Operate`

r (s1 `:>>`

s2)

. Instead, the latter is
equivalent to `Operate`

(`Operate`

r s1) s2

, where `Operate`

r (s1 `:>>`

`Suture`

`:>>`

s2)`Suture`

inserts some intermediate normalization steps.

data IdSurgery :: MajorSurgery k Source #

The identity surgery: doesn't do anything.

## Surgeries

data InsertField (n :: Nat) (fd :: Maybe Symbol) (t :: Type) :: MajorSurgery k Source #

## Instances

type PerformL (l :: k -> Type) (InsertField n fd t :: (k -> Type) -> (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type PerformL (l :: k -> Type) (InsertField n fd t :: (k -> Type) -> (k -> Type) -> Type) = PerformLInsert n fd t l (Eval (InsertField n fd t l)) | |

type Eval (InsertField 0 fd t (U1 :: k -> Type) :: (k -> Type) -> Type) Source # | |

type Eval (InsertField n fd t (f :*: g) :: (k -> Type) -> Type) Source # | |

type Eval (InsertField n fd t (f :+: (V1 :: k -> Type)) :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal | |

type Eval (InsertField n fd t (M1 C m f) :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type Eval (InsertField n fd t (M1 C m f) :: (k -> Type) -> Type) = M1 C m (Eval (InsertField n fd t f)) | |

type Eval (InsertField n fd t (M1 D m f) :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type Eval (InsertField n fd t (M1 D m f) :: (k -> Type) -> Type) = M1 D m (Eval (InsertField n fd t f)) |

data RemoveField (n :: Nat) (a :: Type) :: MajorSurgery k Source #

## Instances

type PerformL (lt :: k -> Type) (RemoveField n a :: (k -> Type) -> (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal | |

type Eval (RemoveField n a f :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal |

data RemoveRField (fd :: Symbol) (a :: Type) :: MajorSurgery k Source #

## Instances

type PerformL (lt :: k -> Type) (RemoveRField fd a :: (k -> Type) -> (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal | |

type Eval (RemoveRField fd a f :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type Eval (RemoveRField fd a f :: (k -> Type) -> Type) = Eval (RemoveField_ (Eval (FieldIndex fd f)) f) |

data InsertConstrAt (c :: sym) (n :: Nat) (t :: ty) :: MajorSurgery k Source #

This is polymorphic to allow different ways of specifying the inserted constructor.

If `sym`

(the kind of the constructor name `c`

) is:

`Symbol`

: treat it like a regular prefix constructor.- TODO Infix constructors and their fixities.

`t`

must be a single-constructor type, then we reuse its generic
representation for the new constructor, only replacing its constructor name
with `c`

.

## Instances

type PerformL (l :: Type -> Type) (InsertConstrAt c n t :: (Type -> Type) -> (Type -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type PerformL (l :: Type -> Type) (InsertConstrAt c n t :: (Type -> Type) -> (Type -> Type) -> Type) = PerformLInsertConstrAt0 l c n t | |

type Eval (InsertConstrAt c n t l :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type Eval (InsertConstrAt c n t l :: (k -> Type) -> Type) = Eval (InsertUConstrAtL n (ConGraft c t :: k -> Type) l) |

data RemoveConstr (c :: Symbol) (t :: Type) :: MajorSurgery k Source #

## Instances

type PerformL (lc :: Type -> Type) (RemoveConstr c t :: (Type -> Type) -> (Type -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal | |

type Eval (RemoveConstr c t l :: (k -> Type) -> Type) Source # | |

Defined in Generic.Data.Surgery.Internal type Eval (RemoveConstr c t l :: (k -> Type) -> Type) = Eval (RemoveConstrAt c ((ConstrIndex c :: (k -> Type) -> Nat -> Type) @@ l) t l) |

data Suture :: MajorSurgery k Source #

Use this if a patient ever needs to go out and back into the operating room, when it's not just to undo the surgery up to that point.

# Constraint synonyms

Hiding implementation details from the signatures above.

## Conversions

type ToORRepLazy a l = ToORLazy (Rep a) l Source #

type ToORLazy f l = (ToOR (Lazify f) l, Coercible f (Arborify l)) Source #

Similar to `ToORRepLazy`

, but as a constraint on the standard
generic representation of `a`

directly, `f ~ `

.`Rep`

a

type FromORRepLazy a l = FromORLazy (Rep a) l Source #

type FromORLazy f l = (FromOR (Lazify f) l, Coercible (Arborify l) f) Source #

Similar to `FromLazyORRep`

, but as a constraint on the standard
generic representation of `a`

directly, `f ~ `

.`Rep`

a

## Surgeries

type RmvCField n t lt l = (GRemoveField n t lt l, CFieldSurgery n t lt l) Source #

This constraint means that the (unnamed) field row `lt`

contains
a field of type `t`

at position `n`

, and removing it yields row `l`

.

type InsCField n t lt l = (GInsertField n t l lt, CFieldSurgery n t lt l) Source #

This constraint means that inserting a field `t`

at position `n`

in the
(unnamed) field row `l`

yields row `lt`

.

type ModCField n t t' lt lt' l = (RmvCField n t lt l, InsCField n t' lt' l) Source #

This constraint means that modifying a field `t`

to `t'`

at position `n`

in the (unnamed) field row `lt`

yields row `lt'`

.
`l`

is the row of fields common to `lt`

and `lt'`

.

type RmvRField fd n t lt l = (GRemoveField n t lt l, RFieldSurgery fd n t lt l) Source #

This constraint means that the record field row `lt`

contains a field of
type `t`

named `fd`

at position `n`

, and removing it yields row `l`

.

type InsRField fd n t lt l = (GInsertField n t l lt, RFieldSurgery fd n t lt l) Source #

This constraint means that inserting a field `t`

named `fd`

at position
`n`

in the record field row `l`

yields row `lt`

.

type ModRField fd n t t' lt lt' l = (RmvRField fd n t lt l, InsRField fd n t' lt' l) Source #

This constraint means that modifying a field `t`

named `fd`

at position `n`

to `t'`

in the record field row `lt`

yields row `lt'`

.
`l`

is the row of fields common to `lt`

and `lt'`

.

type RmvConstr c n t lc l = (GRemoveConstr n t lc l, ConstrSurgery c n t lc l (Eval (ConstrAt n lc))) Source #

This constraint means that the constructor row `lc`

contains a constructor
named `c`

at position `n`

, and removing it from `lc`

yields row `l`

.
Furthermore, constructor `c`

contains a field row `l_t`

compatible with the
tuple type `t`

.

type InsConstr c n (t :: Type) lc l = (GInsertConstr n t l lc, ConstrSurgery c n t lc l (Eval (ConstrAt n lc))) Source #

This constraint means that inserting a constructor `c`

at position `n`

in the constructor row `l`

yields row `lc`

.
Furthermore, constructor `c`

contains a field row `l_t`

compatible with the
tuple type `t`

.

type ModConstr c n t t' lc lc' l = (RmvConstr c n t lc l, InsConstr c n t' lc' l) Source #

This constraint means that the constructor row `lc`

contains a constructor
named `c`

at position `n`

of type isomorphic to `t`

, and modifying it to
`t'`

yields row `lc'`

.

type RmvConstrT c n t lc l = (RmvConstr c n t lc l, IsTuple (Arity (Eval (ConstrAt n lc))) t) Source #

A variant of `RmvConstr`

allowing `t`

to be inferred.