generic-data-1.0.0.0: Deriving instances with GHC.Generics and related utilities
Safe HaskellNone
LanguageHaskell2010

Generic.Data.Internal.Microsurgery

Description

Surgeries that are just coerce.

Warning

This is an internal module: it is not subject to any versioning policy, breaking changes can happen at any time.

If something here seems useful, please report it or create a pull request to export it from an external module.

Synopsis

Surgery

type Surgery (s :: *) (a :: *) = Generically (Surgery' s a) Source #

Apply a microsurgery s to a type a for DerivingVia.

For the Monoid class, see ProductSurgery.

Example

{-# LANGUAGE DerivingVia #-}

-- The constructors must be visible.
import Generic.Data.Microsurgery
  (Surgery, Surgery'(..), Generically(..), Derecordify)

data T = T { unT :: Int }
  deriving Show via (Surgery Derecordify T)

-- T won't be shown as a record:
--   show (T {unT = 3}) == "T 3"

type ProductSurgery (s :: *) (a :: *) = GenericProduct (Surgery' s a) Source #

Apply a microsurgery s to a type a for DerivingVia for the Monoid class.

type Surgeries (s :: [*]) (a :: *) = Surgery (Cat s) a Source #

Plural of Surgery. Apply a list of microsurgeries.

type ProductSurgeries (s :: [*]) (a :: *) = ProductSurgery (Cat s) a Source #

Plural of ProductSurgery. Apply a list of microsurgeries.

newtype Surgery' (s :: *) (a :: *) Source #

See Surgery.

Constructors

Surgery' 

Fields

Instances

Instances details
(Generic a, Coercible (GSurgery s (Rep a)) (Rep a)) => Generic (Surgery' s a) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

Associated Types

type Rep (Surgery' s a) :: Type -> Type #

Methods

from :: Surgery' s a -> Rep (Surgery' s a) x #

to :: Rep (Surgery' s a) x -> Surgery' s a #

type Rep (Surgery' s a) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type Rep (Surgery' s a) = GSurgery s (Rep a)

type family GSurgery (s :: *) (f :: k -> *) :: k -> * Source #

Apply a microsurgery represented by a symbol s (declared as a dummy data type) to a generic representation f.

Instances

Instances details
type GSurgery Derecordify (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery Derecordify (f :: k -> Type) = GDerecordify f
type GSurgery Typeage (M1 D ('MetaData nm md pk _nt) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery Typeage (M1 D ('MetaData nm md pk _nt) f :: k -> Type) = M1 D ('MetaData nm md pk 'False) f
type GSurgery (CopyRep a) (_1 :: Type -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (CopyRep a) (_1 :: Type -> Type) = Rep a
type GSurgery (RenameFields rnm) (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (RenameFields rnm) (f :: k -> Type) = GRenameFields rnm f
type GSurgery (RenameConstrs rnm) (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (RenameConstrs rnm) (f :: k -> Type) = GRenameConstrs rnm f
type GSurgery (OnFields f) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (OnFields f) (g :: k -> Type) = GOnFields f g
type GSurgery (Cat (s ': ss)) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (Cat (s ': ss)) (g :: k -> Type) = GSurgery s (GSurgery (Cat ss) g)
type GSurgery (Cat ('[] :: [Type])) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (Cat ('[] :: [Type])) (g :: k -> Type) = g
type GSurgery (OnField s f) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (OnField s f) (g :: k -> Type) = GOnField s f g

Derecordify

data Derecordify :: * Source #

Forget that a type was declared using record syntax.

data Foo = Bar { baz :: Zap }

-- becomes --

data Foo = Bar Zap

Concretely, set the last field of MetaCons to False and forget field names.

This is a defunctionalized symbol, applied using GSurgery or Surgery.

Instances

Instances details
type GSurgery Derecordify (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery Derecordify (f :: k -> Type) = GDerecordify f

type family GDerecordify (f :: k -> *) :: k -> * Source #

Instances

Instances details
type GDerecordify (U1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (U1 :: k -> Type) = U1 :: k -> Type
type GDerecordify (V1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (V1 :: k -> Type) = V1 :: k -> Type
type GDerecordify (f :*: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (f :+: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (M1 S ('MetaSel _nm su ss ds) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (M1 S ('MetaSel _nm su ss ds) f :: k -> Type) = M1 S ('MetaSel ('Nothing :: Maybe Symbol) su ss ds) f
type GDerecordify (M1 C ('MetaCons nm fx _isRecord) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (M1 C ('MetaCons nm fx _isRecord) f :: k -> Type) = M1 C ('MetaCons nm fx 'False) (GDerecordify f)
type GDerecordify (M1 D m f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GDerecordify (M1 D m f :: k -> Type) = M1 D m (GDerecordify f)

Type aging ("denewtypify")

data Typeage :: * Source #

Forget that a type is a newtype. (The pun is that "aging" a type makes it no longer "new".)

newtype Foo = Bar Baz

-- becomes --

data Foo = Bar Baz

This is a defunctionalized symbol, applied using GSurgery or Surgery.

Instances

Instances details
type GSurgery Typeage (M1 D ('MetaData nm md pk _nt) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery Typeage (M1 D ('MetaData nm md pk _nt) f :: k -> Type) = M1 D ('MetaData nm md pk 'False) f

Renaming

renameFields :: forall rnm f p. Coercible (GSurgery (RenameFields rnm) f) f => Data f p -> Data (GSurgery (RenameFields rnm) f) p Source #

unrenameFields :: forall rnm f p. Coercible (GSurgery (RenameFields rnm) f) f => Data f p -> Data (GSurgery (RenameFields rnm) f) p Source #

renameConstrs :: forall rnm f p. Coercible (GSurgery (RenameConstrs rnm) f) f => Data f p -> Data (GSurgery (RenameConstrs rnm) f) p Source #

unrenameConstrs :: forall rnm f p. Coercible (GSurgery (RenameConstrs rnm) f) f => Data f p -> Data (GSurgery (RenameConstrs rnm) f) p Source #

data RenameFields (rnm :: *) :: * Source #

Rename fields using the function rnm given as a parameter.

data Foo = Bar { baz :: Zap }

-- becomes, renaming "baz" to "bag" --

data Foo = Bar { bag :: Zap }

This is a defunctionalized symbol, applied using GSurgery or Surgery.

Instances

Instances details
type GSurgery (RenameFields rnm) (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (RenameFields rnm) (f :: k -> Type) = GRenameFields rnm f

type family GRenameFields (rnm :: *) (f :: k -> *) :: k -> * Source #

Instances

Instances details
type GRenameFields rnm (U1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (U1 :: k -> Type) = U1 :: k -> Type
type GRenameFields rnm (V1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (V1 :: k -> Type) = V1 :: k -> Type
type GRenameFields rnm (f :*: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (f :*: g :: k -> Type) = GRenameFields rnm f :*: GRenameFields rnm g
type GRenameFields rnm (f :+: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (f :+: g :: k -> Type) = GRenameFields rnm f :+: GRenameFields rnm g
type GRenameFields rnm (M1 C m f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (M1 C m f :: k -> Type) = M1 C m (GRenameFields rnm f)
type GRenameFields rnm (M1 D m f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (M1 D m f :: k -> Type) = M1 D m (GRenameFields rnm f)
type GRenameFields rnm (M1 S ('MetaSel ('Just nm) su ss ds) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameFields rnm (M1 S ('MetaSel ('Just nm) su ss ds) f :: k -> Type) = M1 S ('MetaSel ('Just (rnm @@ nm)) su ss ds) f

data RenameConstrs (rnm :: *) :: * Source #

Rename constructors using the function rnm given as a parameter.

data Foo = Bar { baz :: Zap }

-- becomes, renaming "Bar" to "Car" --

data Foo = Car { baz :: Zap }

This is a defunctionalized symbol, applied using GSurgery or Surgery.

Instances

Instances details
type GSurgery (RenameConstrs rnm) (f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (RenameConstrs rnm) (f :: k -> Type) = GRenameConstrs rnm f

type family GRenameConstrs (rnm :: *) (f :: k -> *) :: k -> * Source #

Instances

Instances details
type GRenameConstrs rnm (V1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameConstrs rnm (V1 :: k -> Type) = V1 :: k -> Type
type GRenameConstrs rnm (f :*: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameConstrs rnm (f :*: g :: k -> Type) = GRenameConstrs rnm f :*: GRenameConstrs rnm g
type GRenameConstrs rnm (f :+: g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameConstrs rnm (f :+: g :: k -> Type) = GRenameConstrs rnm f :+: GRenameConstrs rnm g
type GRenameConstrs rnm (M1 D m f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameConstrs rnm (M1 D m f :: k -> Type) = M1 D m (GRenameConstrs rnm f)
type GRenameConstrs rnm (M1 C ('MetaCons nm fi ir) f :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GRenameConstrs rnm (M1 C ('MetaCons nm fi ir) f :: k -> Type) = M1 C ('MetaCons (rnm @@ nm) fi ir) f

Defining symbol functions

type family (f :: *) @@ (s :: Symbol) :: Symbol Source #

f @@ s is the application of a type-level function symbolized by f to a s :: Symbol.

A function FooToBar can be defined as follows:

data FooToBar
type instance FooToBar @@ "foo" = "bar"

Instances

Instances details
type SError @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type SError @@ s = TypeError ('Text "Invalid name: " :<>: 'ShowType s) :: Symbol
type SId @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type SId @@ s = s
type (SConst z) @@ _s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type (SConst z) @@ _s = z
type (SRename xs f) @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type (SRename xs f) @@ s = SRename' xs f s

data SId Source #

Identity function Symbol -> Symbol.

Instances

Instances details
type SId @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type SId @@ s = s

data SError Source #

Empty function (compile-time error when applied).

Instances

Instances details
type SError @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type SError @@ s = TypeError ('Text "Invalid name: " :<>: 'ShowType s) :: Symbol

data SConst (s :: Symbol) Source #

Constant function.

Instances

Instances details
type (SConst z) @@ _s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type (SConst z) @@ _s = z

data SRename (xs :: [(Symbol, Symbol)]) (f :: *) Source #

Define a function for a fixed set of strings, and fall back to f for the others.

Instances

Instances details
type (SRename xs f) @@ s Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type (SRename xs f) @@ s = SRename' xs f s

type family SRename' (xs :: [(Symbol, Symbol)]) (f :: *) (s :: Symbol) where ... Source #

Closed type family for SRename.

Equations

SRename' '[] f s = f @@ s 
SRename' ('(s, t) ': _xs) _f s = t 
SRename' ('(_r, _t) ': xs) f s = SRename' xs f s 

Other

class UnifyRep (f :: k -> *) (g :: k -> *) Source #

Unify the "spines" of two generic representations (the "spine" is everything except the field types).

Instances

Instances details
g' ~ (V1 :: k -> Type) => UnifyRep (V1 :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

g' ~ (U1 :: k -> Type) => UnifyRep (U1 :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

g' ~ (K1 i b :: k -> Type) => UnifyRep (K1 i a :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

(g' ~ (g1 :*: g2), UnifyRep f1 g1, UnifyRep f2 g2) => UnifyRep (f1 :*: f2 :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

(g' ~ (g1 :+: g2), UnifyRep f1 g1, UnifyRep f2 g2) => UnifyRep (f1 :+: f2 :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

(g' ~ M1 s c g, UnifyRep f g) => UnifyRep (M1 s c f :: k -> Type) (g' :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

onData :: (UnifyRep r s, UnifyRep s r) => p (Data r x) (Data s y) -> p (Data r x) (Data s y) Source #

onData :: _ => (Data r x -> Data s y) -> (Data r x -> Data s y)  -- possible specialization

Can be used with generic-lens for type-changing field updates with field_ (and possibly other generic optics).

A specialization of the identity function to be used to fix types of functions on Data, unifying the "spines" of input and output generic representations (the "spine" is everything except field types, which may thus change).

data OnFields (f :: * -> *) :: * Source #

Apply a type constructor f to every field type of a generic representation r.

data Color = RGB
  { r :: Int
  , g :: Int
  , b :: Int }

-- becomes --

data Color f = RGB
  { r :: f Int
  , g :: f Int
  , b :: f Int }

This is a defunctionalized symbol, applied using GSurgery or Surgery.

Instances

Instances details
type GSurgery (OnFields f) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (OnFields f) (g :: k -> Type) = GOnFields f g

type family GOnFields (f :: * -> *) (g :: k -> *) :: k -> * Source #

Instances

Instances details
type GOnFields f (V1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (V1 :: k -> Type) = V1 :: k -> Type
type GOnFields f (U1 :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (U1 :: k -> Type) = U1 :: k -> Type
type GOnFields f (K1 i a :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (K1 i a :: k -> Type) = K1 i (f a) :: k -> Type
type GOnFields f (r :*: s :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (r :*: s :: k -> Type) = GOnFields f r :*: GOnFields f s
type GOnFields f (r :+: s :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (r :+: s :: k -> Type) = GOnFields f r :+: GOnFields f s
type GOnFields f (M1 s m r :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GOnFields f (M1 s m r :: k -> Type) = M1 s m (GOnFields f r)

type DOnFields (f :: * -> *) (a :: *) = Data (GSurgery (OnFields f) (Rep a)) () Source #

Apply a type constructor f to every field type of a type a to make a synthetic type.

data OnField (s :: Symbol) (f :: * -> *) :: * Source #

Apply a type constructor f to the field named s in a generic record r.

data Vec a = Vec
  { len :: Int
  , contents :: [a] }

-- with (OnField "len" Sum) becomes --

data Vec a = Vec
  { len :: Sum Int
  , contents :: [a] }

This is a defunctionalized symbol, applied using GSurgery or Surgery. See also the synonym (%~).

Instances

Instances details
type GSurgery (OnField s f) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (OnField s f) (g :: k -> Type) = GOnField s f g

type family GOnField (x :: Symbol) (f :: * -> *) (g :: k -> *) :: k -> * where ... Source #

Equations

GOnField x f (M1 S ('MetaSel ('Just x) a b c) (K1 i t)) = M1 S ('MetaSel ('Just x) a b c) (K1 i (f t)) 
GOnField x f (M1 S m r) = M1 S m r 
GOnField x f (M1 C m r) = M1 C m (GOnField x f r) 
GOnField x f (M1 D m r) = M1 D m (GOnField x f r) 
GOnField x f (r :+: s) = GOnField x f r :+: GOnField x f s 
GOnField x f (r :*: s) = GOnField x f r :*: GOnField x f s 
GOnField x f (K1 i a) = K1 i (f a) 
GOnField x f U1 = U1 
GOnField x f V1 = V1 

type (%~) = OnField infixr 4 Source #

Infix name for OnField. To be used with Surgeries or Cat.

Examples

Expand

Transform one Int field into Sum Int for deriving Monoid:

data Vec a = Vec
  { len :: Int
  , contents :: [a] }
  deriving Generic
  deriving (Eq, Show) via Generically (Vec a)
  deriving (Semigroup, Monoid) via ProductSurgeries '["len" %~ Sum] (Vec a)

Wrap unshowable fields in Opaque for deriving Show:

data Unshowable = Unshowable
  { fun :: Int -> Int
  , io :: IO Bool
  , int :: Int }
  deriving Generic
  deriving Show via Surgeries '["fun" %~ Opaque, "io" %~ Opaque] Unshowable

-- show (Unshowable id (pure True) 42) = "Unshowable _ _ 42"

data Cat (ss :: [*]) :: * Source #

Compose surgeries together.

Instances

Instances details
type GSurgery (Cat (s ': ss)) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (Cat (s ': ss)) (g :: k -> Type) = GSurgery s (GSurgery (Cat ss) g)
type GSurgery (Cat ('[] :: [Type])) (g :: k -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (Cat ('[] :: [Type])) (g :: k -> Type) = g

type DCat (ss :: [*]) (a :: *) = Data (GSurgery (Cat ss) (Rep a)) () Source #

Make a synthetic type (Data) by chaining multiple surgeries.

data CopyRep (a :: *) :: * Source #

Change the generic representation to that of another type a.

Instances

Instances details
type GSurgery (CopyRep a) (_1 :: Type -> Type) Source # 
Instance details

Defined in Generic.Data.Internal.Microsurgery

type GSurgery (CopyRep a) (_1 :: Type -> Type) = Rep a

copyRep :: forall a f p. Coercible (GSurgery (CopyRep a) f) f => Data f p -> Data (GSurgery (CopyRep a) f) p Source #

uncopyRep :: forall a f p. Coercible f (GSurgery (CopyRep a) f) => Data (GSurgery (CopyRep a) f) p -> Data f p Source #