packages feed

generic-data 0.6.0.1 → 0.7.0.0

raw patch · 9 files changed

+84/−28 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Generic.Data.Internal.Generically: instance (GHC.Generics.Generic a, GHC.Base.Monoid (GHC.Generics.Rep a ())) => GHC.Base.Monoid (Generic.Data.Internal.Generically.Generically a)
+ Generic.Data: gcoerce :: (Generic a, Generic b, Coercible (Rep a) (Rep b)) => a -> b
+ Generic.Data: gcoerceBinop :: (Generic a, Generic b, Coercible (Rep a) (Rep b)) => (a -> a -> a) -> b -> b -> b
+ Generic.Data.Internal.Generically: instance (GHC.Base.Semigroup a, GHC.Generics.Generic a, GHC.Base.Monoid (GHC.Generics.Rep a ())) => GHC.Base.Monoid (Generic.Data.Internal.Generically.Generically a)
+ Generic.Data.Internal.Utils: coerce1 :: Coercible f g => f x -> g x
+ Generic.Data.Internal.Utils: gcoerce :: (Generic a, Generic b, Coercible (Rep a) (Rep b)) => a -> b
+ Generic.Data.Internal.Utils: gcoerceBinop :: (Generic a, Generic b, Coercible (Rep a) (Rep b)) => (a -> a -> a) -> b -> b -> b

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+# 0.7.0.0++- Changed `Monoid` instance for `Generically`, to be compatible with users'+  non-generic instances of `Semigroup`. Thanks to yairchu.+- Add `gcoerce`, `gcoerceBinop`.+ # 0.6.0.1  - Fix derivation of `Show1` for `(:.:)`
README.md view
@@ -4,7 +4,34 @@  ## Generic deriving for standard classes +### Example: generically deriving Semigroup instances for products++Semi-automatic method using `gmappend`+ ```haskell+data Foo a = Bar [a] [a] deriving Generic++instance Semigroup (Foo a) where+  (<>) = gmappend+```++This library also synergizes with the `DerivingVia` extension+(introduced in GHC 8.6), thanks to the `Generically` newtype.++```haskell+data Foo a = Bar [a] [a]+  deriving Generic+  deriving Semigroup via (Generically (Foo a))+```++These examples can be found in `test/example.hs`.++---++Note for completeness, the first example uses the following extensions and+imports:++```haskell {-# LANGUAGE DeriveGeneric #-}  -- base@@ -12,35 +39,32 @@ import GHC.Generics  -- generic-data-import Generic.Data (gmappend, Generically(..))+import Generic.Data (gmappend) import Generic.Data.Orphans ()--data Foo a = Bar [a] [a] deriving Generic--instance Semigroup (Foo a) where-  (<>) = gmappend+``` --- also with some additional extensions --+The second example makes these additions on top: +```haskell {-# LANGUAGE     DerivingStrategies,     DerivingVia #-}  -- since GHC 8.6.1 -data Foo a = Bar [a] [a]-  deriving Generic-  deriving Semigroup via (Generically (Foo a))---- This example can be found in test/example.hs+-- In addition to the previous imports+import Generic.Data (Generically(..)) ``` +### Supported classes+ Supported classes that GHC currently can't derive: `Semigroup`, `Monoid`, `Applicative`, `Alternative`, `Eq1`, `Ord1`, `Show1`.  Other classes from base are also supported, even though GHC can already derive them: -- `Eq`, `Ord`, `Enum`, `Bounded`, `Show` (standard);-- `Functor`, `Foldable`, `Traversable` (via extensions, `DeriveFunctor`, etc.).+- `Eq`, `Ord`, `Enum`, `Bounded`, `Show` (derivable by the standard);+- `Functor`, `Foldable`, `Traversable` (derivable via extensions,+  `DeriveFunctor`, etc.).  (`Read` is currently not implemented.) @@ -75,12 +99,11 @@  ```haskell {-# LANGUAGE DeriveGeneric #-}- import GHC.Generic (Generic)- import Generic.Data (gshowsPrec) import Generic.Data.Microsurgery (toData, derecordify) +-- An example record type newtype T = T { unT :: Int } deriving Generic  -- Naively deriving Show would result in this being shown:@@ -102,7 +125,6 @@  ```haskell {-# LANGUAGE DeriveGeneric, DerivingVia #-}- import GHC.Generic (Generic)  -- Constructors must be visible to use DerivingVia
generic-data.cabal view
@@ -1,5 +1,5 @@ name:                generic-data-version:             0.6.0.1+version:             0.7.0.0 synopsis:            Deriving instances with GHC.Generics and related utilities description:   Generic implementations of standard type classes.
src/Generic/Data.hs view
@@ -113,6 +113,10 @@   , pack   , unpack +    -- * Generic coercions+  , gcoerce+  , gcoerceBinop+     -- * Accessing metadata      -- | Using @TypeApplications@.@@ -163,3 +167,4 @@ import Generic.Data.Internal.Show import Generic.Data.Internal.Newtype import Generic.Data.Internal.Resolvers+import Generic.Data.Internal.Utils
src/Generic/Data/Internal/Data.hs view
@@ -31,11 +31,11 @@            , Eq, Ord, Eq1, Ord1, Semigroup, Monoid )  -- | Conversion between a generic type and the synthetic type made using its--- representation.+-- representation. Inverse of 'fromData'. toData :: Generic a => a -> Data (Rep a) p toData = Data . from --- | Inverse of 'fromData'.+-- | Inverse of 'toData'. fromData :: Generic a => Data (Rep a) p -> a fromData = to . unData 
src/Generic/Data/Internal/Generically.hs view
@@ -36,9 +36,12 @@ instance (Generic a, Semigroup (Rep a ())) => Semigroup (Generically a) where   (<>) = gmappend -instance (Generic a, Monoid (Rep a ())) => Monoid (Generically a) where+-- | This uses the 'Semigroup' instance of the wrapped type 'a' to define 'mappend'.+-- The purpose of this instance is to derive 'mempty', while remaining consistent+-- with possibly custom 'Semigroup' instances.+instance (Semigroup a, Generic a, Monoid (Rep a ())) => Monoid (Generically a) where   mempty = gmempty-  mappend = gmappend'+  mappend (Generically x) (Generically y) = Generically (x <> y)  instance (Generic a, GEnum StandardEnum (Rep a)) => Enum (Generically a) where   toEnum = gtoEnum
src/Generic/Data/Internal/Microsurgery.hs view
@@ -42,7 +42,7 @@ -- @ type Surgery (s :: *) (a :: *) = Generically (Surgery' s a) --- | See 'Surgery''.+-- | See 'Surgery'. newtype Surgery' (s :: *) (a :: *) = Surgery' { unSurgery' :: a }  instance (Generic a, Coercible (GSurgery s (Rep a)) (Rep a)) => Generic (Surgery' s a) where@@ -78,7 +78,7 @@ -- Concretely, set the last field of 'MetaCons' to 'False' and forget field -- names. ----- This is a defunctionalized symbol, to be applied using 'GSurgery'.+-- This is a defunctionalized symbol, applied using 'GSurgery' or 'Surgery'. data Derecordify :: * type instance GSurgery Derecordify f = GDerecordify f @@ -112,7 +112,7 @@ -- > -- > data Foo = Bar Baz ----- This is a defunctionalized symbol, to be applied using 'GSurgery'.+-- This is a defunctionalized symbol, applied using 'GSurgery' or 'Surgery'. data Typeage :: * type instance GSurgery Typeage (M1 D ('MetaData nm md pk _nt) f) = M1 D ('MetaData nm md pk 'False) f @@ -150,7 +150,7 @@ -- > -- > data Foo = Bar { bag :: Zap } ----- This is a defunctionalized symbol, to be applied using 'GSurgery'.+-- This is a defunctionalized symbol, applied using 'GSurgery' or 'Surgery'. data RenameFields (rnm :: *) :: * type instance GSurgery (RenameFields rnm) f = GRenameFields rnm f @@ -171,7 +171,7 @@ -- > -- > data Foo = Car { baz :: Zap } ----- This is a defunctionalized symbol, to be applied using 'GSurgery'.+-- This is a defunctionalized symbol, applied using 'GSurgery' or 'Surgery'. data RenameConstrs (rnm :: *) :: * type instance GSurgery (RenameConstrs rnm) f = GRenameConstrs rnm f @@ -252,7 +252,7 @@ -- | Apply a type constructor @f@ to every field type of a generic -- representation @r@. ----- This is a defunctionalized symbol, to be applied using 'GSurgery'.+-- This is a defunctionalized symbol, applied using 'GSurgery' or 'Surgery'. data OnFields (f :: * -> *) :: * type instance GSurgery (OnFields f) g = GOnFields f g 
src/Generic/Data/Internal/Utils.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE     BangPatterns,+    FlexibleContexts,     PolyKinds #-}  module Generic.Data.Internal.Utils where@@ -7,9 +8,25 @@ import Data.Coerce import GHC.Generics +-- | Convert between types with representationally equivalent generic+-- representations.+gcoerce+  :: (Generic a, Generic b, Coercible (Rep a) (Rep b))+  => a -> b+gcoerce = to . coerce1 . from++-- | Compose 'gcoerce' with a binary operation.+gcoerceBinop+  :: (Generic a, Generic b, Coercible (Rep a) (Rep b))+  => (a -> a -> a) -> (b -> b -> b)+gcoerceBinop f x y = gcoerce (f (gcoerce x) (gcoerce y))+ -- | Coerce while preserving the type index. coerce' :: Coercible (f x) (g x) => f x -> g x coerce' = coerce++coerce1 :: Coercible f g => f x -> g x+coerce1 = coerce  -- | Elimination of @V1@. absurd1 :: V1 x -> a
test/unit.hs view
@@ -16,6 +16,9 @@ data P a = P a a   deriving (Generic, Generic1) +instance Semigroup a => Semigroup (P a) where+  x <> y = unGenerically (Generically x <> Generically y)+ type PTy a = a -> a -> Generically (P a)  p :: PTy a