packages feed

generic-functor 0.1.0.0 → 0.2.0.0

raw patch · 9 files changed

+1312/−872 lines, 9 filesdep +ap-normalizedep +transformersdep ~basesetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: ap-normalize, transformers

Dependency ranges changed: base

API changes (from Hackage documentation)

- Generic.Functor: DeriveBifunctor :: f a b -> DeriveBifunctor f a b
- Generic.Functor: DeriveFunctor :: f a -> DeriveFunctor f a
- Generic.Functor: newtype DeriveBifunctor f a b
- Generic.Functor: newtype DeriveFunctor f a
- Generic.Functor.Internal: (:+) :: a -> b -> (:+) a b
- Generic.Functor.Internal: DeriveBifunctor :: f a b -> DeriveBifunctor f a b
- Generic.Functor.Internal: DeriveFunctor :: f a -> DeriveFunctor f a
- Generic.Functor.Internal: S :: arr -> arr' -> S arr arr'
- Generic.Functor.Internal: class GMap1 ((a -> b) :+ (c -> d) :+ ()) (Rep (f a c)) (Rep (f b d)) => GBifunctorRep a b c d f
- Generic.Functor.Internal: class Multimap_ arr x y
- Generic.Functor.Internal: data S arr arr'
- Generic.Functor.Internal: data a :+ b
- Generic.Functor.Internal: gmap1 :: GMap1 arr f g => arr -> f () -> g ()
- Generic.Functor.Internal: infixr 1 :+
- Generic.Functor.Internal: instance (Data.Bifunctor.Bifunctor f, Generic.Functor.Internal.Multimap arr x1 y1, Generic.Functor.Internal.Multimap arr x2 y2) => Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (f x1 x2) (f y1 y2)
- Generic.Functor.Internal: instance (GHC.Base.Functor (f x), Generic.Functor.Internal.Multimap arr x2 y2) => Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (f x x2) (f x y2)
- Generic.Functor.Internal: instance (GHC.Base.Functor f, Generic.Functor.Internal.Multimap arr x y) => Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (f x) (f y)
- Generic.Functor.Internal: instance (Generic.Functor.Internal.GBifunctor f, Generic.Functor.Internal.GFirst f, Generic.Functor.Internal.GSecond f) => Data.Bifunctor.Bifunctor (Generic.Functor.Internal.DeriveBifunctor f)
- Generic.Functor.Internal: instance (Generic.Functor.Internal.GMap1 arr f1 g1, Generic.Functor.Internal.GMap1 arr f2 g2) => Generic.Functor.Internal.GMap1 arr (f1 GHC.Generics.:*: f2) (g1 GHC.Generics.:*: g2)
- Generic.Functor.Internal: instance (Generic.Functor.Internal.GMap1 arr f1 g1, Generic.Functor.Internal.GMap1 arr f2 g2) => Generic.Functor.Internal.GMap1 arr (f1 GHC.Generics.:+: f2) (g1 GHC.Generics.:+: g2)
- Generic.Functor.Internal: instance (Generic.Functor.Internal.Multimap arr y1 x1, Generic.Functor.Internal.Multimap arr x2 y2) => Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (x1 -> x2) (y1 -> y2)
- Generic.Functor.Internal: instance (forall a c. GHC.Generics.Generic (f a c), forall a b c d. Generic.Functor.Internal.GBifunctorRep a b c d f) => Generic.Functor.Internal.GBifunctor f
- Generic.Functor.Internal: instance Generic.Functor.Internal.GFunctor f => GHC.Base.Functor (Generic.Functor.Internal.DeriveFunctor f)
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 ((a -> b) Generic.Functor.Internal.:+ ((c -> d) Generic.Functor.Internal.:+ ())) (GHC.Generics.Rep (f a c)) (GHC.Generics.Rep (f b d)) => Generic.Functor.Internal.GBifunctorRep a b c d f
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 ((a -> b) Generic.Functor.Internal.:+ ()) (GHC.Generics.Rep (f a c)) (GHC.Generics.Rep (f b c)) => Generic.Functor.Internal.GFirstRep a b c f
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 ((a -> b) Generic.Functor.Internal.:+ ()) (GHC.Generics.Rep (f a)) (GHC.Generics.Rep (f b)) => Generic.Functor.Internal.GFunctorRep a b f
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 ((a -> b) Generic.Functor.Internal.:+ ()) (GHC.Generics.Rep x) (GHC.Generics.Rep y) => Generic.Functor.Internal.GSolomap a b x y
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 arr (GHC.Generics.Rep x) (GHC.Generics.Rep y) => Generic.Functor.Internal.GMultimap arr x y
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 arr GHC.Generics.U1 GHC.Generics.U1
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 arr GHC.Generics.V1 GHC.Generics.V1
- Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 arr f g => Generic.Functor.Internal.GMap1 arr (GHC.Generics.M1 i c f) (GHC.Generics.M1 i' c'' g)
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap ((a -> b) Generic.Functor.Internal.:+ ()) x y => Generic.Functor.Internal.Solomap a b x y
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap arr x y => Generic.Functor.Internal.GMap1 arr (GHC.Generics.K1 i x) (GHC.Generics.K1 i' y)
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ((a -> b) Generic.Functor.Internal.:+ arr')) a b
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (f x y) (f x y)
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) (f x) (f x)
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ()) x x
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr arr') x y => Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S arr ((a -> b) Generic.Functor.Internal.:+ arr')) x y
- Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap_ (Generic.Functor.Internal.S2 arr) x y => Generic.Functor.Internal.Multimap arr x y
- Generic.Functor.Internal: multimap_ :: Multimap_ arr x y => arr -> x -> y
- Generic.Functor.Internal: newtype DeriveBifunctor f a b
- Generic.Functor.Internal: newtype DeriveFunctor f a
- Generic.Functor.Internal: s2 :: arr -> S2 arr
- Generic.Functor.Internal: type S2 arr = S arr arr
+ Generic.Functor: GenericBifunctor :: f a b -> GenericBifunctor f a b
+ Generic.Functor: GenericFunctor :: f a -> GenericFunctor f a
+ Generic.Functor: class (forall a b. Generic (t a b), forall a b c d. GBifoldMapRep a b c d m t) => GBifoldMap m t
+ Generic.Functor: class (forall m. Monoid m => GBifoldMap m t) => GBifoldable t
+ Generic.Functor: class (forall a c. Generic (f a c), forall a b c d. GBimapRep a b c d f) => GBimap f
+ Generic.Functor: class (forall f. Applicative f => GBitraverse f t) => GBitraversable t
+ Generic.Functor: class (forall a b. Generic (t a b), forall a b c d. GBitraverseRep a b c d f t) => GBitraverse f t
+ Generic.Functor: class (forall a. Generic (t a), forall a b. GFoldMapRep a b m t) => GFoldMap m t
+ Generic.Functor: class (forall m. Monoid m => GFoldMap m t) => GFoldable t
+ Generic.Functor: class (forall f. Applicative f => GBitraverse f t) => GTraversable t
+ Generic.Functor: class (forall a. Generic (t a), forall a b. GTraverseRep a b f t) => GTraverse f t
+ Generic.Functor: gbifoldMap :: forall t m a b. (GBifoldMap m t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+ Generic.Functor: gbitraverse :: forall t f a b c d. (GBitraverse f t, Applicative f) => (a -> f b) -> (c -> f d) -> t a c -> f (t b d)
+ Generic.Functor: gfoldMap :: forall t m a. (GFoldMap m t, Monoid m) => (a -> m) -> t a -> m
+ Generic.Functor: gtraverse :: forall t f a b. (GTraverse f t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Generic.Functor: newtype GenericBifunctor f a b
+ Generic.Functor: newtype GenericFunctor f a
+ Generic.Functor.Internal: GenericBifunctor :: f a b -> GenericBifunctor f a b
+ Generic.Functor.Internal: GenericFunctor :: f a -> GenericFunctor f a
+ Generic.Functor.Internal: class (forall a b. Generic (t a b), forall a b c d. GBifoldMapRep a b c d m t) => GBifoldMap m t
+ Generic.Functor.Internal: class GFoldMap1 m (Default Incoherent (Fold m a b :+ Fold m c d)) (Rep (t a c)) (Rep (t b d)) => GBifoldMapRep a b c d m t
+ Generic.Functor.Internal: class (forall m. Monoid m => GBifoldMap m t) => GBifoldable t
+ Generic.Functor.Internal: class (forall a c. Generic (f a c), forall a b c d. GBimapRep a b c d f) => GBimap f
+ Generic.Functor.Internal: class GMap1 (Default Incoherent ((a -> b) :+ (c -> d))) (Rep (f a c)) (Rep (f b d)) => GBimapRep a b c d f
+ Generic.Functor.Internal: class (forall f. Applicative f => GBitraverse f t) => GBitraversable t
+ Generic.Functor.Internal: class (forall a b. Generic (t a b), forall a b c d. GBitraverseRep a b c d f t) => GBitraverse f t
+ Generic.Functor.Internal: class GTraverse1 f (Default Incoherent ((a -> f b) :+ (c -> f d))) (Rep (t a c)) (Rep (t b d)) => GBitraverseRep a b c d f t
+ Generic.Functor.Internal: class (forall a. Generic (t a), forall a b. GFoldMapRep a b m t) => GFoldMap m t
+ Generic.Functor.Internal: class GMultimapK (Const (EndoM m)) arr f g => GFoldMap1 m arr f g
+ Generic.Functor.Internal: class GFoldMap1 m (Default Incoherent (Fold m a b)) (Rep (t a)) (Rep (t b)) => GFoldMapRep a b m t
+ Generic.Functor.Internal: class (forall m. Monoid m => GFoldMap m t) => GFoldable t
+ Generic.Functor.Internal: class GMultimapK m arr f g
+ Generic.Functor.Internal: class (forall f. Applicative f => GBitraverse f t) => GTraversable t
+ Generic.Functor.Internal: class (forall a. Generic (t a), forall a b. GTraverseRep a b f t) => GTraverse f t
+ Generic.Functor.Internal: class GMultimapK (Aps m) arr f g => GTraverse1 m arr f g
+ Generic.Functor.Internal: class GTraverse1 f (Default Incoherent (a -> f b)) (Rep (t a)) (Rep (t b)) => GTraverseRep a b f t
+ Generic.Functor.Internal: coerceBifoldMap :: Coercible t u => (am -> bm -> t -> m) -> am -> bm -> u -> m
+ Generic.Functor.Internal: coerceFoldMap :: Coercible t u => (am -> t -> m) -> am -> u -> m
+ Generic.Functor.Internal: foldToConst :: Monoid m => Fold m x y -> x -> Const (EndoM m) y
+ Generic.Functor.Internal: gbifoldMap :: forall t m a b. (GBifoldMap m t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+ Generic.Functor.Internal: gbitraverse :: forall t f a b c d. (GBitraverse f t, Applicative f) => (a -> f b) -> (c -> f d) -> t a c -> f (t b d)
+ Generic.Functor.Internal: gfoldMap :: forall t m a. (GFoldMap m t, Monoid m) => (a -> m) -> t a -> m
+ Generic.Functor.Internal: gfoldMapRep :: forall m arr f. (GFoldMap1 m arr f f, Monoid m) => arr -> f () -> m
+ Generic.Functor.Internal: gmapRep :: GMap1 arr f g => arr -> f () -> g ()
+ Generic.Functor.Internal: gmultimapK :: GMultimapK m arr f g => arr -> f () -> m (g ())
+ Generic.Functor.Internal: gtraverse :: forall t f a b. (GTraverse f t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Generic.Functor.Internal: gtraverseRep :: GTraverse1 m arr f g => arr -> f () -> Aps m (g ())
+ Generic.Functor.Internal: instance (Generic.Functor.Internal.GBimap f, Generic.Functor.Internal.GFirst f, Generic.Functor.Internal.GSecond f) => Generic.Functor.Internal.GBifunctor f
+ Generic.Functor.Internal: instance (Generic.Functor.Internal.GMultimapK m arr f g, GHC.Base.Functor m) => Generic.Functor.Internal.GMultimapK m arr (GHC.Generics.M1 i c f) (GHC.Generics.M1 i' c' g)
+ Generic.Functor.Internal: instance (Generic.Functor.Internal.GMultimapK m arr f1 g1, Generic.Functor.Internal.GMultimapK m arr f2 g2, GHC.Base.Applicative m) => Generic.Functor.Internal.GMultimapK m arr (f1 GHC.Generics.:*: f2) (g1 GHC.Generics.:*: g2)
+ Generic.Functor.Internal: instance (Generic.Functor.Internal.GMultimapK m arr f1 g1, Generic.Functor.Internal.GMultimapK m arr f2 g2, GHC.Base.Applicative m) => Generic.Functor.Internal.GMultimapK m arr (f1 GHC.Generics.:+: f2) (g1 GHC.Generics.:+: g2)
+ Generic.Functor.Internal: instance (Generic.Functor.Internal.Implicit.Multifold_ m arr x y, GHC.Base.Monoid m) => Generic.Functor.Internal.GMultimapK (Data.Functor.Const.Const (Generic.Functor.Internal.EndoM m)) arr (GHC.Generics.K1 i x) (GHC.Generics.K1 i' y)
+ Generic.Functor.Internal: instance (forall (f :: * -> *). GHC.Base.Applicative f => Generic.Functor.Internal.GBitraverse f t) => Generic.Functor.Internal.GBitraversable t
+ Generic.Functor.Internal: instance (forall (f :: * -> *). GHC.Base.Applicative f => Generic.Functor.Internal.GBitraverse f t) => Generic.Functor.Internal.GTraversable t
+ Generic.Functor.Internal: instance (forall a b. GHC.Generics.Generic (t a b), forall a b c d. Generic.Functor.Internal.GBifoldMapRep a b c d m t) => Generic.Functor.Internal.GBifoldMap m t
+ Generic.Functor.Internal: instance (forall a b. GHC.Generics.Generic (t a b), forall a b c d. Generic.Functor.Internal.GBitraverseRep a b c d f t) => Generic.Functor.Internal.GBitraverse f t
+ Generic.Functor.Internal: instance (forall a c. GHC.Generics.Generic (f a c), forall a b c d. Generic.Functor.Internal.GBimapRep a b c d f) => Generic.Functor.Internal.GBimap f
+ Generic.Functor.Internal: instance (forall a. GHC.Generics.Generic (t a), forall a b. Generic.Functor.Internal.GFoldMapRep a b m t) => Generic.Functor.Internal.GFoldMap m t
+ Generic.Functor.Internal: instance (forall a. GHC.Generics.Generic (t a), forall a b. Generic.Functor.Internal.GTraverseRep a b f t) => Generic.Functor.Internal.GTraverse f t
+ Generic.Functor.Internal: instance (forall m. GHC.Base.Monoid m => Generic.Functor.Internal.GBifoldMap m t) => Generic.Functor.Internal.GBifoldable t
+ Generic.Functor.Internal: instance (forall m. GHC.Base.Monoid m => Generic.Functor.Internal.GFoldMap m t) => Generic.Functor.Internal.GFoldable t
+ Generic.Functor.Internal: instance GHC.Base.Applicative m => Generic.Functor.Internal.GMultimapK m arr GHC.Generics.U1 GHC.Generics.U1
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GBifoldable f => Data.Bifoldable.Bifoldable (Generic.Functor.Internal.GenericBifunctor f)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GBifunctor f => Data.Bifunctor.Bifunctor (Generic.Functor.Internal.GenericBifunctor f)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GFoldMap1 m (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent (Generic.Functor.Internal.Implicit.Fold m a b Generic.Functor.Internal.Implicit.:+ Generic.Functor.Internal.Implicit.Fold m c d)) (GHC.Generics.Rep (t a c)) (GHC.Generics.Rep (t b d)) => Generic.Functor.Internal.GBifoldMapRep a b c d m t
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GFoldMap1 m (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent (Generic.Functor.Internal.Implicit.Fold m a b)) (GHC.Generics.Rep (t a)) (GHC.Generics.Rep (t b)) => Generic.Functor.Internal.GFoldMapRep a b m t
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GFoldable f => Data.Foldable.Foldable (Generic.Functor.Internal.GenericFunctor f)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GFunctor f => GHC.Base.Functor (Generic.Functor.Internal.GenericFunctor f)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent ((a -> b) Generic.Functor.Internal.Implicit.:+ (c -> d))) (GHC.Generics.Rep (f a c)) (GHC.Generics.Rep (f b d)) => Generic.Functor.Internal.GBimapRep a b c d f
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent (a -> b)) (GHC.Generics.Rep (f a c)) (GHC.Generics.Rep (f b c)) => Generic.Functor.Internal.GFirstRep a b c f
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent (a -> b)) (GHC.Generics.Rep (f a)) (GHC.Generics.Rep (f b)) => Generic.Functor.Internal.GFunctorRep a b f
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMap1 (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent arr) (GHC.Generics.Rep x) (GHC.Generics.Rep y) => Generic.Functor.Internal.GMultimap arr x y
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimap (a -> b) x y => Generic.Functor.Internal.GSolomap a b x y
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimapK (ApNormalize.Aps.Aps m) arr f g => Generic.Functor.Internal.GTraverse1 m arr f g
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimapK (Data.Functor.Const.Const (Generic.Functor.Internal.EndoM m)) arr (GHC.Generics.K1 i x) (GHC.Generics.K1 i x)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimapK (Data.Functor.Const.Const (Generic.Functor.Internal.EndoM m)) arr f g => Generic.Functor.Internal.GFoldMap1 m arr f g
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimapK Data.Functor.Identity.Identity arr f g => Generic.Functor.Internal.GMap1 arr f g
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GMultimapK m arr GHC.Generics.V1 GHC.Generics.V1
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GTraverse1 f (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent ((a -> f b) Generic.Functor.Internal.Implicit.:+ (c -> f d))) (GHC.Generics.Rep (t a c)) (GHC.Generics.Rep (t b d)) => Generic.Functor.Internal.GBitraverseRep a b c d f t
+ Generic.Functor.Internal: instance Generic.Functor.Internal.GTraverse1 f (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent (a -> f b)) (GHC.Generics.Rep (t a)) (GHC.Generics.Rep (t b)) => Generic.Functor.Internal.GTraverseRep a b f t
+ Generic.Functor.Internal: instance Generic.Functor.Internal.Implicit.MultimapI (Generic.Functor.Internal.Implicit.Default Generic.Functor.Internal.Implicit.Incoherent arr) x y => Generic.Functor.Internal.Multimap arr x y
+ Generic.Functor.Internal: instance Generic.Functor.Internal.Implicit.MultimapI arr x y => Generic.Functor.Internal.GMultimapK Data.Functor.Identity.Identity arr (GHC.Generics.K1 i x) (GHC.Generics.K1 i' y)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.Implicit.Multitraverse m arr x y => Generic.Functor.Internal.GMultimapK (ApNormalize.Aps.Aps m) arr (GHC.Generics.K1 i x) (GHC.Generics.K1 i' y)
+ Generic.Functor.Internal: instance Generic.Functor.Internal.Multimap (a -> b) x y => Generic.Functor.Internal.Solomap a b x y
+ Generic.Functor.Internal: liftEndoM :: Monoid m => m -> EndoM m
+ Generic.Functor.Internal: newtype GenericBifunctor f a b
+ Generic.Functor.Internal: newtype GenericFunctor f a
+ Generic.Functor.Internal: type EndoM m = Endo (Maybe m)
+ Generic.Functor.Internal: unEndoM :: Monoid m => EndoM m -> m
+ Generic.Functor.Internal.Implicit: (:+) :: a -> b -> (:+) a b
+ Generic.Functor.Internal.Implicit: AnyBifunctor :: AnyBifunctor
+ Generic.Functor.Internal.Implicit: AnyFunctor :: AnyFunctor
+ Generic.Functor.Internal.Implicit: AnyId :: AnyId
+ Generic.Functor.Internal.Implicit: Fold :: (x -> m) -> Fold m x y
+ Generic.Functor.Internal.Implicit: Incoherent :: Incoherent
+ Generic.Functor.Internal.Implicit: NilArr :: NilArr
+ Generic.Functor.Internal.Implicit: Rule :: rule -> mode -> Rule rule mode
+ Generic.Functor.Internal.Implicit: S :: arr -> arr' -> S arr arr'
+ Generic.Functor.Internal.Implicit: [unFold] :: Fold m x y -> x -> m
+ Generic.Functor.Internal.Implicit: catbimap :: BifunctorOf cat t => cat a b -> cat c d -> cat (t a c) (t b d)
+ Generic.Functor.Internal.Implicit: catid :: CatLike cat => cat x x
+ Generic.Functor.Internal.Implicit: catmap :: FunctorOf cat t => cat a b -> cat (t a) (t b)
+ Generic.Functor.Internal.Implicit: class BifunctorOf cat t
+ Generic.Functor.Internal.Implicit: class CatLike cat
+ Generic.Functor.Internal.Implicit: class Coercible warr arr => CoercibleKleisli (f :: Type -> Type) warr arr
+ Generic.Functor.Internal.Implicit: class FunctorOf cat t
+ Generic.Functor.Internal.Implicit: class MultimapOf (Fold m) arr x y => Multifold_ m arr x y
+ Generic.Functor.Internal.Implicit: class MultimapOf (->) arr x y => MultimapI arr x y
+ Generic.Functor.Internal.Implicit: class Multimap_ cat (S2 arr) x y => MultimapOf cat arr x y
+ Generic.Functor.Internal.Implicit: class Multimap_ cat arr x y
+ Generic.Functor.Internal.Implicit: class Multitraverse_ f arr x y => Multitraverse f arr x y
+ Generic.Functor.Internal.Implicit: data AnyBifunctor
+ Generic.Functor.Internal.Implicit: data AnyFunctor
+ Generic.Functor.Internal.Implicit: data AnyId
+ Generic.Functor.Internal.Implicit: data Incoherent
+ Generic.Functor.Internal.Implicit: data NilArr
+ Generic.Functor.Internal.Implicit: data Rule rule mode
+ Generic.Functor.Internal.Implicit: data S arr arr'
+ Generic.Functor.Internal.Implicit: data a :+ b
+ Generic.Functor.Internal.Implicit: def :: mode -> arr -> Default mode arr
+ Generic.Functor.Internal.Implicit: defaultIncoherent :: arr -> Default Incoherent arr
+ Generic.Functor.Internal.Implicit: infixr 1 :+
+ Generic.Functor.Internal.Implicit: instance (Data.Bifoldable.Bifoldable t, GHC.Base.Monoid m) => Generic.Functor.Internal.Implicit.BifunctorOf (Generic.Functor.Internal.Implicit.Fold m) t
+ Generic.Functor.Internal.Implicit: instance (Data.Foldable.Foldable t, GHC.Base.Monoid m) => Generic.Functor.Internal.Implicit.FunctorOf (Generic.Functor.Internal.Implicit.Fold m) t
+ Generic.Functor.Internal.Implicit: instance (GHC.Base.Applicative f, Data.Bitraversable.Bitraversable t) => Generic.Functor.Internal.Implicit.BifunctorOf (Control.Arrow.Kleisli f) t
+ Generic.Functor.Internal.Implicit: instance (GHC.Base.Applicative f, Data.Traversable.Traversable t) => Generic.Functor.Internal.Implicit.FunctorOf (Control.Arrow.Kleisli f) t
+ Generic.Functor.Internal.Implicit: instance (Generic.Functor.Internal.Implicit.BifunctorOf cat f, Generic.Functor.Internal.Implicit.MultimapOf cat arr x1 y1, Generic.Functor.Internal.Implicit.MultimapOf cat arr x2 y2) => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (Generic.Functor.Internal.Implicit.Rule Generic.Functor.Internal.Implicit.AnyBifunctor Generic.Functor.Internal.Implicit.Incoherent Generic.Functor.Internal.Implicit.:+ arr')) (f x1 x2) (f y1 y2)
+ Generic.Functor.Internal.Implicit: instance (Generic.Functor.Internal.Implicit.CoercibleKleisli f a b, Generic.Functor.Internal.Implicit.CoercibleKleisli f arr arr') => Generic.Functor.Internal.Implicit.CoercibleKleisli f (a Generic.Functor.Internal.Implicit.:+ arr) (b Generic.Functor.Internal.Implicit.:+ arr')
+ Generic.Functor.Internal.Implicit: instance (Generic.Functor.Internal.Implicit.FunctorOf cat f, Generic.Functor.Internal.Implicit.MultimapOf cat arr x y) => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (Generic.Functor.Internal.Implicit.Rule Generic.Functor.Internal.Implicit.AnyFunctor Generic.Functor.Internal.Implicit.Incoherent Generic.Functor.Internal.Implicit.:+ arr')) (f x) (f y)
+ Generic.Functor.Internal.Implicit: instance (Generic.Functor.Internal.Implicit.MultimapOf (->) arr y1 x1, Generic.Functor.Internal.Implicit.MultimapOf (->) arr x2 y2) => Generic.Functor.Internal.Implicit.Multimap_ (->) (Generic.Functor.Internal.Implicit.S arr (Generic.Functor.Internal.Implicit.Rule Generic.Functor.Internal.Implicit.AnyBifunctor Generic.Functor.Internal.Implicit.Incoherent Generic.Functor.Internal.Implicit.:+ arr')) (x1 -> x2) (y1 -> y2)
+ Generic.Functor.Internal.Implicit: instance (b2 GHC.Types.~ f c, a GHC.Types.~ Control.Arrow.Kleisli f b1 c) => Generic.Functor.Internal.Implicit.CoercibleKleisli f a (b1 -> b2)
+ Generic.Functor.Internal.Implicit: instance (d GHC.Types.~ Generic.Functor.Internal.Implicit.NilArr) => Generic.Functor.Internal.Implicit.CoercibleKleisli f d Generic.Functor.Internal.Implicit.NilArr
+ Generic.Functor.Internal.Implicit: instance (d GHC.Types.~ Generic.Functor.Internal.Implicit.Rule rule mode) => Generic.Functor.Internal.Implicit.CoercibleKleisli f d (Generic.Functor.Internal.Implicit.Rule rule mode)
+ Generic.Functor.Internal.Implicit: instance Data.Bifunctor.Bifunctor t => Generic.Functor.Internal.Implicit.BifunctorOf (->) t
+ Generic.Functor.Internal.Implicit: instance GHC.Base.Applicative f => Generic.Functor.Internal.Implicit.CatLike (Control.Arrow.Kleisli f)
+ Generic.Functor.Internal.Implicit: instance GHC.Base.Functor t => Generic.Functor.Internal.Implicit.FunctorOf (->) t
+ Generic.Functor.Internal.Implicit: instance GHC.Base.Monoid m => Generic.Functor.Internal.Implicit.CatLike (Generic.Functor.Internal.Implicit.Fold m)
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.CatLike (->)
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.CatLike cat => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (Generic.Functor.Internal.Implicit.Rule Generic.Functor.Internal.Implicit.AnyId Generic.Functor.Internal.Implicit.Incoherent Generic.Functor.Internal.Implicit.:+ arr')) x x
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.MultimapOf (->) arr x y => Generic.Functor.Internal.Implicit.MultimapI arr x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.MultimapOf (Generic.Functor.Internal.Implicit.Fold m) arr x y => Generic.Functor.Internal.Implicit.Multifold_ m arr x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (arr0 Generic.Functor.Internal.Implicit.:+ (arr1 Generic.Functor.Internal.Implicit.:+ arr2))) x y => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr ((arr0 Generic.Functor.Internal.Implicit.:+ arr1) Generic.Functor.Internal.Implicit.:+ arr2)) x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (cat a b Generic.Functor.Internal.Implicit.:+ arr')) a b
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr arr') x y => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (() Generic.Functor.Internal.Implicit.:+ arr')) x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr arr') x y => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (Generic.Functor.Internal.Implicit.NilArr Generic.Functor.Internal.Implicit.:+ arr')) x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr arr') x y => Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S arr (arr0 Generic.Functor.Internal.Implicit.:+ arr')) x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multimap_ cat (Generic.Functor.Internal.Implicit.S2 arr) x y => Generic.Functor.Internal.Implicit.MultimapOf cat arr x y
+ Generic.Functor.Internal.Implicit: instance Generic.Functor.Internal.Implicit.Multitraverse_ f arr x y => Generic.Functor.Internal.Implicit.Multitraverse f arr x y
+ Generic.Functor.Internal.Implicit: multifold_ :: forall m arr x y. Multifold_ m arr x y => arr -> Fold m x y
+ Generic.Functor.Internal.Implicit: multimapI :: forall arr x y. MultimapI arr x y => arr -> x -> y
+ Generic.Functor.Internal.Implicit: multimapOf :: forall cat arr x y. MultimapOf cat arr x y => arr -> cat x y
+ Generic.Functor.Internal.Implicit: multimap_ :: Multimap_ cat arr x y => arr -> cat x y
+ Generic.Functor.Internal.Implicit: multitraverse :: forall f arr x y. Multitraverse f arr x y => arr -> x -> f y
+ Generic.Functor.Internal.Implicit: newtype Fold m x y
+ Generic.Functor.Internal.Implicit: s2 :: arr -> S2 arr
+ Generic.Functor.Internal.Implicit: type Default mode arr = arr :+ Rule AnyId mode :+ Rule AnyFunctor mode :+ Rule AnyBifunctor mode :+ NilArr
+ Generic.Functor.Internal.Implicit: type Multitraverse_ f arr x y = (MultimapOf (Kleisli f) (WrapKleisli f arr) x y, CoercibleKleisli f (WrapKleisli f arr) arr)
+ Generic.Functor.Internal.Implicit: type S2 arr = S arr arr
+ Generic.Functor.Internal.Implicit: type family WrapKleisli (f :: Type -> Type) (arr :: Type)
- Generic.Functor: class (forall a c. Generic (f a c), forall a b c d. GBifunctorRep a b c d f) => GBifunctor f
+ Generic.Functor: class (GBimap f, GFirst f, GSecond f) => GBifunctor f
- Generic.Functor: class GMap1 arr (Rep x) (Rep y) => GMultimap arr x y
+ Generic.Functor: class GMap1 (Default Incoherent arr) (Rep x) (Rep y) => GMultimap arr x y
- Generic.Functor: class GMap1 ((a -> b) :+ ()) (Rep x) (Rep y) => GSolomap a b x y
+ Generic.Functor: class GMultimap (a -> b) x y => GSolomap a b x y
- Generic.Functor: class Multimap_ (S2 arr) x y => Multimap arr x y
+ Generic.Functor: class MultimapI (Default Incoherent arr) x y => Multimap arr x y
- Generic.Functor: class Multimap ((a -> b) :+ ()) x y => Solomap a b x y
+ Generic.Functor: class Multimap (a -> b) x y => Solomap a b x y
- Generic.Functor: gbimap :: forall f a b c d. GBifunctor f => (a -> b) -> (c -> d) -> f a c -> f b d
+ Generic.Functor: gbimap :: forall f a b c d. GBimap f => (a -> b) -> (c -> d) -> f a c -> f b d
- Generic.Functor.Internal: class (forall a c. Generic (f a c), forall a b c d. GBifunctorRep a b c d f) => GBifunctor f
+ Generic.Functor.Internal: class (GBimap f, GFirst f, GSecond f) => GBifunctor f
- Generic.Functor.Internal: class GMap1 ((a -> b) :+ ()) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f
+ Generic.Functor.Internal: class GMap1 (Default Incoherent (a -> b)) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f
- Generic.Functor.Internal: class GMap1 ((a -> b) :+ ()) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f
+ Generic.Functor.Internal: class GMap1 (Default Incoherent (a -> b)) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f
- Generic.Functor.Internal: class GMap1 arr f g
+ Generic.Functor.Internal: class GMultimapK Identity arr f g => GMap1 arr f g
- Generic.Functor.Internal: class GMap1 arr (Rep x) (Rep y) => GMultimap arr x y
+ Generic.Functor.Internal: class GMap1 (Default Incoherent arr) (Rep x) (Rep y) => GMultimap arr x y
- Generic.Functor.Internal: class GMap1 ((a -> b) :+ ()) (Rep x) (Rep y) => GSolomap a b x y
+ Generic.Functor.Internal: class GMultimap (a -> b) x y => GSolomap a b x y
- Generic.Functor.Internal: class Multimap_ (S2 arr) x y => Multimap arr x y
+ Generic.Functor.Internal: class MultimapI (Default Incoherent arr) x y => Multimap arr x y
- Generic.Functor.Internal: class Multimap ((a -> b) :+ ()) x y => Solomap a b x y
+ Generic.Functor.Internal: class Multimap (a -> b) x y => Solomap a b x y
- Generic.Functor.Internal: gbimap :: forall f a b c d. GBifunctor f => (a -> b) -> (c -> d) -> f a c -> f b d
+ Generic.Functor.Internal: gbimap :: forall f a b c d. GBimap f => (a -> b) -> (c -> d) -> f a c -> f b d

Files

CHANGELOG.md view
@@ -1,12 +1,19 @@-## 0.1.0.0--- Add `gmultimap`, `multimap`, `(:+)`-- Add `DeriveBifunctor`, `gbimap`, `gfirst`, `gsecond`--## 0.0.1.1--* Include README--## 0.0.1.0--* Create generic-functor+## 0.2.0.0
+
+- Add `gfoldMap`, `gtraverse`, `gbifoldMap`, `gbitraverse` `GFoldable`, `GFoldMap`, `GTraversable`, `GTraverse`, `GBiFoldable`, `GBifoldMap`, `GBitraversable`, `GBitraverse`
+- Rename `GBifunctor` to `GBimap`, and add new `GBifunctor` (class synonym for `GBimap`, `GFirst`, and `GSecond`)
+- Rename `DeriveFunctor` to `GenericFunctor`, and rename `DeriveBifunctor` to `GenericBifunctor`
+- Add instances for deriving-via `Foldable` and `Bifoldable`
+
+## 0.1.0.0
+
+- Add `gmultimap`, `multimap`, `(:+)`
+- Add `DeriveBifunctor`, `gbimap`, `gfirst`, `gsecond`
+
+## 0.0.1.1
+
+* Include README
+
+## 0.0.1.0
+
+* Create generic-functor
LICENSE view
@@ -1,19 +1,19 @@-Copyright Li-yao Xia (c) 2020--Permission is hereby granted, free of charge, to any person obtaining a copy of-this software and associated documentation files (the “Software”), to deal in-the Software without restriction, including without limitation the rights to-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies-of the Software, and to permit persons to whom the Software is furnished to do-so, subject to the following conditions:--The above copyright notice and this permission notice shall be included in all-copies or substantial portions of the Software.--THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE-SOFTWARE.+Copyright Li-yao Xia (c) 2020
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the “Software”), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
README.md view
@@ -1,202 +1,209 @@-# Generic functors [![Hackage](https://img.shields.io/hackage/v/generic-functor.svg)](https://hackage.haskell.org/package/generic-functor) [![pipeline status](https://gitlab.com/lysxia/generic-functor/badges/main/pipeline.svg)](https://gitlab.com/lysxia/generic-functor/-/commits/main)---Implementation of `Functor` instances and other functor-like structures-using `GHC.Generics`.--## Functors not over the last type parameter--The standard `Functor` class only applies to types that are functors over their-last type parameter. For example, in `Either e r`, `fmap` maps only `r`.--Using this library, `fmap`-like functions can be derived over any type-parameter of a `Generic` data type, all from the same definition `gsolomap`.--```haskell-{-# LANGUAGE DeriveGeneric #-}--import GHC.Generics (Generic)-import Generic.Functor (gsolomap)--data Result a r = Error a | Ok r   -- Another name for Either-  deriving Generic--mapError :: (a -> b) -> Result a r -> Result b r-mapError = gsolomap---- This one is fmap-mapOk :: (a -> b) -> Result e a -> Result e b-mapOk = gsolomap--mapBoth :: (a -> b) -> Result a a -> Result b b-mapBoth = gsolomap-```--`gsolomap` is **unsafe**. Misuse will break your program.-Read on for specifics.--### Usage--`gsolomap` should only be used to define **polymorphic** "`fmap`-like functions"-for `Generic` types.--The signature of `gsolomap` is:--```haskell-gsolomap :: (Generic x, Generic y, GSolomap a b x y) => (a -> b) -> (x -> y)-```--The types `x` and `y` must be specializations of the same user-defined `data`-type which is an instance of `Generic`, with some type parameters equal to `a`-or `b` respectively. At use sites of `gsolomap`, `a` and `b` must also be two-distinct universally quantified type variables, with no equality constraint-relating them with each other or any other type.--The guarantee is that `gsolomap` satisfies `gsolomap id = id`. Under the-condition that `a` and `b` are abstract, that equation uniquely determines the-implementation. (That uniqueness claim may be broken with GADTs and other-explicit uses of type equality constraints.)--In particular, `gsolomap` *must not* be specialized with types `a` and `b` that-are equal. A function defined using `gsolomap` is safe to specialize once-the `GSolomap` constraint has been discharged.--For instance the three functions above, `mapError`, `mapOk`, `mapBoth` are-sufficiently polymorphic.-They are each uniquely determined by their types and the equation `mapX id = id`.-(Without that equation, `mapBoth` has four implementations of the same type.)--## Compositions of functors--How many `fmap` do you need to map a function `a -> b` over-`(t, Maybe [Either Bool a])`?--You only need one `solomap`:--```haskell-type F t a = (t, Maybe [Either Bool a])--maps :: (a -> b) -> F t a -> F t b-maps = solomap-```--`solomap` can also see through bifunctors and there may be more than-one occurrence of the type parameter `a`.--```haskell-type F a = ([a], Either a ())--maps2 :: (a -> b) -> F a -> F b-maps2 = solomap-```--`solomap` is **unsafe**, subject to the same restrictions as `gsolomap`:-where `solomap` is used, the type of its first argument `(a -> b)` must refer-to two distinct universally quantified variables `a` and `b`.-Functions are safe to specialize only once the `Solomap` constraint is out of-their contexts.--```haskell-solomap :: Solomap a b x y => (a -> b) -> (x -> y)-```--## Functors of multiple parameters--You can also map with more than one function simultaneously.-For example with `a -> b` and `c -> d` over `(Maybe a, [(c, a)])`:--```haskell-type F a c = (Maybe a, [(c, a)])--bimaps :: (a -> b) -> (c -> d) -> F a c -> F b d-bimaps f g = multimap (f :+ g :+ ())-```--`multimap` takes a list of functions separated by `(:+)` and terminated by `()`.--There is also a `gmultimap`, generalizing `gsolomap`.--`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 (DeriveFunctor(..))--data Twice a = Twice (Either a a)-  deriving Generic-  deriving Functor via (DeriveFunctor 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 (DeriveFunctor(..), DeriveBifunctor(..))--data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b-  deriving Generic-  deriving Functor via (DeriveFunctor (Tree a))-  deriving Bifunctor via (DeriveBifunctor Tree)-```-------## Internal module policy--The public API is `Generic.Functor`. Don't use `Generic.Functor.Internal`.--## Future work--- Bifunctors and variants with more than one function argument.-- Functors in arbitrary categories.--## Related links--- [*generic-data*][generic-data]: utilities for `GHC.Generics` and deriving for-  other standard classes.--- [*generic-lens*][generic-lens]: the `params` traversal uses a very similar implementation.--- [*one-liner*][one-liner]. [*product-profunctors*][pp]--- [*Deriving Bifunctors with Generics*](https://kcsongor.github.io/generic-deriving-bifunctor/),-  blogpost by Csongor Kiss,-  describing the main idea for the implementation (using incoherent instances).--[generic-data]: https://hackage.haskell.org/package/generic-data-[generic-lens]: https://hackage.haskell.org/package/generic-lens-[one-liner]: https://hackage.haskell.org/package/one-liner-[pp]: https://hackage.haskell.org/package/product-profunctors+# Generic functors [![Hackage](https://img.shields.io/hackage/v/generic-functor.svg)](https://hackage.haskell.org/package/generic-functor) [![pipeline status](https://gitlab.com/lysxia/generic-functor/badges/main/pipeline.svg)](https://gitlab.com/lysxia/generic-functor/-/commits/main)
+
+
+Implementation of `Functor` instances and other functor-like structures
+using `GHC.Generics`.
+
+## Functors not over the last type parameter
+
+The standard `Functor` class only applies to types that are functors over their
+last type parameter. For example, in `Either e r`, `fmap` maps only `r`.
+
+Using this library, `fmap`-like functions can be derived over any type
+parameter of a `Generic` data type, all from the same definition `gsolomap`.
+
+```haskell
+{-# LANGUAGE DeriveGeneric #-}
+
+import GHC.Generics (Generic)
+import Generic.Functor (gsolomap)
+
+data Result a r = Error a | Ok r   -- Another name for Either
+  deriving Generic
+
+mapError :: (a -> b) -> Result a r -> Result b r
+mapError = gsolomap
+
+-- This one is fmap
+mapOk :: (a -> b) -> Result e a -> Result e b
+mapOk = gsolomap
+
+mapBoth :: (a -> b) -> Result a a -> Result b b
+mapBoth = gsolomap
+```
+
+`gsolomap` is **unsafe**. Misuse will break your program.
+Read on for specifics.
+
+### Usage
+
+`gsolomap` should only be used to define **polymorphic** "`fmap`-like functions"
+for `Generic` types.
+
+The signature of `gsolomap` is:
+
+```haskell
+gsolomap :: (Generic x, Generic y, GSolomap a b x y) => (a -> b) -> (x -> y)
+```
+
+The types `x` and `y` must be specializations of the same user-defined `data`
+type which is an instance of `Generic`, with some type parameters equal to `a`
+or `b` respectively. At use sites of `gsolomap`, `a` and `b` must also be two
+distinct universally quantified type variables, with no equality constraint
+relating them with each other or any other type.
+
+The guarantee is that `gsolomap` satisfies `gsolomap id = id`. Under the
+condition that `a` and `b` are abstract, that equation uniquely determines the
+implementation. (That uniqueness claim may be broken with GADTs and other
+explicit uses of type equality constraints.)
+
+In particular, `gsolomap` *must not* be specialized with types `a` and `b` that
+are equal. A function defined using `gsolomap` is safe to specialize once
+the `GSolomap` constraint has been discharged.
+
+For instance the three functions above, `mapError`, `mapOk`, `mapBoth` are
+sufficiently polymorphic.
+They are each uniquely determined by their types and the equation `mapX id = id`.
+(Without that equation, `mapBoth` has four implementations of the same type.)
+
+## Compositions of functors
+
+How many `fmap` do you need to map a function `a -> b` over
+`(t, Maybe [Either Bool a])`?
+
+You only need one `solomap`:
+
+```haskell
+type F t a = (t, Maybe [Either Bool a])
+
+maps :: (a -> b) -> F t a -> F t b
+maps = solomap
+```
+
+`solomap` can also see through bifunctors and there may be more than
+one occurrence of the type parameter `a`.
+
+```haskell
+type F a = ([a], Either a ())
+
+maps2 :: (a -> b) -> F a -> F b
+maps2 = solomap
+```
+
+`solomap` is **unsafe**, subject to the same restrictions as `gsolomap`:
+where `solomap` is used, the type of its first argument `(a -> b)` must refer
+to two distinct universally quantified variables `a` and `b`.
+Functions are safe to specialize only once the `Solomap` constraint is out of
+their contexts.
+
+```haskell
+solomap :: Solomap a b x y => (a -> b) -> (x -> y)
+```
+
+## Functors of multiple parameters
+
+You can also map with more than one function simultaneously.
+For example with `a -> b` and `c -> d` over `(Maybe a, [(c, a)])`:
+
+```haskell
+type F a c = (Maybe a, [(c, a)])
+
+bimaps :: (a -> b) -> (c -> d) -> F a c -> F b d
+bimaps f g = multimap (f :+ g :+ ())
+```
+
+`multimap` takes a list of functions separated by `(:+)` and terminated by `()`.
+
+There is also a `gmultimap`, generalizing `gsolomap`.
+
+`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`).
+
+---
+
+## Internal module policy
+
+The public API is `Generic.Functor`. Don't use `Generic.Functor.Internal`.
+
+## Future work
+
+- Functors in arbitrary categories.
+
+## Related links
+
+- [*generic-data*][generic-data]: utilities for `GHC.Generics` and deriving for
+  other standard classes.
+
+- [*generic-lens*][generic-lens]: the `params` traversal uses a very similar implementation.
+
+- [*one-liner*][one-liner]. [*product-profunctors*][pp]
+
+- [*Deriving Bifunctors with Generics*](https://kcsongor.github.io/generic-deriving-bifunctor/),
+  blogpost by Csongor Kiss,
+  describing the main idea for the implementation (using incoherent instances).
+
+[generic-data]: https://hackage.haskell.org/package/generic-data
+[generic-lens]: https://hackage.haskell.org/package/generic-lens
+[one-liner]: https://hackage.haskell.org/package/one-liner
+[pp]: https://hackage.haskell.org/package/product-profunctors
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple-main = defaultMain+import Distribution.Simple
+main = defaultMain
generic-functor.cabal view
@@ -1,40 +1,44 @@-cabal-version:       >=1.10-name:                generic-functor-version:             0.1.0.0-synopsis: Deriving generalized functors with GHC.Generics-description:-  Derive @fmap@, and other @fmap@-like functions where the-  parameter of the functor could occur anywhere.-  .-  See the README for details.-homepage:            https://gitlab.com/lysxia/generic-functor-bug-reports:         https://gitlab.com/lysxia/generic-functor/-/issues-license:             MIT-license-file:        LICENSE-author:              Li-yao Xia-maintainer:          lysxia@gmail.com-copyright:           Li-yao Xia 2020-category:            Generics-build-type:          Simple-extra-source-files:  CHANGELOG.md, README.md--library-  hs-source-dirs: src-  exposed-modules:-    Generic.Functor-    Generic.Functor.Internal-  build-depends:       base >=4.12 && <4.15-  default-language:    Haskell2010--test-suite examples-  hs-source-dirs: test-  main-is: test.hs-  build-depends:-    generic-functor,-    base-  type: exitcode-stdio-1.0-  default-language:    Haskell2010--source-repository head-  type:     git-  location: https://gitlab.com/lysxia/generic-functor+cabal-version:       >=1.10
+name:                generic-functor
+version:             0.2.0.0
+synopsis: Deriving generalized functors with GHC.Generics
+description:
+  Derive @fmap@, and other @fmap@-like functions where the
+  parameter of the functor could occur anywhere.
+  .
+  See the README for details.
+homepage:            https://gitlab.com/lysxia/generic-functor
+bug-reports:         https://gitlab.com/lysxia/generic-functor/-/issues
+license:             MIT
+license-file:        LICENSE
+author:              Li-yao Xia
+maintainer:          lysxia@gmail.com
+copyright:           Li-yao Xia 2020
+category:            Generics
+build-type:          Simple
+extra-source-files:  CHANGELOG.md, README.md
+
+library
+  hs-source-dirs: src
+  exposed-modules:
+    Generic.Functor
+    Generic.Functor.Internal
+    Generic.Functor.Internal.Implicit
+  build-depends:
+    ap-normalize,
+    base >=4.12 && <4.15
+  default-language:    Haskell2010
+
+test-suite examples
+  hs-source-dirs: test
+  main-is: test.hs
+  build-depends:
+    generic-functor,
+    transformers,
+    base
+  type: exitcode-stdio-1.0
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://gitlab.com/lysxia/generic-functor
src/Generic/Functor.hs view
@@ -1,38 +1,63 @@--- | Generic and generalized functors.--module Generic.Functor-  ( -- * Derive functors--    -- ** Unary functors-    gsolomap-  , solomap--    -- ** N-ary functors-  , gmultimap-  , multimap-  , (:+)(..)--    -- ** Derive Functor and Bifunctor--    -- *** DerivingVia-  , DeriveFunctor(..)-  , DeriveBifunctor(..)--    -- *** Generic method definitions-  , gfmap-  , gbimap-  , gfirst-  , gsecond--    -- * Auxiliary classes-  , GFunctor()-  , GBifunctor()-  , GFirst()-  , GSecond()-  , GSolomap()-  , Solomap()-  , GMultimap()-  , Multimap()-  ) where--import Generic.Functor.Internal+-- | Generic and generalized functors.
+
+module Generic.Functor
+  ( -- * Derive functors
+
+    -- ** Unary functors
+    gsolomap
+  , solomap
+
+    -- ** N-ary functors
+  , gmultimap
+  , multimap
+  , (:+)(..)
+
+    -- ** Derive Functor, Bifunctor, Foldable, Traversable
+
+    -- *** DerivingVia
+    -- | The type synonyms 'GenericFunctor' and 'GenericBifunctor' can be
+    -- used with the @DerivingVia@ extension to derive 'Functor', 'Bifunctor', and 'Foldable'.
+    -- Sadly, 'Traversable' cannot be derived-via.
+  , GenericFunctor(..)
+  , GenericBifunctor(..)
+
+    -- *** Generic method definitions
+  , gfmap
+  , gfoldMap
+  , gtraverse
+
+    -- **** Bifunctors
+  , gbimap
+  , gfirst
+  , gsecond
+  , gbifoldMap
+  , gbitraverse
+
+    -- * Auxiliary classes
+
+    -- ** Related to standard classes
+  , GFunctor()
+  , GFoldable()
+  , GFoldMap()
+  , GTraversable()
+  , GTraverse()
+
+    -- *** Bifunctors
+  , GBifunctor()
+  , GBimap()
+  , GFirst()
+  , GSecond()
+  , GBifoldable()
+  , GBifoldMap()
+  , GBitraversable()
+  , GBitraverse()
+
+    -- ** Generalized functors
+  , GSolomap()
+  , Solomap()
+  , GMultimap()
+  , Multimap()
+  ) where
+
+import Generic.Functor.Internal
+import Generic.Functor.Internal.Implicit
src/Generic/Functor/Internal.hs view
@@ -1,420 +1,511 @@-{-# LANGUAGE-  AllowAmbiguousTypes,-  ConstraintKinds,-  EmptyCase,-  FlexibleContexts,-  FlexibleInstances,-  MultiParamTypeClasses,-  QuantifiedConstraints,-  RankNTypes,-  ScopedTypeVariables,-  TypeApplications,-  TypeOperators,-  UndecidableInstances #-}--{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}---- | This is an internal module. Look, don't touch.------ "Generic.Functor" is the public API.--module Generic.Functor.Internal where--import Data.Bifunctor-import Data.Coerce-import GHC.Generics hiding (S)---- | Generic implementation of 'fmap'. See also 'DeriveFunctor' for @DerivingVia@,--- using 'gfmap' under the hood.------ === Example------ @--- {-\# LANGUAGE DeriveGeneric \#-}------ import "GHC.Generics" ('Generic')--- import "Generic.Functor" ('gfmap')------ data Twice a = Twice (Either a a)---   deriving 'Generic'------ instance 'Functor' Twice where---   'fmap' = 'gfmap'--- @------ Unlike 'gsolomap', 'gfmap' is safe to use in all contexts.-gfmap :: forall f a b. GFunctor f => (a -> b) -> (f a -> f b)-gfmap f = with @(GFunctorRep a b f) (to . gmap1 (f :+ ()) . from)---- | Generalized generic functor.------ 'gsolomap' is a generalization of 'gfmap' (generic 'fmap'),--- where the type parameter to be \"mapped\" does not have to be the last one.------ 'gsolomap' is __unsafe__: misuse will break your programs.--- Read the <#gsolomapusage Usage> section below for details.------ === Example------ @--- {-\# LANGUAGE DeriveGeneric \#-}------ import "GHC.Generics" ('Generic')--- import "Generic.Functor" ('gsolomap')------ data Result a r = Error a | Ok r  -- Another name for Either---   deriving 'Generic'------ mapError :: (a -> b) -> Result a r -> Result b r--- mapError = 'gsolomap'------ mapOk :: (r -> s) -> Result a r -> Result a s--- mapOk = 'gsolomap'------ mapBoth :: (a -> b) -> Result a a -> Result b b--- mapBoth = 'gsolomap'--- @------ === Usage #gsolomapusage#------ (This also applies to 'solomap', 'gmultimap', and 'multimap'.)------ 'gsolomap' should only be used to define __polymorphic__ "@fmap@-like functions".--- It works only in contexts where @a@ and @b@ are two distinct, non-unifiable--- type variables. This is usually the case when they are bound by universal--- quantification (@forall a b. ...@), with no equality constraints on @a@ and--- @b@.------ The one guarantee of 'gsolomap' is that @'gsolomap' 'id' = 'id'@.--- Under the above conditions, that law and the types should uniquely determine--- the implementation, which 'gsolomap' seeks automatically.------ The unsafety is due to the use of incoherent instances as part of the--- definition of 'GSolomap'. Functions are safe to specialize after 'GSolomap'--- (and 'Solomap') constraints have been discharged.-gsolomap :: forall a b x y. (Generic x, Generic y, GSolomap a b x y) => (a -> b) -> (x -> y)-gsolomap f = to . gmap1 (f :+ ()) . from---- | Generalized implicit functor.------ Use this when @x@ and @y@ are applications of existing functors--- ('Functor', 'Bifunctor').------ This is a different use case from 'gfmap' and 'gsolomap', which make--- functors out of freshly declared @data@ types.------ 'solomap' is __unsafe__: misuse will break your programs.------ See the <#gsolomapusage Usage> section of 'gsolomap' for details.------ === Example------ @--- map1 :: (a -> b) -> Either e (Maybe [IO a]) -> Either e (Maybe [IO b])--- map1 = 'solomap'--- -- equivalent to:   fmap . fmap . fmap . fmap------ map2 :: (a -> b) -> (e -> Either [a] r) -> (e -> Either [b] r)--- map2 = 'solomap'--- -- equivalent to:   \\f -> fmap (bimap (fmap f) id)--- @-solomap :: forall a b x y. Solomap a b x y => (a -> b) -> (x -> y)-solomap f = multimap (f :+ ())---- | Generic n-ary functor.------ A generalization of 'gsolomap' to map over multiple parameters simultaneously.--- 'gmultimap' takes a list of functions separated by @(':+')@ and terminated by @()@.------ 'gmultimap' is __unsafe__: misuse will break your programs.--- The type of every function in the list must be some @(a -> b)@--- where @a@ and @b@ are distinct type variables.------ See the <#gsolomapusage Usage> section of 'gsolomap' for details.------ === Example------ @--- {-\# LANGUAGE DeriveGeneric \#-}------ import "GHC.Generics" ('Generic')--- import "Generic.Functor" ('gmultimap')------ data Three a b c = One a | Two b | Three c---   deriving 'Generic'------ mapThree :: (a -> a') -> (b -> b') -> (c -> c') -> Three a b c -> Three a' b' c'--- mapThree f g h = 'gmultimap' (f ':+' g ':+' h ':+' ())--- @-gmultimap :: forall arr x y. (Generic x, Generic y, GMultimap arr x y) => arr -> (x -> y)-gmultimap f = to . gmap1 f . from---- | Implicit n-ary functor.------ A generalization of 'solomap' to map over multiple parameters simultaneously.--- 'multimap' takes a list of functions separated by @(':+')@ and terminated by @()@.------ 'multimap' is __unsafe__: misuse will break your programs.--- The type of every function in the list must be some @(a -> b)@--- where @a@ and @b@ are distinct type variables.------ See the <#gsolomapusage Usage> section of 'gsolomap' for details.------ === Example------ @--- type F a b c = Either a (b, c)------ map3 :: (a -> a') -> (b -> b') -> (c -> c') -> F a b c -> F a' b' c'--- map3 f g h = 'multimap' (f ':+' g ':+' h ':+' ())--- -- equivalent to:  \\f g h -> bimap f (bimap g h)--- @-multimap :: forall arr x y. Multimap arr x y => arr -> (x -> y)-multimap f = multimap_ (s2 f)---- | Generic implementation of 'bimap'. See also 'DeriveBifunctor'.-gbimap :: forall f a b c d. GBifunctor f => (a -> b) -> (c -> d) -> f a c -> f b d-gbimap f g = with @(GBifunctorRep a b c d f) (to . gmap1 (f :+ g :+ ()) . from)---- | Generic implementation of 'first'. See also 'DeriveBifunctor'.-gfirst :: forall f a b c. GFirst f => (a -> b) -> f a c -> f b c-gfirst f = with @(GFirstRep a b c f) (to . gmap1 (f :+ ()) . from)---- | Generic implementation of 'second'. See also 'DeriveBifunctor'.-gsecond :: forall f a c d. GSecond f => (c -> d) -> f a c -> f a d-gsecond = gfmap---- | Explicitly require a constraint, to force the instantiation of a quantified constraint.-with :: forall c r. (c => r) -> (c => r)-with x = x---- ** Top-level constraints---- *** @gfmap@---- | Constraint for 'gfmap'.-class    (forall a. Generic (f a), forall a b. GFunctorRep a b f) => GFunctor f-instance (forall a. Generic (f a), forall a b. GFunctorRep a b f) => GFunctor f---- | Internal component of 'GFunctor'.------ This is an example of the \"quantified constraints trick\" to encode--- @forall a b. GMap1 a b (Rep (f a)) (Rep (f b))@ which doesn't actually--- work as-is.-class    GMap1 ((a -> b) :+ ()) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f-instance GMap1 ((a -> b) :+ ()) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f---- *** @gbimap@---- | Constraint for 'gbimap'.-class    (forall a c. Generic (f a c), forall a b c d. GBifunctorRep a b c d f) => GBifunctor f-instance (forall a c. Generic (f a c), forall a b c d. GBifunctorRep a b c d f) => GBifunctor f---- | Internal component of 'GBifunctor'.-class    GMap1 ((a -> b) :+ (c -> d) :+ ()) (Rep (f a c)) (Rep (f b d)) => GBifunctorRep a b c d f-instance GMap1 ((a -> b) :+ (c -> d) :+ ()) (Rep (f a c)) (Rep (f b d)) => GBifunctorRep a b c d f---- *** @gfirst@---- | Constraint for 'gfirst'.-class    (forall a c. Generic (f a c), forall a b c. GFirstRep a b c f) => GFirst f-instance (forall a c. Generic (f a c), forall a b c. GFirstRep a b c f) => GFirst f---- | Internal component of 'GFirst'.-class    GMap1 ((a -> b) :+ ()) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f-instance GMap1 ((a -> b) :+ ()) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f---- *** @gsecond@---- | Constraint for 'gsecond'.-class    (forall a c. Generic (f a c), forall a c d. GFunctorRep c d (f a)) => GSecond f-instance (forall a c. Generic (f a c), forall a c d. GFunctorRep c d (f a)) => GSecond f---- *** Others---- | Constraint for 'gsolomap'.-class    GMap1 ((a -> b) :+ ()) (Rep x) (Rep y) => GSolomap a b x y-instance GMap1 ((a -> b) :+ ()) (Rep x) (Rep y) => GSolomap a b x y---- | Constraint for 'solomap'.-class    Multimap ((a -> b) :+ ()) x y => Solomap a b x y-instance Multimap ((a -> b) :+ ()) x y => Solomap a b x y---- | Constraint for 'gmultimap'.-class    GMap1 arr (Rep x) (Rep y) => GMultimap arr x y-instance GMap1 arr (Rep x) (Rep y) => GMultimap arr x y---- | Constraint for 'multimap'.-class    Multimap_ (S2 arr) x y => Multimap arr x y-instance Multimap_ (S2 arr) x y => Multimap arr x y---- * Deriving Via---- ** Functor---- | @newtype@ for @DerivingVia@ of 'Functor' instances.------ Note: the GHC extension @DeriveFunctor@ already works out-of-the-box in most--- cases. There are exceptions, such as the following example.------ === Example------ @--- {-\# LANGUAGE DeriveGeneric, DerivingVia \#-}------ import "GHC.Generics" ('Generic')--- import "Generic.Functor" ('DeriveFunctor'(..))------ data Twice a = Twice (Either a a)---   deriving 'Generic'---   deriving 'Functor' via ('DeriveFunctor' Twice)--- @-newtype DeriveFunctor f a = DeriveFunctor (f a)--instance GFunctor f => Functor (DeriveFunctor f) where-  fmap = coerce1 (gfmap @f)---- ** Bifunctor---- | @newtype@ for @DerivingVia@ of 'Bifunctor' instances.------ Note: deriving 'Bifunctor' for a generic type often requires 'Functor'--- instances for types mentioned in the fields.------ === Example------ @--- {-\# LANGUAGE DeriveGeneric, DerivingVia \#-}------ import "GHC.Generics" ('Generic')--- import "Generic.Functor" ('DeriveFunctor'(..), 'DeriveBifunctor'(..))------ data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b---   deriving 'Generic'---   deriving 'Functor' via ('DeriveFunctor' (Tree a))---   deriving 'Bifunctor' via ('DeriveBifunctor' Tree)------ data CofreeF f a b = a :< f b---   deriving 'Generic'---   deriving 'Bifunctor' via ('DeriveBifunctor' (CofreeF f))--- @-newtype DeriveBifunctor f a b = DeriveBifunctor (f a b)--instance (GBifunctor f, GFirst f, GSecond f) => Bifunctor (DeriveBifunctor f) where-  bimap = coerce2 (gbimap @f)-  first = coerce3 (gfirst @f)-  second = coerce3 (gsecond @f)---- ** Internal coercions--coerce1 :: Coercible s t => (r -> s) -> (r -> t)-coerce1 = coerce--coerce2 :: Coercible t u => (r -> s -> t) -> (r -> s -> u)-coerce2 = coerce--coerce3 :: (Coercible w v, Coercible (f b d) (g b d)) => (r -> w -> f b d) -> (r -> v -> g b d)-coerce3 = coerce------class GMap1 arr f g where-  gmap1 :: arr -> f () -> g ()--instance GMap1 arr f g => GMap1 arr (M1 i c f) (M1 i' c'' g) where-  gmap1 = coerce (gmap1 @arr @f @g)--instance (GMap1 arr f1 g1, GMap1 arr f2 g2) => GMap1 arr (f1 :+: f2) (g1 :+: g2) where-  gmap1 f (L1 x) = L1 (gmap1 f x)-  gmap1 f (R1 x) = R1 (gmap1 f x)--instance (GMap1 arr f1 g1, GMap1 arr f2 g2) => GMap1 arr (f1 :*: f2) (g1 :*: g2) where-  gmap1 f (x :*: y) = gmap1 f x :*: gmap1 f y--instance GMap1 arr U1 U1 where-  gmap1 _ U1 = U1--instance GMap1 arr V1 V1 where-  gmap1 _ v = case v of {}--instance Multimap arr x y => GMap1 arr (K1 i x) (K1 i' y) where-  gmap1 = coerce (multimap @arr @x @y)---- | Internal implementation of 'Solomap'.-class Multimap_ arr x y where-  multimap_ :: arr -> x -> y---- | Heterogeneous lists of arrows are constructed as lists separated by--- @(':+')@ and terminated by @()@.------ === Example------ Given @f :: a -> a'@ and @g :: b -> b'@,--- @(f ':+' g ':+' ())@ is a list with the two elements @f@ and @g@.------ @--- if---   f :: a -> a'---   g :: b -> b'------ then---   f ':+' g ':+' ()  ::  (a -> a') ':+' (b -> b') ':+' ()--- @------ Those lists are used by 'gmultimap' and 'multimap'.------ @--- bimap_ :: (a -> a') -> (b -> b') -> (Maybe a, [Either b a]) -> (Maybe a', [Either b' a'])--- bimap_ f g = 'multimap' (f ':+' g ':+' ())--- @-data a :+ b = a :+ b-infixr 1 :+---- | @arr@ is the list of arrows provided by the user. It is constant.--- When testing whether any arrow matches, @arr'@ is the remaining list of--- arrows to be tested.-data S arr arr' = S arr arr'--type S2 arr = S arr arr--s2 :: arr -> S2 arr-s2 f = S f f--instance {-# INCOHERENT #-} Multimap_ (S arr ((a -> b) :+ arr')) a b where-  multimap_ (S _ (f :+ _)) = f--instance Multimap_ (S arr arr') x y => Multimap_ (S arr ((a -> b) :+ arr')) x y where-  multimap_ (S f (_ :+ g')) = multimap_ (S f g')---- "id" instance-instance {-# INCOHERENT #-} Multimap_ (S arr ()) x x where-  multimap_ _ = id---- "Functor" instance-instance {-# INCOHERENT #-} (Functor f, Multimap arr x y)-  => Multimap_ (S arr ()) (f x) (f y) where-  multimap_ (S f ()) = fmap (multimap f)---- Intersection of "id" and "Functor" instances. Prefer "id".--- When both of those instances match then this one should match and avoid an--- unnecessary and overly restrictive Functor constraint.-instance {-# INCOHERENT #-} Multimap_ (S arr ()) (f x) (f x) where-  multimap_ _ = id--instance (Multimap arr y1 x1, Multimap arr x2 y2)-  => Multimap_ (S arr ()) (x1 -> x2) (y1 -> y2) where-  multimap_ (S f ()) u = multimap f . u . multimap f---- "Bifunctor" instance.-instance {-# INCOHERENT #-} (Bifunctor f, Multimap arr x1 y1, Multimap arr x2 y2)-  => Multimap_ (S arr ()) (f x1 x2) (f y1 y2) where-  multimap_ (S f ()) = bimap (multimap f) (multimap f)---- Intersection of "Bifunctor" and "Functor" instances. Prefer "Functor".-instance {-# INCOHERENT #-} (Functor (f x), Multimap arr x2 y2)-  => Multimap_ (S arr ()) (f x x2) (f x y2) where-  multimap_ (S f ()) = fmap (multimap f)---- Intersection of "Bifunctor", "Functor", and "id" instances. Prefer "id".-instance {-# INCOHERENT #-} Multimap_ (S arr ()) (f x y) (f x y) where-  multimap_ _ = id+{-# LANGUAGE
+  AllowAmbiguousTypes,
+  ConstraintKinds,
+  EmptyCase,
+  FlexibleContexts,
+  FlexibleInstances,
+  MultiParamTypeClasses,
+  QuantifiedConstraints,
+  RankNTypes,
+  ScopedTypeVariables,
+  TypeApplications,
+  TypeOperators,
+  UndecidableInstances #-}
+
+{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
+
+-- | This is an internal module. Look, don't touch.
+--
+-- "Generic.Functor" is the public API.
+
+module Generic.Functor.Internal where
+
+import ApNormalize
+import Control.Applicative (liftA2)
+import Data.Bifoldable (Bifoldable(..))
+import Data.Bifunctor (Bifunctor(..))
+import Data.Coerce (coerce, Coercible)
+import Data.Functor.Identity (Identity(..))
+import Data.Functor.Const (Const(..))
+import Data.Monoid (Endo(..))
+import GHC.Generics hiding (S)
+
+import Generic.Functor.Internal.Implicit
+
+-- | Generic implementation of 'fmap'. See also 'GenericFunctor' for @DerivingVia@,
+-- using 'gfmap' under the hood.
+--
+-- === Example
+--
+-- @
+-- {-\# LANGUAGE DeriveGeneric \#-}
+--
+-- import "GHC.Generics" ('Generic')
+-- import "Generic.Functor" ('gfmap')
+--
+-- data Twice a = Twice (Either a a)
+--   deriving 'Generic'
+--
+-- instance 'Functor' Twice where
+--   'fmap' = 'gfmap'
+-- @
+--
+-- Unlike 'gsolomap', 'gfmap' is safe to use in all contexts.
+gfmap :: forall f a b. GFunctor f => (a -> b) -> (f a -> f b)
+gfmap f = with @(GFunctorRep a b f) (to . gmapRep (defaultIncoherent f) . from)
+
+-- | Generalized generic functor.
+--
+-- 'gsolomap' is a generalization of 'gfmap' (generic 'fmap'),
+-- where the type parameter to be \"mapped\" does not have to be the last one.
+--
+-- 'gsolomap' is __unsafe__: misuse will break your programs.
+-- Read the <#gsolomapusage Usage> section below for details.
+--
+-- === Example
+--
+-- @
+-- {-\# LANGUAGE DeriveGeneric \#-}
+--
+-- import "GHC.Generics" ('Generic')
+-- import "Generic.Functor" ('gsolomap')
+--
+-- data Result a r = Error a | Ok r  -- Another name for Either
+--   deriving 'Generic'
+--
+-- mapError :: (a -> b) -> Result a r -> Result b r
+-- mapError = 'gsolomap'
+--
+-- mapOk :: (r -> s) -> Result a r -> Result a s
+-- mapOk = 'gsolomap'
+--
+-- mapBoth :: (a -> b) -> Result a a -> Result b b
+-- mapBoth = 'gsolomap'
+-- @
+--
+-- === Usage #gsolomapusage#
+--
+-- (This also applies to 'solomap', 'gmultimap', and 'multimap'.)
+--
+-- 'gsolomap' should only be used to define __polymorphic__ "@fmap@-like functions".
+-- It works only in contexts where @a@ and @b@ are two distinct, non-unifiable
+-- type variables. This is usually the case when they are bound by universal
+-- quantification (@forall a b. ...@), with no equality constraints on @a@ and
+-- @b@.
+--
+-- The one guarantee of 'gsolomap' is that @'gsolomap' 'id' = 'id'@.
+-- Under the above conditions, that law and the types should uniquely determine
+-- the implementation, which 'gsolomap' seeks automatically.
+--
+-- The unsafety is due to the use of incoherent instances as part of the
+-- definition of 'GSolomap'. Functions are safe to specialize after 'GSolomap'
+-- (and 'Solomap') constraints have been discharged.
+--
+-- Note also that the type parameters of 'gsolomap' must all be determined by
+-- the context. For instance, composing two 'gsolomap', as in
+-- @'gsolomap' f . 'gsolomap' g@, is a type error because the type in the middle
+-- cannot be inferred.
+gsolomap :: forall a b x y. (Generic x, Generic y, GSolomap a b x y) => (a -> b) -> (x -> y)
+gsolomap f = to . gmapRep (defaultIncoherent f) . from
+
+-- | Generalized implicit functor.
+--
+-- Use this when @x@ and @y@ are applications of existing functors
+-- ('Functor', 'Bifunctor').
+--
+-- This is a different use case from 'gfmap' and 'gsolomap', which make
+-- functors out of freshly declared @data@ types.
+--
+-- 'solomap' is __unsafe__: misuse will break your programs.
+--
+-- See the <#gsolomapusage Usage> section of 'gsolomap' for details.
+--
+-- === Example
+--
+-- @
+-- map1 :: (a -> b) -> Either e (Maybe [IO a]) -> Either e (Maybe [IO b])
+-- map1 = 'solomap'
+-- -- equivalent to:   fmap . fmap . fmap . fmap
+--
+-- map2 :: (a -> b) -> (e -> Either [a] r) -> (e -> Either [b] r)
+-- map2 = 'solomap'
+-- -- equivalent to:   \\f -> fmap (bimap (fmap f) id)
+-- @
+solomap :: forall a b x y. Solomap a b x y => (a -> b) -> (x -> y)
+solomap f = multimap f
+
+-- | Generic n-ary functor.
+--
+-- A generalization of 'gsolomap' to map over multiple parameters simultaneously.
+-- 'gmultimap' takes a list of functions separated by @(':+')@ and terminated by @()@.
+--
+-- 'gmultimap' is __unsafe__: misuse will break your programs.
+-- The type of every function in the list must be some @(a -> b)@
+-- where @a@ and @b@ are distinct type variables.
+--
+-- See the <#gsolomapusage Usage> section of 'gsolomap' for details.
+--
+-- === Example
+--
+-- @
+-- {-\# LANGUAGE DeriveGeneric \#-}
+--
+-- import "GHC.Generics" ('Generic')
+-- import "Generic.Functor" ('gmultimap')
+--
+-- data Three a b c = One a | Two b | Three c
+--   deriving 'Generic'
+--
+-- mapThree :: (a -> a') -> (b -> b') -> (c -> c') -> Three a b c -> Three a' b' c'
+-- mapThree f g h = 'gmultimap' (f ':+' g ':+' h ':+' ())
+-- @
+gmultimap :: forall arr x y. (Generic x, Generic y, GMultimap arr x y) => arr -> (x -> y)
+gmultimap f = to . gmapRep (defaultIncoherent f) . from
+
+-- | Implicit n-ary functor.
+--
+-- A generalization of 'solomap' to map over multiple parameters simultaneously.
+-- 'multimap' takes a list of functions separated by @(':+')@ and terminated by @()@.
+--
+-- 'multimap' is __unsafe__: misuse will break your programs.
+-- The type of every function in the list must be some @(a -> b)@
+-- where @a@ and @b@ are distinct type variables.
+--
+-- See the <#gsolomapusage Usage> section of 'gsolomap' for details.
+--
+-- === Example
+--
+-- @
+-- type F a b c = Either a (b, c)
+--
+-- map3 :: (a -> a') -> (b -> b') -> (c -> c') -> F a b c -> F a' b' c'
+-- map3 f g h = 'multimap' (f ':+' g ':+' h ':+' ())
+-- -- equivalent to:  \\f g h -> bimap f (bimap g h)
+-- @
+multimap :: forall arr x y. Multimap arr x y => arr -> (x -> y)
+multimap f = multimapI (defaultIncoherent f)
+
+-- | Generic implementation of 'bimap' from 'Bifunctor'. See also 'GenericBifunctor'.
+gbimap :: forall f a b c d. GBimap f => (a -> b) -> (c -> d) -> f a c -> f b d
+gbimap f g = with @(GBimapRep a b c d f) (to . gmapRep (defaultIncoherent (f :+ g)) . from)
+
+-- | Generic implementation of 'first' from 'Bifunctor'. See also 'GenericBifunctor'.
+gfirst :: forall f a b c. GFirst f => (a -> b) -> f a c -> f b c
+gfirst f = with @(GFirstRep a b c f) (to . gmapRep (defaultIncoherent f) . from)
+
+-- | Generic implementation of 'second' from 'Bifunctor'. See also 'GenericBifunctor'.
+gsecond :: forall f a c d. GSecond f => (c -> d) -> f a c -> f a d
+gsecond = gfmap
+
+-- *** Fold
+
+-- | Generic implementation of 'foldMap' from 'Foldable'.
+gfoldMap :: forall t m a. (GFoldMap m t, Monoid m) => (a -> m) -> t a -> m
+gfoldMap f =
+  with @(GFoldMapRep a a m t) (gfoldMapRep (defaultIncoherent (Fold @m @a @a f)) . from)
+
+-- | Generic implementation of 'bifoldMap' from 'Bifoldable'.
+gbifoldMap :: forall t m a b. (GBifoldMap m t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+gbifoldMap f g =
+  with @(GBifoldMapRep a a b b m t) (gfoldMapRep (defaultIncoherent (Fold @m @a @a f :+ Fold @m @b @b g)) . from)
+
+-- *** Traverse
+
+-- | Generic implementation of 'traverse' from 'Traversable'.
+gtraverse :: forall t f a b. (GTraverse f t, Applicative f) => (a -> f b) -> t a -> f (t b)
+gtraverse f = with @(GTraverseRep a b f t) (lowerAps . fmap to . gtraverseRep (defaultIncoherent f) . from)
+
+-- | Generic implementation of 'bitraverse' from 'Bitraversable'.
+gbitraverse :: forall t f a b c d. (GBitraverse f t, Applicative f) => (a -> f b) -> (c -> f d) -> t a c -> f (t b d)
+gbitraverse f g =
+  with @(GBitraverseRep a b c d f t) (lowerAps . fmap to . gtraverseRep (defaultIncoherent (f :+ g)) . from)
+
+
+-- | Explicitly require a constraint, to force the instantiation of a quantified constraint.
+with :: forall c r. (c => r) -> (c => r)
+with x = x
+
+-- ** Top-level constraints
+
+-- *** @gfmap@
+
+-- | Generic 'Functor'. Constraint for 'gfmap'.
+class    (forall a. Generic (f a), forall a b. GFunctorRep a b f) => GFunctor f
+instance (forall a. Generic (f a), forall a b. GFunctorRep a b f) => GFunctor f
+
+-- | Internal component of 'GFunctor'.
+--
+-- This is an example of the \"quantified constraints trick\" to encode
+-- @forall a b. GMap1 a b (Rep (f a)) (Rep (f b))@ which doesn't actually
+-- work as-is.
+class    GMap1 (Default Incoherent (a -> b)) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f
+instance GMap1 (Default Incoherent (a -> b)) (Rep (f a)) (Rep (f b)) => GFunctorRep a b f
+
+-- *** @gbimap@
+
+-- | Constraint for 'gbimap'.
+class    (forall a c. Generic (f a c), forall a b c d. GBimapRep a b c d f) => GBimap f
+instance (forall a c. Generic (f a c), forall a b c d. GBimapRep a b c d f) => GBimap f
+
+-- | Internal component of 'GBifunctor'.
+class    GMap1 (Default Incoherent ((a -> b) :+ (c -> d))) (Rep (f a c)) (Rep (f b d)) => GBimapRep a b c d f
+instance GMap1 (Default Incoherent ((a -> b) :+ (c -> d))) (Rep (f a c)) (Rep (f b d)) => GBimapRep a b c d f
+
+-- *** @gfirst@
+
+-- | Constraint for 'gfirst'.
+class    (forall a c. Generic (f a c), forall a b c. GFirstRep a b c f) => GFirst f
+instance (forall a c. Generic (f a c), forall a b c. GFirstRep a b c f) => GFirst f
+
+-- | Internal component of 'GFirst'.
+class    GMap1 (Default Incoherent (a -> b)) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f
+instance GMap1 (Default Incoherent (a -> b)) (Rep (f a c)) (Rep (f b c)) => GFirstRep a b c f
+
+-- *** @gsecond@
+
+-- | Constraint for 'gsecond'.
+class    (forall a c. Generic (f a c), forall a c d. GFunctorRep c d (f a)) => GSecond f
+instance (forall a c. Generic (f a c), forall a c d. GFunctorRep c d (f a)) => GSecond f
+
+-- | Generic 'Bifunctor'.
+class    (GBimap f, GFirst f, GSecond f) => GBifunctor f
+instance (GBimap f, GFirst f, GSecond f) => GBifunctor f
+
+-- *** @gtraverse@
+
+-- | Constraint for 'gtraverse'.
+class    (forall a. Generic (t a), forall a b. GTraverseRep a b f t) => GTraverse f t
+instance (forall a. Generic (t a), forall a b. GTraverseRep a b f t) => GTraverse f t
+
+class    GTraverse1 f (Default Incoherent (a -> f b)) (Rep (t a)) (Rep (t b)) => GTraverseRep a b f t
+instance GTraverse1 f (Default Incoherent (a -> f b)) (Rep (t a)) (Rep (t b)) => GTraverseRep a b f t
+
+-- | Generic 'Traversable'.
+class    (forall f. Applicative f => GBitraverse f t) => GTraversable t
+instance (forall f. Applicative f => GBitraverse f t) => GTraversable t
+
+-- | Constraint for 'gtraverse'.
+class    (forall a b. Generic (t a b), forall a b c d. GBitraverseRep a b c d f t) => GBitraverse f t
+instance (forall a b. Generic (t a b), forall a b c d. GBitraverseRep a b c d f t) => GBitraverse f t
+
+class    GTraverse1 f (Default Incoherent ((a -> f b) :+ (c -> f d))) (Rep (t a c)) (Rep (t b d)) => GBitraverseRep a b c d f t
+instance GTraverse1 f (Default Incoherent ((a -> f b) :+ (c -> f d))) (Rep (t a c)) (Rep (t b d)) => GBitraverseRep a b c d f t
+
+-- | Generic 'Bitraversable'.
+class    (forall f. Applicative f => GBitraverse f t) => GBitraversable t
+instance (forall f. Applicative f => GBitraverse f t) => GBitraversable t
+
+-- *** @foldMap@
+
+-- | Constraint for 'gfoldMap'.
+class    (forall a. Generic (t a), forall a b. GFoldMapRep a b m t) => GFoldMap m t
+instance (forall a. Generic (t a), forall a b. GFoldMapRep a b m t) => GFoldMap m t
+
+class    GFoldMap1 m (Default Incoherent (Fold m a b)) (Rep (t a)) (Rep (t b)) => GFoldMapRep a b m t
+instance GFoldMap1 m (Default Incoherent (Fold m a b)) (Rep (t a)) (Rep (t b)) => GFoldMapRep a b m t
+
+-- | Generic 'Foldable'. Constraint for 'GenericFunctor' (deriving-via 'Foldable').
+class    (forall m. Monoid m => GFoldMap m t) => GFoldable t
+instance (forall m. Monoid m => GFoldMap m t) => GFoldable t
+
+-- | Constraint for 'gbifoldMap'.
+class    (forall a b. Generic (t a b), forall a b c d. GBifoldMapRep a b c d m t) => GBifoldMap m t
+instance (forall a b. Generic (t a b), forall a b c d. GBifoldMapRep a b c d m t) => GBifoldMap m t
+
+class    GFoldMap1 m (Default Incoherent (Fold m a b :+ Fold m c d)) (Rep (t a c)) (Rep (t b d)) => GBifoldMapRep a b c d m t
+instance GFoldMap1 m (Default Incoherent (Fold m a b :+ Fold m c d)) (Rep (t a c)) (Rep (t b d)) => GBifoldMapRep a b c d m t
+
+-- | Generic 'Foldable'. Constraint for 'GenericFunctor' (deriving-via 'Foldable').
+class    (forall m. Monoid m => GBifoldMap m t) => GBifoldable t
+instance (forall m. Monoid m => GBifoldMap m t) => GBifoldable t
+
+-- *** Others
+
+-- | Constraint for 'gsolomap'.
+class    GMultimap (a -> b) x y => GSolomap a b x y
+instance GMultimap (a -> b) x y => GSolomap a b x y
+
+-- | Constraint for 'solomap'.
+class    Multimap (a -> b) x y => Solomap a b x y
+instance Multimap (a -> b) x y => Solomap a b x y
+
+-- | Constraint for 'gmultimap'.
+class    GMap1 (Default Incoherent arr) (Rep x) (Rep y) => GMultimap arr x y
+instance GMap1 (Default Incoherent arr) (Rep x) (Rep y) => GMultimap arr x y
+
+-- | Constraint for 'multimap'.
+class    MultimapI (Default Incoherent arr) x y => Multimap arr x y
+instance MultimapI (Default Incoherent arr) x y => Multimap arr x y
+
+-- * Deriving Via
+
+-- ** Functor
+
+-- | @newtype@ for @DerivingVia@ of 'Functor' and 'Foldable' instances.
+--
+-- Note: the GHC extensions @DeriveFunctor@, @DeriveFoldable@, and @DeriveTraversable@
+-- (which implies all three) already works out-of-the-box in most cases.
+-- There are exceptions, such as the following example.
+--
+-- === Example
+--
+-- @
+-- {-\# LANGUAGE DeriveGeneric, DerivingVia \#-}
+--
+-- import "GHC.Generics" ('Generic')
+-- import "Generic.Functor" ('GenericFunctor'(..))
+--
+-- data Twice a = Twice (Either a a)
+--   deriving 'Generic'
+--   deriving ('Functor', 'Foldable') via ('GenericFunctor' Twice)
+-- @
+newtype GenericFunctor f a = GenericFunctor (f a)
+
+instance GFunctor f => Functor (GenericFunctor f) where
+  fmap = coerce1 (gfmap @f)
+
+instance GFoldable f => Foldable (GenericFunctor f) where
+  foldMap = coerceFoldMap (gfoldMap @f)
+
+-- ** Bifunctor
+
+-- | @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.
+--
+-- === Example
+--
+-- @
+-- {-\# LANGUAGE DeriveGeneric, DerivingVia \#-}
+--
+-- import "Data.Bifoldable" ('Bifoldable')
+-- import "Data.Bifunctor" ('Bifunctor')
+-- 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', 'Foldable') via ('GenericFunctor' (Tree a))
+--   deriving ('Bifunctor', 'Bifoldable') via ('GenericBifunctor' Tree)
+--
+-- data CofreeF f a b = a :< f b
+--   deriving 'Generic'
+--   deriving ('Bifunctor', 'Bifoldable') via ('GenericBifunctor' (CofreeF f))
+-- @
+newtype GenericBifunctor f a b = GenericBifunctor (f a b)
+
+instance GBifunctor f => Bifunctor (GenericBifunctor f) where
+  bimap = coerce2 (gbimap @f)
+  first = coerce3 (gfirst @f)
+  second = coerce3 (gsecond @f)
+
+instance GBifoldable f => Bifoldable (GenericBifunctor f) where
+  bifoldMap = coerceBifoldMap (gbifoldMap @f)
+
+-- ** Internal coercions
+
+coerce1 :: Coercible s t => (r -> s) -> (r -> t)
+coerce1 = coerce
+
+coerce2 :: Coercible t u => (r -> s -> t) -> (r -> s -> u)
+coerce2 = coerce
+
+coerce3 :: (Coercible w v, Coercible (f b d) (g b d)) => (r -> w -> f b d) -> (r -> v -> g b d)
+coerce3 = coerce
+
+coerceFoldMap :: Coercible t u => (am -> t -> m) -> (am -> u -> m)
+coerceFoldMap = coerce
+
+coerceBifoldMap :: Coercible t u => (am -> bm -> t -> m) -> (am -> bm -> u -> m)
+coerceBifoldMap = coerce
+
+-- ** @GMultimapK@
+
+-- | We use the same class to implement all of 'fmap', 'foldMap', 'traverse',
+-- instantiating @m@ as 'Identity', 'Const (EndoM mm)' and 'Aps n' respectively.
+-- Those three cases differ in their instances for 'K1'.
+--
+-- (the K stands for @Kleisli@, because the result is @Kleisli m (f ()) (g ())@
+class GMultimapK m arr f g where
+  gmultimapK :: arr -> f () -> m (g ())
+
+-- *** Instance for @fmap@
+
+instance MultimapI arr x y => GMultimapK Identity arr (K1 i x) (K1 i' y) where
+  gmultimapK = coerce (multimapI @arr @x @y)
+
+class    GMultimapK Identity arr f g => GMap1 arr f g
+instance GMultimapK Identity arr f g => GMap1 arr f g
+
+gmapRep :: GMap1 arr f g => arr -> f () -> g ()
+gmapRep f x = runIdentity (gmultimapK f x)
+
+-- *** Instance for @foldMap@
+
+instance (Multifold_ m arr x y, Monoid m) => GMultimapK (Const (EndoM m)) arr (K1 i x) (K1 i' y) where
+  gmultimapK f (K1 x) = K1 <$> foldToConst (multifold_ f) x
+
+-- Spooky instance. It makes sense only because @GMultimapK (Const (EndoM m))@
+-- occurs exclusively under a quantified constraint (in the definition of GFoldMap).
+instance {-# INCOHERENT #-} GMultimapK (Const (EndoM m)) arr (K1 i x) (K1 i x) where
+  gmultimapK _ (K1 _) = Const (Endo id)
+
+-- An extra wrapper to simplify away @(mempty <> _)@ and @(_ <> mempty)@.
+type EndoM m = Endo (Maybe m)
+
+unEndoM :: Monoid m => EndoM m -> m
+unEndoM (Endo f) = case f Nothing of
+  Nothing -> mempty
+  Just y -> y
+
+liftEndoM :: Monoid m => m -> EndoM m
+liftEndoM y = Endo (Just . app)
+  where
+    app Nothing = y
+    app (Just y') = y `mappend` y'
+
+foldToConst :: Monoid m => Fold m x y -> x -> Const (EndoM m) y
+foldToConst (Fold f) x = Const (liftEndoM (f x))
+
+class    GMultimapK (Const (EndoM m)) arr f g => GFoldMap1 m arr f g
+instance GMultimapK (Const (EndoM m)) arr f g => GFoldMap1 m arr f g
+
+-- | Danger! @GFoldMap1 m arr f f@ MUST come from a quantified constraint (see use in 'gfoldMap').
+gfoldMapRep :: forall m arr f. (GFoldMap1 m arr f f, Monoid m) => arr -> f () -> m
+gfoldMapRep f x = unEndoM (getConst (gmultimapK f x :: Const (EndoM m) (f ())))
+
+-- *** Instance for @traverse@
+
+instance (Multitraverse m arr x y) => GMultimapK (Aps m) arr (K1 i x) (K1 i' y) where
+  gmultimapK f (K1 x) = K1 <$>^ multitraverse f x
+
+class    GMultimapK (Aps m) arr f g => GTraverse1 m arr f g
+instance GMultimapK (Aps m) arr f g => GTraverse1 m arr f g
+
+gtraverseRep :: GTraverse1 m arr f g => arr -> f () -> Aps m (g ())
+gtraverseRep = gmultimapK
+
+-- *** Common instances
+
+instance (GMultimapK m arr f g, Functor m) => GMultimapK m arr (M1 i c f) (M1 i' c' g) where
+  gmultimapK f (M1 x) = M1 <$> gmultimapK f x
+
+instance
+  (GMultimapK m arr f1 g1, GMultimapK m arr f2 g2, Applicative m) =>
+  GMultimapK m arr (f1 :+: f2) (g1 :+: g2)
+  where
+  gmultimapK f (L1 x) = L1 <$> gmultimapK f x
+  gmultimapK f (R1 y) = R1 <$> gmultimapK f y
+
+instance
+  (GMultimapK m arr f1 g1, GMultimapK m arr f2 g2, Applicative m) =>
+  GMultimapK m arr (f1 :*: f2) (g1 :*: g2)
+  where
+  gmultimapK f (x :*: y) = liftA2 (:*:) (gmultimapK f x) (gmultimapK f y)
+
+instance Applicative m => GMultimapK m arr U1 U1 where
+  gmultimapK _ U1 = pure U1
+
+instance GMultimapK m arr V1 V1 where
+  gmultimapK _ v = case v of
+ src/Generic/Functor/Internal/Implicit.hs view
@@ -0,0 +1,225 @@+{-# LANGUAGE
+  ConstraintKinds,
+  FlexibleContexts,
+  FlexibleInstances,
+  InstanceSigs,
+  MultiParamTypeClasses,
+  RankNTypes,
+  ScopedTypeVariables,
+  TypeApplications,
+  TypeFamilies,
+  TypeOperators,
+  UndecidableInstances #-}
+{-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-}
+
+module Generic.Functor.Internal.Implicit where
+
+import Control.Arrow (Kleisli (..))
+import Data.Bifunctor (Bifunctor (..))
+import Data.Bifoldable (Bifoldable (..))
+import Data.Bitraversable (Bitraversable (..))
+import Data.Coerce (Coercible, coerce)
+import Data.Kind (Type)
+
+-- | Core of 'multimap'
+multimapI :: forall arr x y. MultimapI arr x y => arr -> (x -> y)
+multimapI = multimapOf
+
+multitraverse :: forall f arr x y. Multitraverse f arr x y => arr -> (x -> f y)
+multitraverse f = runKleisli (multimapOf (coerce f :: WrapKleisli f arr))
+
+-- | This is kept internal because of the 'Fold' wrapping.
+multifold_ :: forall m arr x y. Multifold_ m arr x y => arr -> Fold m x y
+multifold_ = multimapOf
+
+multimapOf :: forall cat arr x y. MultimapOf cat arr x y => arr -> cat x y
+multimapOf f = multimap_ (s2 f)
+
+-- | Core of 'multimap'.
+class    MultimapOf (->) arr x y => MultimapI arr x y
+instance MultimapOf (->) arr x y => MultimapI arr x y
+
+-- | Constraint for 'multifold_'.
+class    MultimapOf (Fold m) arr x y => Multifold_ m arr x y
+instance MultimapOf (Fold m) arr x y => Multifold_ m arr x y
+
+-- | Constraint for 'multitraverse'.
+class    Multitraverse_ f arr x y => Multitraverse f arr x y
+instance Multitraverse_ f arr x y => Multitraverse f arr x y
+
+-- | Internal definition of 'Multitraverse'
+type Multitraverse_ f arr x y =
+  ( MultimapOf (Kleisli f) (WrapKleisli f arr) x y,
+    CoercibleKleisli f (WrapKleisli f arr) arr
+  )
+
+type family WrapKleisli (f :: Type -> Type) (arr :: Type)
+type instance WrapKleisli _f NilArr = NilArr
+type instance WrapKleisli _f (Rule rule mode)= Rule rule mode
+type instance WrapKleisli f (a :+ arr) = WrapKleisli f a :+ WrapKleisli f arr
+type instance WrapKleisli f (a -> f b) = Kleisli f a b
+
+-- | Auxiliary constraint for 'Multitraverse'
+class Coercible warr arr => CoercibleKleisli (f :: Type -> Type) warr arr
+instance (d ~ NilArr) => CoercibleKleisli f d NilArr
+instance (d ~ Rule rule mode) => CoercibleKleisli f d (Rule rule mode)
+instance (CoercibleKleisli f a b, CoercibleKleisli f arr arr') => CoercibleKleisli f (a :+ arr) (b :+ arr')
+instance (b2 ~ f c, a ~ Kleisli f b1 c) => CoercibleKleisli f a (b1 -> b2)
+
+class    Multimap_ cat (S2 arr) x y => MultimapOf cat arr x y
+instance Multimap_ cat (S2 arr) x y => MultimapOf cat arr x y
+
+-- | @Fold m@ is like @Kleisli (Const m)@, but it has a different @FunctorOf@ instance,
+-- with 'Foldable' instead of 'Traversable'.
+newtype Fold m x y = Fold { unFold :: x -> m }
+
+instance Monoid m => CatLike (Fold m) where
+  catid = Fold (\_ -> mempty)
+
+instance (Foldable t, Monoid m) => FunctorOf (Fold m) t where
+  catmap (Fold f) = Fold (foldMap f)
+
+instance (Bifoldable t, Monoid m) => BifunctorOf (Fold m) t where
+  catbimap (Fold f) (Fold g) = Fold (bifoldMap f g)
+
+-- * Internal
+
+class CatLike cat where
+  catid :: cat x x
+
+instance CatLike (->) where
+  catid = id
+
+instance Applicative f => CatLike (Kleisli f) where
+  catid = Kleisli pure
+
+class FunctorOf cat t where
+  catmap :: cat a b -> cat (t a) (t b)
+
+instance Functor t => FunctorOf (->) t where
+  catmap = fmap
+
+instance (Applicative f, Traversable t) => FunctorOf (Kleisli f) t where
+  catmap :: forall a b. Kleisli f a b -> Kleisli f (t a) (t b)
+  catmap = coerce (traverse @t @f @a @b)
+
+class BifunctorOf cat t where
+  catbimap :: cat a b -> cat c d -> cat (t a c) (t b d)
+
+instance Bifunctor t => BifunctorOf (->) t where
+  catbimap = bimap
+
+instance (Applicative f, Bitraversable t) => BifunctorOf (Kleisli f) t where
+  catbimap :: forall a b c d. Kleisli f a b -> Kleisli f c d -> Kleisli f (t a c) (t b d)
+  catbimap = coerce (bitraverse @t @f @a @b @c @d)
+
+-- | Internal implementation of 'MultimapOf'.
+class Multimap_ cat arr x y where
+  multimap_ :: arr -> cat x y
+
+-- | Heterogeneous lists of arrows are constructed as lists separated by
+-- @(':+')@ and terminated by @()@.
+--
+-- === Example
+--
+-- Given @f :: a -> a'@ and @g :: b -> b'@,
+-- @(f ':+' g ':+' ())@ is a list with the two elements @f@ and @g@.
+--
+-- @
+-- if
+--   f :: a -> a'
+--   g :: b -> b'
+--
+-- then
+--   f ':+' g ':+' ()  ::  (a -> a') ':+' (b -> b') ':+' ()
+-- @
+--
+-- Those lists are used by 'gmultimap' and 'multimap'.
+--
+-- @
+-- bimap_ :: (a -> a') -> (b -> b') -> (Maybe a, [Either b a]) -> (Maybe a', [Either b' a'])
+-- bimap_ f g = 'multimap' (f ':+' g ':+' ())
+-- @
+data a :+ b = a :+ b
+
+infixr 1 :+
+
+-- Special arrows
+
+data Rule rule mode = Rule rule mode
+data AnyId = AnyId
+data AnyFunctor = AnyFunctor
+data AnyBifunctor = AnyBifunctor
+data NilArr = NilArr
+
+data Incoherent = Incoherent
+
+type Default mode arr = arr :+ Rule AnyId mode :+ Rule AnyFunctor mode :+ Rule AnyBifunctor mode :+ NilArr
+
+defaultIncoherent :: arr -> Default Incoherent arr
+defaultIncoherent = def Incoherent
+
+def :: mode -> arr -> Default mode arr
+def mode arr = arr :+ Rule AnyId mode :+ Rule AnyFunctor mode :+ Rule AnyBifunctor mode :+ NilArr
+
+-- | @arr@ is the list of arrows provided by the user. It is constant.
+-- When testing whether any arrow matches, @arr'@ is the remaining list of
+-- arrows to be tested.
+data S arr arr' = S arr arr'
+
+type S2 arr = S arr arr
+
+s2 :: arr -> S2 arr
+s2 f = S f f
+
+-- The head doesn't match anything, go to the next thing.
+instance {-# OVERLAPPABLE #-} Multimap_ cat (S arr arr') x y => Multimap_ cat (S arr (arr0 :+ arr')) x y where
+  multimap_ (S f (_ :+ g')) = multimap_ (S f g')
+
+-- Reassociate to even handle tree-shaped parameters.
+instance Multimap_ cat (S arr (arr0 :+ arr1 :+ arr2)) x y => Multimap_ cat (S arr ((arr0 :+ arr1) :+ arr2)) x y where
+  multimap_ (S f ((f0 :+ f1) :+ f2)) = multimap_ (S f (f0 :+ f1 :+ f2))
+
+instance Multimap_ cat (S arr arr') x y => Multimap_ cat (S arr (NilArr :+ arr')) x y where
+  multimap_ (S f (NilArr :+ f')) = multimap_ (S f f')
+
+instance Multimap_ cat (S arr arr') x y => Multimap_ cat (S arr (() :+ arr')) x y where
+  multimap_ (S f (() :+ f')) = multimap_ (S f f')
+
+instance {-# INCOHERENT #-} Multimap_ cat (S arr (cat a b :+ arr')) a b where
+  multimap_ (S _ (f :+ _)) = f
+
+-- "id" instance
+instance {-# INCOHERENT #-} CatLike cat => Multimap_ cat (S arr (Rule AnyId Incoherent :+ arr')) x x where
+  multimap_ _ = catid
+
+-- "Functor" instance
+-- Note: if x ~ y, then @AnyId Incoherent@ should already have matched earlier
+-- (if you remembered to put it in the list),
+-- so we don't need another overlapping instance here.
+instance
+  {-# INCOHERENT #-}
+  (FunctorOf cat f, MultimapOf cat arr x y) =>
+  Multimap_ cat (S arr (Rule AnyFunctor Incoherent :+ arr')) (f x) (f y)
+  where
+  multimap_ (S f (Rule AnyFunctor Incoherent :+ _)) = catmap (multimapOf f)
+
+-- "Bifunctor" instance.
+-- Note: the overlap with AnyId (where x1 ~ y1, x2 ~ y2) and AnyFunctor (where x1 ~ x2)
+-- is handled by putting those rules before AnyBifunctor in the list.
+instance
+  {-# INCOHERENT #-}
+  (BifunctorOf cat f, MultimapOf cat arr x1 y1, MultimapOf cat arr x2 y2) =>
+  Multimap_ cat (S arr (Rule AnyBifunctor Incoherent :+ arr')) (f x1 x2) (f y1 y2)
+  where
+  multimap_ (S f (Rule AnyBifunctor Incoherent :+ _)) = catbimap (multimapOf f) (multimapOf f)
+
+-- Hardcoded special case for (->)
+-- We know how to "Multimap_ (->)" over (->),
+-- not "Multimap_ (Kleisli f)".
+instance
+  {-# INCOHERENT #-}
+  (MultimapOf (->) arr y1 x1, MultimapOf (->) arr x2 y2) =>
+  Multimap_ (->) (S arr (Rule AnyBifunctor Incoherent :+ arr')) (x1 -> x2) (y1 -> y2)
+  where
+  multimap_ (S f (Rule AnyBifunctor Incoherent :+ _)) u = multimapOf f . u . multimapOf f
test/test.hs view
@@ -1,139 +1,220 @@-{-# LANGUAGE-  DeriveGeneric,-  DerivingVia #-}--import Data.Bifunctor-import GHC.Generics-import Generic.Functor-import System.Exit (exitFailure)---- Testing DeriveFunctor (gfmap) and gsolomap--data Empty a-  deriving Generic-  deriving Functor via (DeriveFunctor Empty)--data Unit a = Unit-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor Unit)--data Result a r = Error a | Ok r-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor (Result a))-  -mapError :: (a -> b) -> Result a r -> Result b r-mapError = gsolomap--mapOk :: (r -> s) -> Result a r -> Result a s-mapOk = gsolomap--mapBoth :: (a -> b) -> Result a a -> Result b b-mapBoth = gsolomap--data Writer w a = Writer w a-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor (Writer w))--mapW :: (w -> w') -> Writer w a -> Writer w' a-mapW = gsolomap--data Square a b = Square a a b b-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor (Square a))--mapFirst :: (a -> a') -> Square a b -> Square a' b-mapFirst = gsolomap--data Twice a = Twice (Either a a)-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor Twice)---- Testing solomap--map1, map1' :: (a -> b) -> Either e (Maybe [(e, a)]) -> Either e (Maybe [(e, b)])-map1 = solomap-map1' = fmap . fmap . fmap . fmap  -- equivalent definition, just making sure it typechecks--map2, map2' :: (a -> b) -> (e -> Either [a] r) -> (e -> Either [b] r)-map2 = solomap-map2' f = fmap (bimap (fmap f) id)--type F a = ([a], Either a ())--map3, map3' :: (a -> b) -> F a -> F b-map3 = solomap-map3' f = bimap (fmap f) (bimap f id)--type G t a = (t, Maybe [Either Bool a])--map4 :: (a -> b) -> G t a -> G t b-map4 = solomap-map4' = fmap . fmap . fmap . fmap---- Deriving Bifunctor--data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b-  deriving (Eq, Show, Generic)-  deriving Functor via (DeriveFunctor (Tree a))-  deriving Bifunctor via (DeriveBifunctor Tree)--data CofreeF f a b = a :< f b-  deriving (Eq, Show, Generic)-  deriving Bifunctor via (DeriveBifunctor (CofreeF f))---- Multimap--data Three a b c = One a | Two b | Three c-  deriving (Eq, Show, Generic)--mapThree :: (a -> a') -> (b -> b') -> (c -> c') -> Three a b c -> Three a' b' c'-mapThree f g h = gmultimap (f :+ g :+ h :+ ())--type F5 a b c = Either a (b, c)--map5 :: (a -> a') -> (b -> b') -> (c -> c') -> F5 a b c -> F5 a' b' c'-map5 f g h = multimap (f :+ g :+ h :+ ())-map5' f g h = bimap f (bimap g h)---- Run at least once--twice :: Int -> Int-twice = (* 2)--main :: IO ()-main = do-  Unit @= fmap twice Unit-  Ok 8 @= fmap twice (Ok 4 :: Result () Int)-  Error 8 @= mapError twice (Error 4 :: Result Int ())-  Writer () 8 @= fmap twice (Writer () 4)-  Writer 8 () @= mapW twice (Writer 4 ())-  Square () () 8 10 @= fmap twice (Square () () 4 5)-  Square 8 10 () () @= mapFirst twice (Square 4 5 () ())-  [Twice (Left 8), Twice (Right 10)] @= (fmap . fmap) twice [Twice (Left 4), Twice (Right 5)]-  Node 8 (Leaf 10) (Leaf 12) @= bimap twice twice (Node 4 (Leaf 5) (Leaf 6))-  (8 :< Just 10) @= bimap twice twice (4 :< Just 5)-  [One 8, Two False, Three 1] @= fmap (mapThree twice not length) [One 4, Two True, Three [()]]--  let t1 = Right (Just [((), 4)])-  map1 twice t1 @= map1' twice t1--  let t2 x = Left [x] :: Either [Int] ()-  map2 twice t2 4 @= map2' twice t2 4--  let t3 = ([4], Left 5)-  map3 twice t3 @= map3' twice t3--  let t4 = ((), Just [Right 4])-  map4 twice t4 @= map4' twice t4--  let t5 = [Left 4, Right (False, [()])]-  fmap (map5 twice not length) t5 @= fmap (map5 twice not length) t5---- Assert equality-(@=) :: (Eq a, Show a) => a -> a -> IO ()-(@=) x y | x == y = pure ()-         | otherwise = do-  putStrLn "Not equal:"-  print x-  print y-  exitFailure+{-# LANGUAGE
+  DeriveFoldable,
+  DeriveGeneric,
+  DerivingVia,
+  StandaloneDeriving,
+  TypeOperators #-}
+
+import Control.Monad.Trans.State ( evalState, state, State )
+import Data.Bifoldable ( Bifoldable() )
+import Data.Bifunctor ( Bifunctor(bimap) )
+import GHC.Generics ( Generic )
+import System.Exit (exitFailure)
+
+import Generic.Functor
+    ( gmultimap,
+      gsolomap,
+      gtraverse,
+      multimap,
+      solomap,
+      GenericBifunctor(..),
+      GenericFunctor(..),
+      type (:+)((:+)) )
+
+-- Testing GenericFunctor (gfmap) and gsolomap
+
+data Empty a
+  deriving Generic
+  deriving (Functor, Foldable) via (GenericFunctor Empty)
+
+data Unit a = Unit
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor Unit)
+
+data Result a r = Error a | Ok r
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor (Result a))
+
+instance Traversable Empty where
+  traverse = gtraverse
+
+instance Traversable Unit where
+  traverse = gtraverse
+
+instance Traversable (Result a) where
+  traverse = gtraverse
+  
+mapError :: (a -> b) -> Result a r -> Result b r
+mapError = gsolomap
+
+mapOk :: (r -> s) -> Result a r -> Result a s
+mapOk = gsolomap
+
+mapBoth :: (a -> b) -> Result a a -> Result b b
+mapBoth = gsolomap
+
+data Writer w a = Writer w a
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor (Writer w))
+
+instance Traversable (Writer w) where
+  traverse = gtraverse
+
+mapW :: (w -> w') -> Writer w a -> Writer w' a
+mapW = gsolomap
+
+data Square a b = Square a a b b
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor (Square a))
+
+instance Traversable (Square a) where
+  traverse = gtraverse
+
+mapFirst :: (a -> a') -> Square a b -> Square a' b
+mapFirst = gsolomap
+
+data Twice a = Twice (Either a a)
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor Twice)
+
+instance Traversable Twice where
+  traverse = gtraverse
+
+-- Testing solomap
+
+map1, map1' :: (a -> b) -> Either e (Maybe [(e, a)]) -> Either e (Maybe [(e, b)])
+map1 = solomap
+map1' = fmap . fmap . fmap . fmap  -- equivalent definition, just making sure it typechecks
+
+map2, map2' :: (a -> b) -> (e -> Either [a] r) -> (e -> Either [b] r)
+map2 = solomap
+map2' f = fmap (bimap (fmap f) id)
+
+type F a = ([a], Either a ())
+
+map3, map3' :: (a -> b) -> F a -> F b
+map3 = solomap
+map3' f = bimap (fmap f) (bimap f id)
+
+type G t a = (t, Maybe [Either Bool a])
+
+map4, map4', map4'' :: (a -> b) -> G t a -> G t b
+map4 = solomap
+map4' = fmap . fmap . fmap . fmap
+map4'' = multimap
+
+map6, map6' :: (a -> b) -> (c -> d) -> G a c -> G b d
+map6 f g = multimap (f :+ g)
+map6' f = bimap f . fmap . fmap . fmap
+
+-- Deriving Bifunctor
+
+data Tree a b = Node a (Tree a b) (Tree a b) | Leaf b
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor (Tree a))
+  deriving (Bifunctor, Bifoldable) via (GenericBifunctor Tree)
+
+instance Traversable (Tree a) where
+  traverse = gtraverse
+
+data CofreeF f a b = a :< f b
+  deriving (Eq, Show, Generic)
+  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
+
+bimapCofreeF' :: Functor f => (a -> b) -> (c -> d) -> CofreeF f a c -> CofreeF f b d
+bimapCofreeF' f g = gmultimap (f :+ g)
+
+-- Multimap
+
+data Three a b c = One a | Two b | Three c
+  deriving (Eq, Show, Generic)
+  deriving (Functor, Foldable) via (GenericFunctor (Three a b))
+
+instance Traversable (Three a b) where
+  traverse = gtraverse
+
+mapThree :: (a -> a') -> (b -> b') -> (c -> c') -> Three a b c -> Three a' b' c'
+mapThree f g h = gmultimap (f :+ g :+ h)
+
+type F5 a b c = Either a (b, c)
+
+map5, map5' :: (a -> a') -> (b -> b') -> (c -> c') -> F5 a b c -> F5 a' b' c'
+map5 f g h = multimap (f :+ g :+ h)
+map5' f g h = bimap f (bimap g h)
+
+-- Run at least once
+
+twice :: Int -> Int
+twice = (* 2)
+
+foldTest :: Foldable t => t Int -> Int
+foldTest = sum  -- specialized
+
+tick :: Int -> State Int Int
+tick _ = state (\i -> (i, i+1))
+
+travTest :: Traversable t => t Int -> t Int
+travTest = (`evalState` 0) . traverse tick
+
+main :: IO ()
+main = do
+  Unit @= fmap twice Unit
+  Ok 8 @= fmap twice (Ok 4 :: Result () Int)
+  Error 8 @= mapError twice (Error 4 :: Result Int ())
+  Writer () 8 @= fmap twice (Writer () 4)
+  Writer 8 () @= mapW twice (Writer 4 ())
+  Square () () 8 10 @= fmap twice (Square () () 4 5)
+  Square 8 10 () () @= mapFirst twice (Square 4 5 () ())
+  [Twice (Left 8), Twice (Right 10)] @= (fmap . fmap) twice [Twice (Left 4), Twice (Right 5)]
+  Node 8 (Leaf 10) (Leaf 12) @= bimap twice twice (Node 4 (Leaf 5) (Leaf 6))
+  (8 :< Just 10) @= bimap twice twice (4 :< Just 5)
+  [One 8, Two False, Three 1] @= fmap (mapThree twice not length) [One 4, Two True, Three [()]]
+
+  let t1 = Right (Just [((), 4)])
+  map1 twice t1 @= map1' twice t1
+
+  let t2 x = Left [x] :: Either [Int] ()
+  map2 twice t2 4 @= map2' twice t2 4
+
+  let t3 = ([4], Left 5)
+  map3 twice t3 @= map3' twice t3
+
+  let t4 = ((), Just [Right 4])
+  map4 twice t4 @= map4' twice t4
+  map4 twice t4 @= map4'' twice t4
+
+  map6 (const True) twice t4 @= map6' (const True) twice t4
+
+  let t5 = [Left 4, Right (False, [()])]
+  fmap (map5 twice not length) t5 @= fmap (map5 twice not length) t5
+
+  -- Foldable
+  0 @= foldTest Unit
+  4 @= foldTest (Ok 4 :: Result () Int)
+  0 @= foldTest (Error 4 :: Result Int Int)
+  4 @= foldTest (Writer () 4)
+  9 @= foldTest (Square () () 4 5)
+  3 @= foldTest (Node 4 (Leaf 1) (Leaf 2) :: Tree Int Int)
+
+  -- Traversable
+  Unit @= travTest Unit
+  Ok 0 @= travTest (Ok 4 :: Result () Int)
+  Error 4 @= travTest (Error 4 :: Result Int Int)
+  Writer () 0 @= travTest (Writer () 4)
+  Square () () 0 1 @= travTest (Square () () 4 5)
+  Node 4 (Leaf 0) (Leaf 1) @= travTest (Node 4 (Leaf 5) (Leaf 6) :: Tree Int Int)
+
+-- Assert equality
+(@=) :: (Eq a, Show a) => a -> a -> IO ()
+(@=) x y | x == y = pure ()
+         | otherwise = do
+  putStrLn "Not equal:"
+  print x
+  print y
+  exitFailure