-- | 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 annotated with \"functional dependencies\", with a meaning -- similar to the homonymous GHC extension for type classes (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. module Generic.Data.Surgery ( Data , toData , fromData , onData -- Microsurgery -- One common and simple situation is to wrap a couple of fields in some -- newtype. You can leverage the @generic-lens@ library with the three -- functions below. -- -- @ -- over :: ASetter s t a b -> (a -> b) -> s -> t -- from lens or microlens -- field :: HasField s t a b => Lens s t a b -- from generic-lens -- @ -- -- For example, to wrap a field named @hidden@ in a newtype like -- 'Generic.Data.Opaque' in some record type @R@: -- -- @ -- 'onData' (over (field @"hidden") 'Generic.Data.Opaque') . 'toData' -- :: R -> Data _ _ -- @ -- -- The result is a type, that from the point of view of "GHC.Generics" -- looks just like @R@ but with the field @hidden@ wrapped. -- * Getting into the operating room , OR , toOR , fromOR' , toOR' , fromOR , OROf -- * Surgeries -- ** Unnamed fields , removeCField , insertCField , insertCField' , modifyCField -- ** Named fields (records) , removeRField , insertRField , insertRField' , modifyRField -- ** Constructors -- | A constructor is extracted to a "tuple", which can be any -- 'GHC.Generics.Generic' single-constructor type with the same number of -- fields. -- -- Note that @()@ and 'Data.Functor.Identity.Identity' can be used as an -- empty and a singleton tuple type respectively. -- -- When the tuple type can't be inferred and doesn't really matter, -- an alternative to explicit type annotations is to use the @...ConstrT@ -- variants of these surgeries, which are specialized to actual tuples -- (@()@, 'Data.Functor.Identity.Identity', @(,)@, @(,,)@, up to 7 --- -- because that's where 'GHC.Generics.Generic' instances currently stop). , removeConstr , insertConstr , modifyConstr , removeConstrT , insertConstrT , modifyConstrT -- * Constraint synonyms -- | Hiding implementation details from the signatures above. -- Useful to compose surgeries in a reusable way. -- ** Conversions , ToORRep , ToOR , FromORRep , FromOR -- ** Surgeries , RmvCField , InsCField , ModCField , RmvRField , InsRField , ModRField , RmvConstr , InsConstr , ModConstr , RmvConstrT , InsConstrT , ModConstrT ) where import Generic.Data.Internal.Data import Generic.Data.Surgery.Internal