generic-functor 1.0.0.0 → 1.1.0.0
raw patch · 5 files changed
+83/−70 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GBifoldable f => Data.Foldable.Foldable (Generic.Functor.Internal.GenericBifunctor f a)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GSecond f => GHC.Base.Functor (Generic.Functor.Internal.GenericBifunctor f a)
Files
- CHANGELOG.md +4/−0
- README.md +64/−63
- generic-functor.cabal +1/−1
- src/Generic/Functor/Internal.hs +13/−3
- test/test.hs +1/−3
CHANGELOG.md view
@@ -1,3 +1,7 @@+## 1.1.0.0++- Add `Functor` and `Foldable` instances for `GenericBifunctor`, anticipating them becoming superclasses of `Bifunctor` and `Bifoldable`+ ## 1.0.0.0 - Split `Generic.Functor`, moving `gsolomap`, `solomap`, `gmultimap`, `multimap` to `Generic.Functor.Multimap`
README.md view
@@ -1,9 +1,71 @@ # Generic functors [](https://hackage.haskell.org/package/generic-functor) [](https://gitlab.com/lysxia/generic-functor/-/commits/main) - Implementation of `Functor` instances and other functor-like structures using `GHC.Generics`. +## Deriving `Functor`++This library enables `DerivingVia` to derive the `Functor` class generically,+via the newtype `GenericFunctor`.++```haskell+{-# LANGUAGE DeriveGeneric, DerivingVia #-}++import GHC.Generics (Generic)+import Generic.Functor (GenericFunctor(..))++data Twice a = Twice (Either a a)+ deriving Generic+ deriving Functor via (GenericFunctor Twice)+```++Note that there is already built-in support for deriving `Functor` in GHC with the+`DeriveFunctor` extension instead. If that extension ever chokes on a type, this+library might have a chance at handling it. (Open an issue if it does not!)++The `Twice` example just above is not handled by the `DeriveFunctor` extension:++```haskell+{-# LANGUAGE DeriveFunctor #-}++data Twice a = Twice (Either a a) deriving Functor++{-+ error:+ • Can't make a derived instance of ‘Functor Twice’:+ Constructor ‘Twice’ must use the type variable only as the last argument of a data type+-}+```++The [*generic-data*][generic-data] library also includes a generic implementation of `Functor`,+but only for instances of `Generic1`, which applies to much more restricted shapes+of `data` than `Generic`.++## Deriving `Bifunctor`++Similarly, we can use `DerivingVia` for the `Bifunctor` class+(from *base*, module `Data.Bifunctor`).++```haskell+{-# LANGUAGE DeriveGeneric, DerivingVia #-}++import GHC.Generics (Generic)+import Generic.Functor (GenericFunctor(..), GenericBifunctor(..))++data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b+ deriving Generic+ deriving Functor via (GenericFunctor (Tree a))+ deriving Bifunctor via (GenericBifunctor Tree)+```++In summary, the newtype `GenericFunctor` can be used for `DerivingVia`+of the classes `Functor` and `Foldable`, and the newtype `GenericBifunctor`+for the classes `Bifunctor` and `Bifoldable`.++Default implementations for the above classes are also available as standalone+functions (`gfmap`, `gfoldMap`, `gbimap`, `gbifoldMap`) and also for+`Traversable` and `Bitraversable` (`gtraverse`, `gbitraverse`).+ ## Functors not over the last type parameter The standard `Functor` class only applies to types that are functors over their@@ -16,7 +78,7 @@ {-# LANGUAGE DeriveGeneric #-} import GHC.Generics (Generic)-import Generic.Functor (gsolomap)+import Generic.Functor.Multimap (gsolomap) data Result a r = Error a | Ok r -- Another name for Either deriving Generic@@ -118,67 +180,6 @@ `gmultimap` and `multimap` are **unsafe**, similarly to `gsolomap` and `solomap`. -## Deriving `Functor`--This library enables `DerivingVia` for the `Functor` class.--```haskell-{-# LANGUAGE DeriveGeneric, DerivingVia #-}--import GHC.Generics (Generic)-import Generic.Functor (GenericFunctor(..))--data Twice a = Twice (Either a a)- deriving Generic- deriving Functor via (GenericFunctor Twice)-```--Note that there is already built-in support for deriving `Functor` in GHC with the-`DeriveFunctor` extension instead. If that extension ever chokes on a type, this-library might have a chance at handling it. (Open an issue if it does not!)--The `Twice` example just above is not handled by the `DeriveFunctor` extension:--```haskell-{-# LANGUAGE DeriveFunctor #-}--data Twice a = Twice (Either a a) deriving Functor--{-- error:- • Can't make a derived instance of ‘Functor Twice’:- Constructor ‘Twice’ must use the type variable only as the last argument of a data type--}-```--The [*generic-data*][generic-data] library also includes a generic implementation of `Functor`,-but only for instances of `Generic1`, which applies to much more restricted shapes-of `data` than `Generic`.--## Deriving `Bifunctor`--Similarly, we can use `DerivingVia` for the `Bifunctor` class-(from *base*, module `Data.Bifunctor`).--```haskell-{-# LANGUAGE DeriveGeneric, DerivingVia #-}--import GHC.Generics (Generic)-import Generic.Functor (GenericFunctor(..), GenericBifunctor(..))--data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b- deriving Generic- deriving Functor via (GenericFunctor (Tree a))- deriving Bifunctor via (GenericBifunctor Tree)-```--In summary, the newtype `GenericFunctor` can be used for `DerivingVia`-of the classes `Functor` and `Foldable`, and the newtype `GenericBifunctor`-for the classes `Bifunctor` and `Bifoldable`.--Default implementations for the above classes are also available as standalone-functions (`gfmap`, `gfoldMap`, `gbimap`, `gbifoldMap`) and also for-`Traversable` and `Bitraversable` (`gtraverse`, `gbitraverse`). ---
generic-functor.cabal view
@@ -1,6 +1,6 @@ cabal-version: >=1.10 name: generic-functor-version: 1.0.0.0+version: 1.1.0.0 synopsis: Deriving generalized functors with GHC.Generics description: Derive @fmap@, and other @fmap@-like functions where the
src/Generic/Functor/Internal.hs view
@@ -371,8 +371,12 @@ -- | @newtype@ for @DerivingVia@ of 'Bifunctor' and 'Bifoldable' instances. ----- Note: deriving 'Bifunctor' for a generic type often requires 'Functor'--- instances for types mentioned in the fields.+-- Note: although 'GenericBifunctor' has 'Functor' and 'Foldable' instances,+-- it is recommended to use 'GenericFunctor' instead for those two classes.+-- They have to use a separate deriving clause from 'Bifunctor' and 'Bifoldable' anyway.+-- Those instances exist because they are to become superclasses of 'Bifunctor'+-- and 'Bifoldable'. The 'Foldable' instance of 'GenericBifunctor' is also less+-- efficient than 'GenericFunctor' unless the extra @const mempty@ gets optimized away. -- -- === Example --@@ -398,10 +402,16 @@ instance GBifunctor f => Bifunctor (GenericBifunctor f) where bimap = coerce2 (gbimap @f) first = coerce3 (gfirst @f)- second = coerce3 (gsecond @f)+ second = fmap instance GBifoldable f => Bifoldable (GenericBifunctor f) where bifoldMap = coerceBifoldMap (gbifoldMap @f)++instance GSecond f => Functor (GenericBifunctor f a) where+ fmap = coerce3 (gsecond @f)++instance GBifoldable f => Foldable (GenericBifunctor f a) where+ foldMap = bifoldMap (const mempty) -- ** Internal coercions
test/test.hs view
@@ -120,10 +120,8 @@ data CofreeF f a b = a :< f b deriving (Eq, Show, Generic)+ deriving (Functor, Foldable) via (GenericFunctor (CofreeF f a)) deriving (Bifunctor, Bifoldable) via (GenericBifunctor (CofreeF f))--deriving via GenericFunctor (CofreeF f a) instance Foldable f => Foldable (CofreeF f a)-deriving via GenericFunctor (CofreeF f a) instance Functor f => Functor (CofreeF f a) instance Traversable f => Traversable (CofreeF f a) where traverse = gtraverse