packages feed

endo 0.2.0.1 → 0.3.0.0

raw patch · 10 files changed

+1499/−508 lines, 10 filesdep +data-default-classdep +mtlPVP ok

version bump matches the API change (PVP)

Dependencies added: data-default-class, mtl

API changes (from Hackage documentation)

- Data.Monoid.Endo: appEndo :: Endo a -> a -> a
- Data.Monoid.Endo.Fold: getFoldable :: WrappedFoldable f a -> f a
- Data.Monoid.Endo.Fold: instance (AnEndo a, AnEndo b, AnEndo c, EndoOperatesOn a ~ EndoOperatesOn b, EndoOperatesOn a ~ EndoOperatesOn c) => AnEndo (a, b, c)
- Data.Monoid.Endo.Fold: instance (AnEndo a, AnEndo b, EndoOperatesOn a ~ EndoOperatesOn b) => AnEndo (a, b)
- Data.Monoid.Endo.Fold: instance (AnEndo a, FoldEndoArgs r, EndoOperatesOn a ~ ResultOperatesOn r) => FoldEndoArgs (a -> r)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, AnEndo a6, AnEndo a7, AnEndo a8, AnEndo a9, AnEndo a10, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5, EndoOperatesOn a1 ~ EndoOperatesOn a6, EndoOperatesOn a1 ~ EndoOperatesOn a7, EndoOperatesOn a1 ~ EndoOperatesOn a8, EndoOperatesOn a1 ~ EndoOperatesOn a9, EndoOperatesOn a1 ~ EndoOperatesOn a10) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, AnEndo a6, AnEndo a7, AnEndo a8, AnEndo a9, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5, EndoOperatesOn a1 ~ EndoOperatesOn a6, EndoOperatesOn a1 ~ EndoOperatesOn a7, EndoOperatesOn a1 ~ EndoOperatesOn a8, EndoOperatesOn a1 ~ EndoOperatesOn a9) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, AnEndo a6, AnEndo a7, AnEndo a8, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5, EndoOperatesOn a1 ~ EndoOperatesOn a6, EndoOperatesOn a1 ~ EndoOperatesOn a7, EndoOperatesOn a1 ~ EndoOperatesOn a8) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, AnEndo a6, AnEndo a7, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5, EndoOperatesOn a1 ~ EndoOperatesOn a6, EndoOperatesOn a1 ~ EndoOperatesOn a7) => AnEndo (a1, a2, a3, a4, a5, a6, a7)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, AnEndo a6, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5, EndoOperatesOn a1 ~ EndoOperatesOn a6) => AnEndo (a1, a2, a3, a4, a5, a6)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, AnEndo a5, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4, EndoOperatesOn a1 ~ EndoOperatesOn a5) => AnEndo (a1, a2, a3, a4, a5)
- Data.Monoid.Endo.Fold: instance (AnEndo a1, AnEndo a2, AnEndo a3, AnEndo a4, EndoOperatesOn a1 ~ EndoOperatesOn a2, EndoOperatesOn a1 ~ EndoOperatesOn a3, EndoOperatesOn a1 ~ EndoOperatesOn a4) => AnEndo (a1, a2, a3, a4)
- Data.Monoid.Endo.Fold: instance (Applicative f, Applicative g, FoldEndoArgs r) => FoldEndoArgs (Compose f g r)
- Data.Monoid.Endo.Fold: instance (Applicative f, Applicative g, FoldEndoArgs r) => FoldEndoArgs (Product f g r)
- Data.Monoid.Endo.Fold: instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (IdentityT f r)
- Data.Monoid.Endo.Fold: instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (ListT f r)
- Data.Monoid.Endo.Fold: instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (ReaderT r' f r)
- Data.Monoid.Endo.Fold: instance (Applicative f, FoldEndoArgs r, Monoid w) => FoldEndoArgs (WriterT w f r)
- Data.Monoid.Endo.Fold: instance (Data (f a), Typeable f, Typeable a) => Data (WrappedFoldable f a)
- Data.Monoid.Endo.Fold: instance (Foldable f, AnEndo a) => AnEndo (Reverse f a)
- Data.Monoid.Endo.Fold: instance (Foldable f, AnEndo a) => AnEndo (WrappedFoldable f a)
- Data.Monoid.Endo.Fold: instance (Monad m, FoldEndoArgs r) => FoldEndoArgs (StateT s m r)
- Data.Monoid.Endo.Fold: instance (Monad m, Functor m, FoldEndoArgs r) => FoldEndoArgs (MaybeT m r)
- Data.Monoid.Endo.Fold: instance (Monad m, Functor m, Monoid w, FoldEndoArgs r) => FoldEndoArgs (RWST r' w s m r)
- Data.Monoid.Endo.Fold: instance (Monoid c, FoldEndoArgs r) => FoldEndoArgs (Const c r)
- Data.Monoid.Endo.Fold: instance AnEndo (Endo a)
- Data.Monoid.Endo.Fold: instance AnEndo (Proxy a)
- Data.Monoid.Endo.Fold: instance AnEndo (a -> a)
- Data.Monoid.Endo.Fold: instance AnEndo a => AnEndo (Maybe a)
- Data.Monoid.Endo.Fold: instance AnEndo a => AnEndo [a]
- Data.Monoid.Endo.Fold: instance Constructor C1_0WrappedFoldable
- Data.Monoid.Endo.Fold: instance Datatype D1WrappedFoldable
- Data.Monoid.Endo.Fold: instance FoldEndoArgs (Endo a)
- Data.Monoid.Endo.Fold: instance FoldEndoArgs r => FoldEndoArgs (Either e r)
- Data.Monoid.Endo.Fold: instance FoldEndoArgs r => FoldEndoArgs (IO r)
- Data.Monoid.Endo.Fold: instance FoldEndoArgs r => FoldEndoArgs (Identity r)
- Data.Monoid.Endo.Fold: instance FoldEndoArgs r => FoldEndoArgs (Maybe r)
- Data.Monoid.Endo.Fold: instance Generic (WrappedFoldable f a)
- Data.Monoid.Endo.Fold: instance Read (f a) => Read (WrappedFoldable f a)
- Data.Monoid.Endo.Fold: instance Selector S1_0_0WrappedFoldable
- Data.Monoid.Endo.Fold: instance Show (f a) => Show (WrappedFoldable f a)
- Data.Monoid.Endo.Fold: instance Typeable WrappedFoldable
+ Data.Monoid.Endo: [appEndo] :: Endo a -> a -> a
+ Data.Monoid.Endo.AnEndo: WrapFoldable :: f a -> WrappedFoldable f a
+ Data.Monoid.Endo.AnEndo: [getFoldable] :: WrappedFoldable f a -> f a
+ Data.Monoid.Endo.AnEndo: aDualEndo :: AnEndo a => a -> Dual (Endo (EndoOperatesOn a))
+ Data.Monoid.Endo.AnEndo: anEndo :: AnEndo a => a -> Endo (EndoOperatesOn a)
+ Data.Monoid.Endo.AnEndo: class AnEndo a where type EndoOperatesOn a anEndo = getDual . aDualEndo aDualEndo = Dual . anEndo where {
+ Data.Monoid.Endo.AnEndo: embedDualEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Dual (Endo a) -> b) -> e -> b
+ Data.Monoid.Endo.AnEndo: embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Endo a -> b) -> e -> b
+ Data.Monoid.Endo.AnEndo: instance (Data.Data.Data (f a), Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f) => Data.Data.Data (Data.Monoid.Endo.AnEndo.WrappedFoldable f a)
+ Data.Monoid.Endo.AnEndo: instance (Data.Foldable.Foldable f, Data.Monoid.Endo.AnEndo.AnEndo a) => Data.Monoid.Endo.AnEndo.AnEndo (Data.Functor.Reverse.Reverse f a)
+ Data.Monoid.Endo.AnEndo: instance (Data.Foldable.Foldable f, Data.Monoid.Endo.AnEndo.AnEndo a) => Data.Monoid.Endo.AnEndo.AnEndo (Data.Monoid.Endo.AnEndo.WrappedFoldable f a)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a, Data.Monoid.Endo.AnEndo.AnEndo b, Data.Monoid.Endo.AnEndo.AnEndo c, Data.Monoid.Endo.AnEndo.EndoOperatesOn a ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn b, Data.Monoid.Endo.AnEndo.EndoOperatesOn a ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn c) => Data.Monoid.Endo.AnEndo.AnEndo (a, b, c)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a, Data.Monoid.Endo.AnEndo.AnEndo b, Data.Monoid.Endo.AnEndo.EndoOperatesOn a ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn b) => Data.Monoid.Endo.AnEndo.AnEndo (a, b)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.AnEndo a6, Data.Monoid.Endo.AnEndo.AnEndo a7, Data.Monoid.Endo.AnEndo.AnEndo a8, Data.Monoid.Endo.AnEndo.AnEndo a9, Data.Monoid.Endo.AnEndo.AnEndo a10, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a6, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a7, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a8, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a9, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a10) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.AnEndo a6, Data.Monoid.Endo.AnEndo.AnEndo a7, Data.Monoid.Endo.AnEndo.AnEndo a8, Data.Monoid.Endo.AnEndo.AnEndo a9, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a6, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a7, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a8, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a9) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.AnEndo a6, Data.Monoid.Endo.AnEndo.AnEndo a7, Data.Monoid.Endo.AnEndo.AnEndo a8, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a6, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a7, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a8) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5, a6, a7, a8)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.AnEndo a6, Data.Monoid.Endo.AnEndo.AnEndo a7, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a6, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a7) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5, a6, a7)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.AnEndo a6, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a6) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5, a6)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.AnEndo a5, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a5) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4, a5)
+ Data.Monoid.Endo.AnEndo: instance (Data.Monoid.Endo.AnEndo.AnEndo a1, Data.Monoid.Endo.AnEndo.AnEndo a2, Data.Monoid.Endo.AnEndo.AnEndo a3, Data.Monoid.Endo.AnEndo.AnEndo a4, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a2, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a3, Data.Monoid.Endo.AnEndo.EndoOperatesOn a1 ~ Data.Monoid.Endo.AnEndo.EndoOperatesOn a4) => Data.Monoid.Endo.AnEndo.AnEndo (a1, a2, a3, a4)
+ Data.Monoid.Endo.AnEndo: instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo (Data.Monoid.Endo a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo (Data.Proxy.Proxy a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo (a -> a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo a => Data.Monoid.Endo.AnEndo.AnEndo (Data.Functor.Identity.Identity a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo a => Data.Monoid.Endo.AnEndo.AnEndo (Data.Semigroup.Option a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo a => Data.Monoid.Endo.AnEndo.AnEndo (GHC.Base.Maybe a)
+ Data.Monoid.Endo.AnEndo: instance Data.Monoid.Endo.AnEndo.AnEndo a => Data.Monoid.Endo.AnEndo.AnEndo [a]
+ Data.Monoid.Endo.AnEndo: instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance GHC.Base.Functor f => GHC.Base.Functor (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance GHC.Base.Monad f => GHC.Base.Monad (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance GHC.Generics.Generic (Data.Monoid.Endo.AnEndo.WrappedFoldable f a)
+ Data.Monoid.Endo.AnEndo: instance GHC.Generics.Generic1 (Data.Monoid.Endo.AnEndo.WrappedFoldable f)
+ Data.Monoid.Endo.AnEndo: instance GHC.Read.Read (f a) => GHC.Read.Read (Data.Monoid.Endo.AnEndo.WrappedFoldable f a)
+ Data.Monoid.Endo.AnEndo: instance GHC.Show.Show (f a) => GHC.Show.Show (Data.Monoid.Endo.AnEndo.WrappedFoldable f a)
+ Data.Monoid.Endo.AnEndo: newtype WrappedFoldable f a
+ Data.Monoid.Endo.AnEndo: type family EndoOperatesOn a;
+ Data.Monoid.Endo.AnEndo: }
+ Data.Monoid.Endo.Apply: ApplyEndo :: f a -> ApplyEndo t f a
+ Data.Monoid.Endo.Apply: [applyEndo] :: ApplyEndo t f a -> f a
+ Data.Monoid.Endo.Apply: apply :: Applicative f => a -> Endo a -> ApplyEndo t f a
+ Data.Monoid.Endo.Apply: applyDef :: (Applicative f, Default a) => ApplyEndo Def f a -> f a
+ Data.Monoid.Endo.Apply: applyDef_ :: Default a => ApplyEndo Def Identity a -> a
+ Data.Monoid.Endo.Apply: applyF :: Functor f => a -> f (Endo a) -> ApplyEndo t f a
+ Data.Monoid.Endo.Apply: applyMempty :: Monoid a => ApplyEndo Mempty f a -> f a
+ Data.Monoid.Endo.Apply: applyMempty_ :: Monoid a => ApplyEndo Mempty Identity a -> a
+ Data.Monoid.Endo.Apply: applyModify :: MonadState s m => ApplyEndo Modify m s -> m s
+ Data.Monoid.Endo.Apply: applyModify' :: MonadState r m => ApplyEndo Modify' m () -> m ()
+ Data.Monoid.Endo.Apply: applyReader :: MonadReader r m => ApplyEndo Reader m r -> m r
+ Data.Monoid.Endo.Apply: applyReaderWith :: MonadReader r m => (m r -> a) -> ApplyEndo Reader m r -> a
+ Data.Monoid.Endo.Apply: data Def
+ Data.Monoid.Endo.Apply: data Mempty
+ Data.Monoid.Endo.Apply: data Modify
+ Data.Monoid.Endo.Apply: data Modify'
+ Data.Monoid.Endo.Apply: data Reader
+ Data.Monoid.Endo.Apply: instance (Data.Data.Data (f a), Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable f) => Data.Data.Data (Data.Monoid.Endo.Apply.ApplyEndo t f a)
+ Data.Monoid.Endo.Apply: instance (GHC.Base.Applicative f, Data.Default.Class.Default a) => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo.Apply.ApplyEndo Data.Monoid.Endo.Apply.Def f a)
+ Data.Monoid.Endo.Apply: instance (GHC.Base.Applicative f, GHC.Base.Monoid a) => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo.Apply.ApplyEndo Data.Monoid.Endo.Apply.Mempty f a)
+ Data.Monoid.Endo.Apply: instance Control.Monad.Reader.Class.MonadReader r m => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo.Apply.ApplyEndo Data.Monoid.Endo.Apply.Reader m r)
+ Data.Monoid.Endo.Apply: instance Control.Monad.State.Class.MonadState s m => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo.Apply.ApplyEndo Data.Monoid.Endo.Apply.Modify m s)
+ Data.Monoid.Endo.Apply: instance Control.Monad.State.Class.MonadState s m => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo.Apply.ApplyEndo Data.Monoid.Endo.Apply.Modify' m s)
+ Data.Monoid.Endo.Apply: instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance GHC.Base.Functor f => GHC.Base.Functor (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance GHC.Base.Monad f => GHC.Base.Monad (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic (Data.Monoid.Endo.Apply.ApplyEndo t f a)
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic Data.Monoid.Endo.Apply.Def
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic Data.Monoid.Endo.Apply.Mempty
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic Data.Monoid.Endo.Apply.Modify
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic Data.Monoid.Endo.Apply.Modify'
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic Data.Monoid.Endo.Apply.Reader
+ Data.Monoid.Endo.Apply: instance GHC.Generics.Generic1 (Data.Monoid.Endo.Apply.ApplyEndo t f)
+ Data.Monoid.Endo.Apply: joinApplyDef :: (Monad m, Default a) => m (ApplyEndo Def m a) -> m a
+ Data.Monoid.Endo.Apply: joinApplyMempty :: (Monad m, Monoid a) => m (ApplyEndo Mempty m a) -> m a
+ Data.Monoid.Endo.Apply: joinApplyModify :: MonadState s m => m (ApplyEndo Modify m s) -> m s
+ Data.Monoid.Endo.Apply: joinApplyModify' :: MonadState r m => m (ApplyEndo Modify' m r) -> m r
+ Data.Monoid.Endo.Apply: joinApplyReader :: MonadReader r m => m (ApplyEndo Reader m r) -> m r
+ Data.Monoid.Endo.Apply: newtype ApplyEndo t f a
+ Data.Monoid.Endo.Fold: [getFoldable] :: WrappedFoldable f a -> f a
+ Data.Monoid.Endo.Fold: infixl 1 <&$>
+ Data.Monoid.Endo.Fold: instance (Data.Monoid.Endo.AnEndo.AnEndo a, Data.Monoid.Endo.Fold.FoldEndoArgs r, Data.Monoid.Endo.AnEndo.EndoOperatesOn a ~ Data.Monoid.Endo.Fold.ResultOperatesOn r) => Data.Monoid.Endo.Fold.FoldEndoArgs (a -> r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Identity.IdentityT f r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.List.ListT f r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Reader.ReaderT r' f r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, Data.Monoid.Endo.Fold.FoldEndoArgs r, GHC.Base.Monoid w) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Writer.Lazy.WriterT w f r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, Data.Monoid.Endo.Fold.FoldEndoArgs r, GHC.Base.Monoid w) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Writer.Strict.WriterT w f r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, GHC.Base.Applicative g, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Functor.Compose.Compose f g r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Applicative f, GHC.Base.Applicative g, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Functor.Product.Product f g r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Except.ExceptT e m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.Maybe.MaybeT m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.State.Lazy.StateT s m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.State.Strict.StateT s m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, GHC.Base.Monoid w, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.RWS.Lazy.RWST r' w s m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monad m, GHC.Base.Monoid w, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Control.Monad.Trans.RWS.Strict.RWST r' w s m r)
+ Data.Monoid.Endo.Fold: instance (GHC.Base.Monoid c, Data.Monoid.Endo.Fold.FoldEndoArgs r) => Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Functor.Const.Const c r)
+ Data.Monoid.Endo.Fold: instance Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Monoid.Endo a)
+ Data.Monoid.Endo.Fold: instance Data.Monoid.Endo.Fold.FoldEndoArgs r => Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Either.Either e r)
+ Data.Monoid.Endo.Fold: instance Data.Monoid.Endo.Fold.FoldEndoArgs r => Data.Monoid.Endo.Fold.FoldEndoArgs (Data.Functor.Identity.Identity r)
+ Data.Monoid.Endo.Fold: instance Data.Monoid.Endo.Fold.FoldEndoArgs r => Data.Monoid.Endo.Fold.FoldEndoArgs (GHC.Base.Maybe r)
+ Data.Monoid.Endo.Fold: instance Data.Monoid.Endo.Fold.FoldEndoArgs r => Data.Monoid.Endo.Fold.FoldEndoArgs (GHC.Types.IO r)
+ Data.Monoid.Endo.Fold: type (:->) args r = (Result args ~ r) => args
+ Data.Monoid.Endo.Fold: type family EndoOperatesOn a;
+ Data.Monoid.Endo.Fold: }
+ Data.Monoid.Endo.FromEndo: class FromEndo a where type EndoOperatedOn a fromDualEndo = fromEndo . getDual where {
+ Data.Monoid.Endo.FromEndo: fromDualEndo :: FromEndo a => Dual (Endo (EndoOperatedOn a)) -> a
+ Data.Monoid.Endo.FromEndo: fromDualEndoTo :: FromEndo a => Dual (Endo (EndoOperatedOn a)) -> proxy a -> a
+ Data.Monoid.Endo.FromEndo: fromDualEndoWith :: (FromEndo a, EndoOperatedOn a ~ c) => (a -> b) -> Dual (Endo c) -> b
+ Data.Monoid.Endo.FromEndo: fromDualEndoWithF :: (Functor f, FromEndo a, EndoOperatedOn a ~ c) => (f a -> b) -> f (Dual (Endo c)) -> b
+ Data.Monoid.Endo.FromEndo: fromEndo :: FromEndo a => Endo (EndoOperatedOn a) -> a
+ Data.Monoid.Endo.FromEndo: fromEndoTo :: FromEndo a => Endo (EndoOperatedOn a) -> proxy a -> a
+ Data.Monoid.Endo.FromEndo: fromEndoWith :: (FromEndo a, EndoOperatedOn a ~ c) => (a -> b) -> Endo c -> b
+ Data.Monoid.Endo.FromEndo: fromEndoWithF :: (Functor f, FromEndo a, EndoOperatedOn a ~ c) => (f a -> b) -> f (Endo c) -> b
+ Data.Monoid.Endo.FromEndo: instance (GHC.Base.Monoid w, GHC.Base.Monad f) => Data.Monoid.Endo.FromEndo.FromEndo (Control.Monad.Trans.RWS.Lazy.RWST r w s f ())
+ Data.Monoid.Endo.FromEndo: instance (GHC.Base.Monoid w, GHC.Base.Monad f) => Data.Monoid.Endo.FromEndo.FromEndo (Control.Monad.Trans.RWS.Strict.RWST r w s f ())
+ Data.Monoid.Endo.FromEndo: instance Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Endo a)
+ Data.Monoid.Endo.FromEndo: instance Data.Monoid.Endo.FromEndo.FromEndo (a -> a)
+ Data.Monoid.Endo.FromEndo: instance Data.Monoid.Endo.FromEndo.FromEndo e => Data.Monoid.Endo.FromEndo.FromEndo (Data.Monoid.Dual e)
+ Data.Monoid.Endo.FromEndo: instance GHC.Base.Monad f => Data.Monoid.Endo.FromEndo.FromEndo (Control.Monad.Trans.Reader.ReaderT r f r)
+ Data.Monoid.Endo.FromEndo: instance GHC.Base.Monad f => Data.Monoid.Endo.FromEndo.FromEndo (Control.Monad.Trans.State.Lazy.StateT s f ())
+ Data.Monoid.Endo.FromEndo: instance GHC.Base.Monad f => Data.Monoid.Endo.FromEndo.FromEndo (Control.Monad.Trans.State.Strict.StateT s f ())
+ Data.Monoid.Endo.FromEndo: type family EndoOperatedOn a;
+ Data.Monoid.Endo.FromEndo: }
- Data.Monoid.Endo.Fold: class AnEndo a where type family EndoOperatesOn a anEndo = getDual . aDualEndo aDualEndo = Dual . anEndo
+ Data.Monoid.Endo.Fold: class AnEndo a where type EndoOperatesOn a anEndo = getDual . aDualEndo aDualEndo = Dual . anEndo where {
- Data.Monoid.Endo.Fold: class FoldEndoArgs a where type family ResultOperatesOn a type family Result a
+ Data.Monoid.Endo.Fold: class FoldEndoArgs a where type ResultOperatesOn a type Result a where {

Files

ChangeLog.md view
@@ -1,6 +1,35 @@ # ChangeLog / ReleaseNotes  +## Version 0.3.0.0++* Introducing type `:->` to simplify type signatures of endomorphism folding+  functions that restrict type of a result. (**new**)+* Type class `AnEndo` moved in to a separate module `Data.Monoid.Endo.AnEndo`.+  Definitions are reexported by `Data.Monoid.Endo.Fold`, therefore providing+  backward compatible API. (**change**)+* Introducing `instance AnEndo a => AnEndo (Identity a)`. (**new**)+* Introducing `FromEndo` type class for conversion of endomorphism in to a+  value. It is a dual to `AnEndo` type class. This type class resides in its+  own module `Data.Monoid.Endo.FromEndo`. (**new**)+* Introducing `ApplyEndo` newtype that provides easier endomorphism evaluation+  in cases when there is an "obvious" default value. This type has its own+  module `Data.Monoid.Endo.Apply` that also provides various helper functions+  and type class instances. (**new**)+* Providing `Eq1`, `Ord1`, `Read1` and `Show1` instances if built with+  [transformers package][transformers] >=0.5 or base >=4.9 (i.e. GHC+  >=8.0.1) is available. (**new**)+* Providing `Generic1` instance for `WrappedFoldable`. (**new**)+* Introducing `instance AnEndo a => AnEndo (Option a)`, but only when compiled+  with base >=4.9, since that is the first version of base which contains+  `Semigroup`. (**new**)+* Bumped upper bound of [transformers package][transformers] to include 0.5.\*+  versions. (**change**)+* Synchronized API documentation of `Data.Monoid.Endo.Fold` with README.+  (**trivial change**)+* Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.3.0.0>++ ## Version 0.2.0.1  * API documentation ehancements and clarifications.@@ -14,13 +43,13 @@ * Default implementation for `anEndo` method of 'AnEndo' type class, which is   now defined as: `anEndo = getDual . aDualEndo`. As a consequence it is now   possible to define complete instances of `AnEndo` by providing either-  `anEndo` or `aDualEndo`. (new, change)+  `anEndo` or `aDualEndo`. (**new**, **change**) * Introducing associated type `Result` to `FoldEndoArgs` type class. This   allows result of the whole folding to be explicitly stated in a type-  signature. (new, change)+  signature. (**new**, **change**) * Introducing functions `embedEndoWith` and `embedDualEndoWith`. Both can be   used to simplify application of endomorphisms that are result of folding.-  (new)+  (**new**)     - `embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Endo a -> b) -> e       -> b`     - `embedDualEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Dual (Endo a)@@ -28,19 +57,19 @@ * Introducing `instance AnEndo (Proxy a)`, which is useful in cases when one   needs to force constraint `EndoOperatesOn args ~ a` where `a` is the `a` from   `Proxy a`. This is done by encoding value of `Proxy` in to identity-  endomorphism that operates on specified type `a`. (new)+  endomorphism that operates on specified type `a`. (**new**) * Introducing `instance (Monoid c, FoldEndoArgs r) => FoldEndoArgs (Const c   r)`, which is useful in cases when one needs to discard the computation and-  return a constant instead. (new)+  return a constant instead. (**new**) * Bumping upper bounds on base and between, therefore it now builds on GHC 7.10-  with base 4.8. (new)+  with base 4.8. (**new**) * Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.2.0.0>   ## Version 0.1.0.2  * Bugfix release.-* Bugfix: Unable to compile with transformers >= 0.4 (again).+* Bugfix: Unable to compile with [transformers][] >= 0.4 (again). * Minor documentation updates. * Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.1.0.2> @@ -48,13 +77,13 @@ ## Version 0.1.0.1  * Bugfix release.-* Bugfix: Unable to compile with transformers >= 0.4.+* Bugfix: Unable to compile with [transformers][] >= 0.4. * Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.1.0.1>   ## Version 0.1.0.0 -* **This version doesn't work with transformers >= 0.4.**+* **This version doesn't work with [transformers][] >= 0.4.** * First public release. * Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.1.0.0> @@ -63,6 +92,9 @@ [Hackage]:   http://hackage.haskell.org/   "HackageDB (or just Hackage) is a collection of releases of Haskell packages."+[transformers]:+  https://hackage.haskell.org/package/transformers+  "Package transformers on Hackage."  <!--   vim: filetype=markdown softtabstop=4 shiftwidth=4 expandtab
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013-2015, Peter Trško+Copyright (c) 2013-2016, Peter Trško  All rights reserved. 
README.md view
@@ -15,6 +15,12 @@  ## Usage Examples +Examples in this section were taken from real live production code, but they+were tamed down a little.+++### Basic Idea+ Lets define simple application `Config` data type as:  ````Haskell@@ -56,14 +62,20 @@ ````  Above example shows us that it is possible to modify `Config` as if it was a-monoid, but without actually having to state it as such. In practice it is-not always possible to define it as `Monoid` or at least a `Semigroup`. What-usually works are endomorphisms, like in this example.+monoid, but without actually having to state it as such. In practice it is not+always possible to define it as `Monoid`, or at least as a `Semigroup`.+Endomorphism are monoids under composition, therefore they are what usually+works in situations when the modified data type can not be instantiated as a+monoid. -Now, `FilePath` has one pathological case, and that is `""`. There is a lot of-ways to handle it. Here we will concentrate only few basic techniques to-illustrate versatility of our approach. +### Working With Corner Cases++In real applications corner cases arise quite easily, e.g. `FilePath` has one+pathological case, and that is `""`. There is a lot of ways to handle it. Here+we will concentrate only few basic techniques to illustrate versatility of our+approach.+ ````Haskell -- | Trying to set output file to \"\" will result in keeping original value. setOutputFile2 :: FilePath -> E Config@@ -88,7 +100,15 @@     &$ setVerbosity Annoying     &$ setOutputFile3 "an.out.put" ````+Great thing about `Maybe` is the fact that it has `Alternative` and `MonadPlus`+instances. Using `guard` may simplify `setOutputFile3` in to definition like+following: +````Haskell+setOutputFile3':: FilePath -> Maybe (E Config)+setOutputFile3' fp = setOutputFile fp <$ guard (not (null fp))+````+ Following example uses common pattern of using `Either` as error reporting monad. This approach can be easily modified for arbitrary error reporting monad.@@ -109,9 +129,12 @@ constructor arguments and order of operations. Using `foldEndo` (and its dual `dualFoldEndo`) doesn't have this restriction. -Instead of setter functions one may want to use lenses (in terms of-[lens package][Hackage: lens]):+### Lenses +Instead of setter functions one may want to use lenses. In this example we use+types from [lens package][Hackage: lens], but definitions use function from+[between package][Hackage: between]:+ ````Haskell verbosity :: Lens' Config Verbosity verbosity = _verbosity ~@@^> \s b -> s{_verbosity = b}@@ -129,6 +152,8 @@     &$ outputFile .~ "an.out.put" ```` +### Other Usage+ Probably one of the most interesting things that can be done with this module is following: @@ -248,6 +273,12 @@   Pass additional warning flags to GHC.  +License+-------++The BSD 3-Clause License, see [LICENSE][] file for details.++ ## Contributions  Contributions, pull requests and bug reports are welcome! Please don't be@@ -255,6 +286,9 @@   +[Hackage: between]:+  http://hackage.haskell.org/package/between+  "between package on Hackage" [Hackage: endo]:   http://hackage.haskell.org/package/endo   "endo package on Hackage"@@ -267,6 +301,9 @@ [Haskell.org]:   http://www.haskell.org   "The Haskell Programming Language"+[LICENSE]:+  https://github.com/trskop/endo/blob/master/LICENSE+  "License of endo package." [tl;dr Legal: BSD3]:   https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29   "BSD 3-Clause License (Revised)"
endo.cabal view
@@ -1,5 +1,5 @@ name:                   endo-version:                0.2.0.1+version:                0.3.0.0 synopsis:               Endomorphism utilities. description:   Package defines extra functions for 'Data.Monoid.Endo' data type, and also@@ -46,11 +46,14 @@ license-file:           LICENSE author:                 Peter Trško maintainer:             peter.trsko@gmail.com-copyright:              (c) 2013-2015, Peter Trško+copyright:              (c) 2013-2016, Peter Trško category:               Data build-type:             Simple cabal-version:          >=1.10 +-- See https://github.com/trskop/endo/blob/master/.travis.yml for more details.+tested-with:            GHC ==7.6.3, GHC ==7.8.4, GHC ==7.10.3, GHC ==8.0.1+ -- Examples require lens and optparse-applicative packages in addition to this -- packackage's dependencies. When using sandbox it is possible to use "cabal -- repl" to test examples by using following command:@@ -76,7 +79,10 @@   hs-source-dirs:       src   exposed-modules:       Data.Monoid.Endo+    , Data.Monoid.Endo.AnEndo+    , Data.Monoid.Endo.Apply     , Data.Monoid.Endo.Fold+    , Data.Monoid.Endo.FromEndo    default-language:     Haskell2010   other-extensions:@@ -88,18 +94,47 @@    build-depends:     -- {{{ Distributed with GHC or Haskell Platform ----------------------------      base >=4.6 && <4.9-    , transformers >=0.3 && <0.5+      base >=4.6 && <5+    , transformers >=0.3 && <0.6+    , mtl >=2.1 && <3+    -- ^ Version 2.1 is the first that supported transformers ==0.3, which is+    -- the lowest supported version by this package.+     -- }}} Distributed with GHC or Haskell Platform --------------------------- -    , between >=0.9 && <0.11+    , between >=0.9 && <1+    , data-default-class ==0.0.* -  if impl(GHC >= 7.8)-    cpp-options:        -DHAVE_MINIMAL_PRAGMA-                        -DKIND_POLYMORPHIC_TYPEABLE-  if impl(GHC >= 7.9)-    cpp-options:        -DAPPLICATIVE_MONAD+  if impl(GHC >=7.8)+    cpp-options:+      -DHAVE_KIND_POLYMORPHIC_TYPEABLE+      -DHAVE_MINIMAL_PRAGMA +      -- Module Data.Proxy, that defines Proxy data type, was+      -- introduced in base ==4.7.0.0, i.e. GHC 7.8.1.+      -DHAVE_PROXY++  if impl(GHC >=7.10)+    cpp-options:+      -- Applicative became supper class of Monad in base ==4.8 which was+      -- bundled with GHC 7.10.1 release.+      -DHAVE_APPLICATIVE_MONAD++  if impl(GHC >=8.0)+    cpp-options:+      -- Definition of Const moved in to its own module Data.Functor.Const in+      -- base 4.9.0.0, i.e. GHC 8.0.1.+      -DHAVE_FUNCTOR_CONST_MODULE++      -- Module Data.Functor.Classes has moved from transformers in to base+      -- 4.9.0.0, but the definitions in that module are compatible+      -- only with transformers >=0.5.+      -DHAVE_FUNCTOR_CLASSES++      -- Package base ==4.9.0.0 introduces Data.Semigroup, which was originally+      -- defined in semigroups package.+      -DHAVE_SEMIGROUPS+   ghc-options:          -Wall   if flag(pedantic)     ghc-options:@@ -114,4 +149,4 @@ source-repository this   type:                 git   location:             git://github.com/trskop/endo.git-  tag:                  0.2.0.1+  tag:                  0.3.0.0
+ example/Example8.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleInstances #-}++module Main where++import Data.Functor.Identity++import Data.Monoid.Endo+import Data.Monoid.Endo.AnEndo++import Data.Default.Class (Default(def))+++data Verbosity+    = Silent+    | Normal+    | Verbose+    | Annoying+  deriving (Show {- ... -})++instance Default Verbosity where+    def = Normal++class HasVerbosity s where+    verbosity :: Functor f => (Verbosity -> f Verbosity) -> s -> f s++setVerbosity :: HasVerbosity s => Verbosity -> s -> s+setVerbosity v = runIdentity . verbosity (const (Identity v))++data Config = Config+    { cfgVerbosity :: Verbosity+    -- ...+    }+  deriving (Show)++instance HasVerbosity Config where+    verbosity f cfg@Config{cfgVerbosity = v} =+        (\v' -> cfg{cfgVerbosity = v'}) <$> f v++data Action = NormalAction Config | ShowVersion | ShowHelp+  deriving (Show {- ... -})++instance Default Config where+    def = Config+        { cfgVerbosity = def+        -- ...+        }++instance Default Action where+    def = NormalAction def++instance AnEndo Verbosity where+    type EndoOperatesOn Verbosity = Action++    anEndo v = Endo $ \case+        NormalAction cfg -> NormalAction $ setVerbosity v cfg+        action           -> action
+ example/Example9.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleInstances #-}++module Main where++import Data.Functor.Identity++import Data.Text (Text)++import Data.Monoid.Endo+import Data.Monoid.Endo.AnEndo++import Data.Default.Class (Default(def))+++data User f g = User+    { _login :: Text+    , _name :: f Text+    , _displayName :: f Text+    , _password :: g Text+    }++type CreateUser = User Maybe Identity+type ShowUser = User Maybe Proxy+type AuthenticateUser = User Proxy Identity
+ src/Data/Monoid/Endo/AnEndo.hs view
@@ -0,0 +1,616 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeFamilies #-}++#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+{-# LANGUAGE DeriveDataTypeable #-}+#endif++#if !MIN_VERSION_base(4,9,0) && MIN_VERSION_transformers(0,5,0)+-- Definitions in Data.Functor.Classes from transformers >=0.5 are compatible+-- with those in base >=4.9, therefore we can enable them.+#define HAVE_FUNCTOR_CLASSES+#endif++-- |+-- Module:       $HEADER$+-- Description:  Conversion of values in to endomorphisms.+-- Copyright:    (c) 2014-2016, Peter Trško+-- License:      BSD3+--+-- Maintainer:   peter.trsko@gmail.com+-- Stability:    experimental+-- Portability:  CPP, DeriveDataTypeable, DeriveGeneric, FlexibleInstances,+--               NoImplicitPrelude, TypeFamilies+--+-- Conversion of values in to endomorphisms.+module Data.Monoid.Endo.AnEndo+    (+    -- * Conversion Into Endo+    --+    -- | Various types can be interpreted as an encoding of an endomorphism. In+    -- example, enum can be viewed as family of endomorphisms where each sets a+    -- specific field of a record to a specific enum value, i.e. data+    -- constructor. Type class 'AnEndo' provides generic way to convert values+    -- in to an endomorphism using 'anEndo' and 'aDualEndo' functions.+      AnEndo(..)++    -- ** WrappedFoldable+    --+    -- $wrappedFoldable+    , WrappedFoldable(..)++    -- * Utility Functions and Types+    , embedEndoWith+    , embedDualEndoWith+    )+  where++import Control.Applicative (Applicative)+import Control.Monad (Monad)+import Data.Foldable (Foldable(foldMap))+import Data.Function (($), (.), id)+import Data.Functor (Functor)+#ifdef HAVE_FUNCTOR_CLASSES+import Data.Functor.Classes+    ( Eq1+    , Ord1+    , Read1(liftReadsPrec)+    , Show1(liftShowsPrec)+    , readsData+    , readsUnaryWith+    , showsUnaryWith+    )+#endif+import Data.Functor.Identity (Identity(Identity))+import Data.Maybe (Maybe(Just, Nothing))+import Data.Monoid+    ( Dual(Dual, getDual)+    , Endo(Endo)+    , Monoid(mempty, mconcat)+    , (<>)+    )+#ifdef HAVE_SEMIGROUPS+import Data.Semigroup (Option(Option))+#endif+import Data.Traversable (Traversable)+import GHC.Generics (Generic, Generic1)+import Text.Read (Read)+import Text.Show (Show)++#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+import Data.Data (Data, Typeable)+#endif++#ifdef HAVE_PROXY+import Data.Proxy (Proxy(Proxy))+#endif++import Data.Functor.Reverse (Reverse)+++-- {{{ AnEndo Type Class ------------------------------------------------------++-- | Class that represents various endomorphism representation. In other words+-- anything that encodes @(a -> a)@ can be instance of this class.+--+-- Here are some important instances with not so obvious definitions.+--+-- @+-- instance 'AnEndo' ('Proxy' a) where+--     type 'EndoOperatesOn' ('Proxy' a) = a+--+--     'anEndo'    _ = 'mempty' -- = Endo 'id'+--     'aDualEndo' _ = 'mempty'+-- @+--+-- It got quite common to use 'Proxy' data type as an explicit way to pass+-- types around. Above instance allows you to restrict type of result of+-- endomorphism folding, to some extent.+--+-- @+-- instance 'AnEndo' a => 'AnEndo' ('Maybe' a) where+--     type 'EndoOperatesOn' ('Maybe' a) = 'EndoOperatesOn' a+--+--     'anEndo' 'Nothing'  = 'mempty' -- = Endo 'id'+--     'anEndo' ('Just' e) = 'anEndo' e+--+--     -- Definition of 'aDualEndo' is analogous.+-- @+--+-- Instance for @Maybe@ lets us conditionally inject endomorphism in to a+-- folding chain.+--+-- @+-- instance 'AnEndo' a => 'AnEndo' ('Identity' a) where+--     type 'EndoOperatesOn' ('Identity' a) = 'EndoOperatesOn' a+--+--     'anEndo' ('Identity' e) = 'anEndo' e+--     'aDualEndo' ('Identity' e) = 'aDualEndo' e+-- @+--+-- Above instance allows us to discard 'Identity' wrapper, which is commonly+-- used in data types that are parametrized by functor or monad.+class AnEndo a where+    -- | Extract type on which endomorphism operates, e.g. for+    -- @('Endo' a)@ it would be @a@.+    type EndoOperatesOn a++    -- | Convert value encoding @(a -> a)@ in to 'Endo'. Default+    -- implementation:+    --+    -- @+    -- 'anEndo' = 'getDual' . 'aDualEndo'+    -- @+    anEndo :: a -> Endo (EndoOperatesOn a)+    anEndo = getDual . aDualEndo++    -- | Dual to 'anEndo'. Default implementation:+    --+    -- @+    -- 'aDualEndo' = 'Dual' . 'anEndo'+    -- @+    aDualEndo :: a -> Dual (Endo (EndoOperatesOn a))+    aDualEndo = Dual . anEndo++#if HAVE_MINIMAL_PRAGMA+    {-# MINIMAL anEndo | aDualEndo #-}+#endif++instance AnEndo (Endo a) where+    type EndoOperatesOn (Endo a) = a+    anEndo = id++instance AnEndo (a -> a) where+    type EndoOperatesOn (a -> a) = a+    anEndo = Endo++instance AnEndo a => AnEndo (Identity a) where+    type EndoOperatesOn (Identity a) = EndoOperatesOn a++    anEndo (Identity e) = anEndo e+    aDualEndo (Identity e) = aDualEndo e++instance AnEndo a => AnEndo (Maybe a) where+    type EndoOperatesOn (Maybe a) = EndoOperatesOn a++    anEndo Nothing  = mempty+    anEndo (Just e) = anEndo e++    aDualEndo Nothing  = mempty+    aDualEndo (Just e) = aDualEndo e++#ifdef HAVE_PROXY+-- | Constructs identity endomorphism for specified phantom type.+instance AnEndo (Proxy a) where+    type EndoOperatesOn (Proxy a) = a++    anEndo    Proxy = mempty+    aDualEndo Proxy = mempty+#endif++#ifdef HAVE_SEMIGROUPS+-- | Has same semantics as 'Maybe' and it is actually defined in terms of+-- 'AnEndo' instance for 'Maybe'.+instance AnEndo a => AnEndo (Option a) where+    type EndoOperatesOn (Option a) = EndoOperatesOn a++    anEndo (Option maybe) = anEndo maybe+    aDualEndo (Option maybe) = aDualEndo maybe+#endif++-- {{{ Foldable Instances -----------------------------------------------------++-- | Wrapper for 'Foldable' types. Used to provide instances that work for all+-- 'Foldable' types without the need for @OverlappingInstances@ language+-- extension.+newtype WrappedFoldable f a = WrapFoldable {getFoldable :: f a}+  deriving+    ( Applicative+    , Foldable+    , Functor+    , Generic+    , Generic1+    , Monad+    , Read+    , Show+    , Traversable+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Data+    , Typeable+#endif+#ifdef HAVE_FUNCTOR_CLASSES+    , Eq1+    , Ord1+#endif+    )++#ifdef HAVE_FUNCTOR_CLASSES+instance Read1 f => Read1 (WrappedFoldable f) where+    liftReadsPrec rp rl = readsData+        $ readsUnaryWith (liftReadsPrec rp rl) "WrapFoldable" WrapFoldable++instance Show1 f => Show1 (WrappedFoldable f) where+    liftShowsPrec sp sl d (WrapFoldable x) =+        showsUnaryWith (liftShowsPrec sp sl) "WrapFoldable" d x+#endif+    -- HAVE_FUNCTOR_CLASSES++instance (Foldable f, AnEndo a) => AnEndo (WrappedFoldable f a) where+    type EndoOperatesOn (WrappedFoldable f a) = EndoOperatesOn a+    anEndo    (WrapFoldable fa) = foldMap anEndo    fa+    aDualEndo (WrapFoldable fa) = foldMap aDualEndo fa++instance AnEndo a => AnEndo [a] where+    type EndoOperatesOn [a] = EndoOperatesOn a+    anEndo    = anEndo    . WrapFoldable+    aDualEndo = aDualEndo . WrapFoldable++-- {{{ Transformers -----------------------------------------------------------++-- | Fold in reverese order.+instance (Foldable f, AnEndo a) => AnEndo (Reverse f a) where+    type EndoOperatesOn (Reverse f a) = EndoOperatesOn a+    anEndo    = anEndo    . WrapFoldable+    aDualEndo = aDualEndo . WrapFoldable++-- }}} Transformers -----------------------------------------------------------++-- }}} Foldable Instances -----------------------------------------------------++-- {{{ Instances For Tuples ---------------------------------------------------++instance+    ( AnEndo a+    , AnEndo b+    , EndoOperatesOn a ~ EndoOperatesOn b+    ) => AnEndo (a, b)+  where+    type EndoOperatesOn (a, b) = EndoOperatesOn a+    anEndo    (a, b) = anEndo    a <> anEndo    b+    aDualEndo (a, b) = aDualEndo a <> aDualEndo b++instance+    ( AnEndo a+    , AnEndo b+    , AnEndo c+    , EndoOperatesOn a ~ EndoOperatesOn b+    , EndoOperatesOn a ~ EndoOperatesOn c+    ) => AnEndo (a, b, c)+  where+    type EndoOperatesOn (a, b, c) = EndoOperatesOn a+    anEndo    (a, b, c) = anEndo    a <> anEndo    b <> anEndo    c+    aDualEndo (a, b, c) = aDualEndo a <> aDualEndo b <> aDualEndo c++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    ) => AnEndo (a1, a2, a3, a4)+  where+    type EndoOperatesOn (a1, a2, a3, a4) = EndoOperatesOn a1+    anEndo (a1, a2, a3, a4) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        ]++    aDualEndo (a1, a2, a3, a4) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    ) => AnEndo (a1, a2, a3, a4, a5)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        ]++    aDualEndo (a1, a2, a3, a4, a5) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , AnEndo a6+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a6+    ) => AnEndo (a1, a2, a3, a4, a5, a6)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5, a6) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5, a6) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        , anEndo a6+        ]++    aDualEndo (a1, a2, a3, a4, a5, a6) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        , aDualEndo a6+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , AnEndo a6+    , AnEndo a7+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a6+    , EndoOperatesOn a1 ~ EndoOperatesOn a7+    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5, a6, a7) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        , anEndo a6+        , anEndo a7+        ]++    aDualEndo (a1, a2, a3, a4, a5, a6, a7) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        , aDualEndo a6+        , aDualEndo a7+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , AnEndo a6+    , AnEndo a7+    , AnEndo a8+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a6+    , EndoOperatesOn a1 ~ EndoOperatesOn a7+    , EndoOperatesOn a1 ~ EndoOperatesOn a8+    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5, a6, a7, a8) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        , anEndo a6+        , anEndo a7+        , anEndo a8+        ]++    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        , aDualEndo a6+        , aDualEndo a7+        , aDualEndo a8+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , AnEndo a6+    , AnEndo a7+    , AnEndo a8+    , AnEndo a9+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a6+    , EndoOperatesOn a1 ~ EndoOperatesOn a7+    , EndoOperatesOn a1 ~ EndoOperatesOn a8+    , EndoOperatesOn a1 ~ EndoOperatesOn a9+    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8, a9) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        , anEndo a6+        , anEndo a7+        , anEndo a8+        , anEndo a9+        ]++    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        , aDualEndo a6+        , aDualEndo a7+        , aDualEndo a8+        , aDualEndo a9+        ]++instance+    ( AnEndo a1+    , AnEndo a2+    , AnEndo a3+    , AnEndo a4+    , AnEndo a5+    , AnEndo a6+    , AnEndo a7+    , AnEndo a8+    , AnEndo a9+    , AnEndo a10+    , EndoOperatesOn a1 ~ EndoOperatesOn a2+    , EndoOperatesOn a1 ~ EndoOperatesOn a3+    , EndoOperatesOn a1 ~ EndoOperatesOn a4+    , EndoOperatesOn a1 ~ EndoOperatesOn a5+    , EndoOperatesOn a1 ~ EndoOperatesOn a6+    , EndoOperatesOn a1 ~ EndoOperatesOn a7+    , EndoOperatesOn a1 ~ EndoOperatesOn a8+    , EndoOperatesOn a1 ~ EndoOperatesOn a9+    , EndoOperatesOn a1 ~ EndoOperatesOn a10+    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)+  where+    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = EndoOperatesOn a1++    anEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = mconcat+        [ anEndo a1+        , anEndo a2+        , anEndo a3+        , anEndo a4+        , anEndo a5+        , anEndo a6+        , anEndo a7+        , anEndo a8+        , anEndo a9+        , anEndo a10+        ]++    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = mconcat+        [ aDualEndo a1+        , aDualEndo a2+        , aDualEndo a3+        , aDualEndo a4+        , aDualEndo a5+        , aDualEndo a6+        , aDualEndo a7+        , aDualEndo a8+        , aDualEndo a9+        , aDualEndo a10+        ]++-- }}} Instances For Tuples ---------------------------------------------------+-- }}} AnEndo Type Class ------------------------------------------------------++-- {{{ Utility Functions and Types --------------------------------------------++-- | Use 'Endo' (possibly result of 'Data.Endo.Fold.foldEndo') and use it to+-- create value of different type.+--+-- Examples:+--+-- @+-- 'embedEndoWith' 'Control.Monad.Trans.Writer.Lazy.tell'+--     :: (Monad m, 'AnEndo' e, w ~ 'EndoOperatesOn' e)+--     => e+--     -> 'Control.Monad.Trans.Writer.Lazy.WriterT' ('Endo' w) m ()+--+-- 'embedEndoWith' ('Control.Monad.Trans.State.Lazy.modify' . 'Data.Monoid.appEndo')+--     :: (Monad m, 'AnEndo' e, s ~ 'EndoOperatesOn' e)+--     => e+--     -> 'Control.Monad.Trans.State.Lazy.StateT' s m ()+-- @+--+-- See also 'embedDualEndoWith'.+embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a)+    => (Endo a -> b)+    -- ^ Embedding function.+    -> e -> b+embedEndoWith = (. anEndo)++-- | Dual to 'embedEndoWith', which uses 'aDualEndo' instead of 'anEndo'.+embedDualEndoWith+    :: (AnEndo e, EndoOperatesOn e ~ a)+    => (Dual (Endo a) -> b)+    -- ^ Embedding function.+    -> e -> b+embedDualEndoWith = (. aDualEndo)++-- }}} Utility Functions and Types --------------------------------------------++-- $wrappedFoldable+--+-- Newtype 'WrappedFoldable' allows us to use 'anEndo', 'aDualEndo',+-- 'Data.Endo.Fold.foldEndo', and 'Data.Endo.Fold.dualFoldEndo' for any+-- 'Foldable' instance without the need to create specific instance for that+-- specific 'Foldable' type and reduces. It would be possible to create+-- 'AnEndo' instance for all 'Foldable' types, but that would require+-- @OverlappingInstances@ language extension.+--+-- Usage examples:+--+-- @+-- \\vectorOfEndos -> 'anEndo' ('WrappedFoldable' vectorOfEndos)+--     :: Vector ('Data.Monoid.Endo.E' a) -> 'Endo' a+-- @+--+-- @+-- \\vectorOfEndos -> 'Data.Monoid.Endo.Fold.foldEndo' ('WrappedFoldable' vectorOfEndos)+--     :: 'Data.Monoid.Endo.Fold.FoldEndoArgs' => Vector ('Data.Monoid.Endo.E' a) -> args+-- @+--+-- Note that the @Vector@ is just one of possible 'Foldable' data types that+-- may be used here. Also, @('Data.Monoid.Endo.E' a)@ is just an example of+-- endomorphism representation, any 'AnEndo' instance can be used.
+ src/Data/Monoid/Endo/Apply.hs view
@@ -0,0 +1,425 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}  -- GeneralizedNewtypeDeriving failed.+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeFamilies #-}++#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+{-# LANGUAGE DeriveDataTypeable #-}+#endif++#if MIN_VERSION_transformers(0,5,0) || MIN_VERSION_base(4,9,0)+#define HAVE_FUNCTOR_CLASSES+#endif++-- |+-- Module:       $HEADER$+-- Description:  ApplyEndo provides easier endomorphism evaluation in cases+--               when there is an "obvious" default value.+-- Copyright:    (c) 2015-2016, Peter Trško+-- License:      BSD3+--+-- Maintainer:   peter.trsko@gmail.com+-- Stability:    experimental+-- Portability:  CPP, DeriveFoldable, DeriveFunctor, DeriveDataTypeable,+--               DeriveGeneric, DeriveTraversable, FlexibleInstances,+--               NoImplicitPrelude, TypeFamilies+--+-- 'ApplyEndo' provides easier endomorphism evaluation in cases when there is an+-- \"obvious\" default value.+module Data.Monoid.Endo.Apply+    (+    -- * ApplyEndo+      ApplyEndo(..)+    , apply+    , applyF++    -- ** ApplyEndo Mempty+    , Mempty+    , applyMempty+    , applyMempty_+    , joinApplyMempty++    -- ** ApplyEndo Def+    --+    -- $applyEndoDef+    , Def+    , applyDef+    , applyDef_+    , joinApplyDef++    -- ** ApplyEndo Reader+    , Reader+    , applyReader+    , applyReaderWith+    , joinApplyReader++    -- ** ApplyEndo Modify+    , Modify+    , applyModify+    , joinApplyModify++    -- ** ApplyEndo Modify'+    , Modify'+    , applyModify'+    , joinApplyModify'++    )+  where++import Prelude (seq)++import Control.Applicative (Applicative(pure))+import Control.Monad+    ( Monad((>>=))+#ifdef HAVE_APPLICATIVE_MONAD+    , void+#else+    , liftM+#endif+    )+import Data.Foldable (Foldable)+import Data.Function+    ( (.)+    , ($)+#ifndef HAVE_APPLICATIVE_MONAD+    , const+#endif+    )+import Data.Functor (Functor, (<$>))+#ifdef HAVE_FUNCTOR_CLASSES+import Data.Functor.Classes+    ( Eq1+    , Ord1+    , Read1(liftReadsPrec)+    , Show1(liftShowsPrec)+    , readsData+    , readsUnaryWith+    , showsUnaryWith+    )+#endif+import Data.Functor.Identity (Identity(runIdentity))+import Data.Monoid (Endo(Endo, appEndo), Monoid(mempty))+import Data.Traversable (Traversable)+import GHC.Generics (Generic, Generic1)++#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+import Data.Data (Data, Typeable)+#endif++import Control.Monad.Reader.Class (MonadReader)+import qualified Control.Monad.Reader.Class as MonadReader (asks)+import Control.Monad.State.Class (MonadState)+import qualified Control.Monad.State.Class as MonadState (state)++import Data.Default.Class (Default(def))++import Data.Monoid.Endo.FromEndo (FromEndo(..))+++-- | There are cases when it is \"obvious\" what is the default value, which+-- should be modified by the endomorphism. This type is a result of such+-- endomorphism application and it uses phantom type @t@ as distinguishing+-- property, which decides what is the correct \"default value\".+newtype ApplyEndo t f a = ApplyEndo {applyEndo :: f a}+  deriving+    ( Applicative+    , Foldable+    , Functor+    , Generic+    , Generic1+    , Monad+    , Traversable+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Data+    , Typeable+#endif+#ifdef HAVE_FUNCTOR_CLASSES+    , Eq1+    , Ord1+#endif+    )++#ifdef HAVE_FUNCTOR_CLASSES+instance Read1 f => Read1 (ApplyEndo t f) where+    liftReadsPrec rp rl =+        readsData $ readsUnaryWith (liftReadsPrec rp rl) "ApplyEndo" ApplyEndo++instance Show1 f => Show1 (ApplyEndo t f) where+    liftShowsPrec sp sl d (ApplyEndo x) =+        showsUnaryWith (liftShowsPrec sp sl) "ApplyEndo" d x+#endif+    -- HAVE_FUNCTOR_CLASSES++-- | Apply endomorphism using provided \"default\" value.+apply :: Applicative f => a -> Endo a -> ApplyEndo t f a+apply defaultValue (Endo f) = ApplyEndo . pure $ f defaultValue+{-# INLINE apply #-}++-- | Similar as 'apply', but expects 'Endo' to be wrapped by a 'Functor'.+applyF :: Functor f => a -> f (Endo a) -> ApplyEndo t f a+applyF defaultValue endo = ApplyEndo $ (`appEndo` defaultValue) <$> endo++-- {{{ ApplyEndo Mempty -------------------------------------------------------++-- | Type tag identifying usage of 'mempty' from 'Monoid'.+data Mempty+  deriving+    ( Generic+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Typeable+#endif+    )++instance (Applicative f, Monoid a) => FromEndo (ApplyEndo Mempty f a) where+    type EndoOperatedOn (ApplyEndo Mempty f a) = a++    fromEndo = apply mempty++-- | Constrained version of 'applyEndo'. Usage example:+--+-- @+-- applyMempty . fromEndo :: ('Applicative' f, 'Monoid' a) => 'Endo' a -> f a+-- @+applyMempty :: Monoid a => ApplyEndo Mempty f a -> f a+applyMempty = applyEndo+{-# INLINE applyMempty #-}++-- | Same as 'applyMempty', but 'Applicative' functor is specialized to+-- 'Identity' functor and evaluated.+--+-- Examples:+--+-- >>> fromEndoWith applyMempty_ $ foldEndo (+1) [(*10), (+42)] :: Int+-- 421+-- >>> fromEndoWith applyMempty_ $ dualFoldEndo (+1) [(*10), (+42)] :: Int+-- 52+applyMempty_ :: Monoid a => ApplyEndo Mempty Identity a -> a+applyMempty_ = runIdentity . applyMempty+{-# INLINE applyMempty_ #-}++-- | Evaluates 'ApplyEndo' in a 'Monad' by joining it with the monad it+-- contains. It can be also viewed as a variant of 'applyMempty' defined as:+--+-- @+-- 'joinApplyMempty' = ('>>=' 'applyMempty')+-- @+joinApplyMempty+    ::  ( Monad m+        , Monoid a+#ifndef HAVE_APPLICATIVE_MONAD+        , Applicative m+#endif+        )+    => m (ApplyEndo Mempty m a) -> m a+joinApplyMempty = (>>= applyMempty)+{-# INLINE joinApplyMempty #-}++-- }}} ApplyEndo Mempty -------------------------------------------------------++-- {{{ ApplyEndo Def ----------------------------------------------------------++-- $applyEndoDef+--+-- Apply endomorphism to a default value 'def' from 'Default'. See also+-- following packages:+--+-- * <https://hackage.haskell.org/package/data-default-extra data-default-extra>+--+-- * <https://hackage.haskell.org/package/data-default data-default>+--+-- Both of those packages provide additional instances to 'Default' type+-- class.++-- | Type tag identifying usage of 'def' from 'Default'.+data Def+  deriving+    ( Generic+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Typeable+#endif+    )++instance (Applicative f, Default a) => FromEndo (ApplyEndo Def f a) where+    type EndoOperatedOn (ApplyEndo Def f a) = a++    fromEndo = apply def++-- | Constrained version of 'applyEndo'. Usage example:+--+-- @+-- applyDef . fromEndo :: ('Applicative' f, 'Default' a) => 'Endo' a -> f a+-- @+applyDef :: (Applicative f, Default a) => ApplyEndo Def f a -> f a+applyDef = applyEndo+{-# INLINE applyDef #-}++-- | Same as 'applyDef', but 'Applicative' functor is specialized to 'Identity'+-- functor and evaluated.+--+-- Examples:+--+-- >>> fromEndoWith applyDef_ $ foldEndo (+1) [(*10), (+42)] :: Int+-- 421+-- >>> fromEndoWith applyDef_ $ dualFoldEndo (+1) [(*10), (+42)] :: Int+-- 52+applyDef_ :: Default a => ApplyEndo Def Identity a -> a+applyDef_ = runIdentity . applyDef+{-# INLINE applyDef_ #-}++-- | Evaluates 'ApplyEndo' in a 'Monad' by joining it with the monad it+-- contains. It can be also viewed as a variant of 'applyDef' defined as:+--+-- @+-- 'joinApplyDef' = ('>>=' 'applyDef')+-- @+joinApplyDef+    ::  ( Monad m+        , Default a+#ifndef HAVE_APPLICATIVE_MONAD+        , Applicative m+#endif+        )+    => m (ApplyEndo Def m a) -> m a+joinApplyDef = (>>= applyDef)+{-# INLINE joinApplyDef #-}++-- }}} ApplyEndo Def ----------------------------------------------------------++-- {{{ ApplyEndo Reader -------------------------------------------------------++-- | Type tag identifying usage of 'MonadReader.asks' operation in 'FromEndo'+-- instance of 'ApplyEndo'.+data Reader+  deriving+    ( Generic+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Typeable+#endif+    )++-- | Evaluates 'ApplyEndo' in terms of 'MonadReader.asks' operation:+--+-- @+-- 'fromEndo' = 'ApplyEndo' . 'MonadReader.asks' . 'appEndo'+-- @+instance MonadReader r m => FromEndo (ApplyEndo Reader m r) where+    type EndoOperatedOn (ApplyEndo Reader m r) = r++    fromEndo = ApplyEndo . MonadReader.asks . appEndo++-- | Evaluates 'ApplyEndo' in terms of 'MonadReader.asks' operation.+--+-- This @(->) r@ is a valid 'MonadReader' instance, therefore, this is a valid+-- use case:+--+-- >>> (applyReader . fromEndo $ foldEndo (*10) (+1)) 0 :: Int+-- 10+applyReader :: MonadReader r m => ApplyEndo Reader m r -> m r+applyReader = applyEndo++-- | Evaluates 'ApplyEndo' in terms of 'MonadReader.asks' operation and then+-- evaluates the resalt using provided function.+--+-- This @(->) r@ is a valid 'MonadReader' instance, therefore, this is a valid+-- use case:+--+-- >>> applyReaderWith ($ 0) . fromEndo $ foldEndo (*10) (+1) :: Int+-- 10+applyReaderWith :: MonadReader r m => (m r -> a) -> ApplyEndo Reader m r -> a+applyReaderWith = (. applyEndo)++-- | Evaluates 'ApplyEndo' in a 'Monad' by joining it with the monad it+-- contains. It can be also viewed as a variant of 'applyReader' defined as:+--+-- @+-- 'joinApplyReader' = ('>>=' 'applyReader')+-- @+joinApplyReader :: MonadReader r m => m (ApplyEndo Reader m r) -> m r+joinApplyReader = (>>= applyEndo)++-- }}} ApplyEndo Reader -------------------------------------------------------++-- {{{ ApplyEndo Modify -------------------------------------------------------++-- | Type tag identifying usage of 'MonadState.state' operation in 'FromEndo'+-- instance of 'ApplyEndo'.+data Modify+  deriving+    ( Generic+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Typeable+#endif+    )++-- | Evaluates 'ApplyEndo' in terms of 'MonadState.state' operation:+--+-- @+-- 'fromEndo' e = 'ApplyEndo' . 'MonadState.state' '$' \\s ->+--     let s' = 'appEndo' e s in (s', s')+-- @+instance MonadState s m => FromEndo (ApplyEndo Modify m s) where+    type EndoOperatedOn (ApplyEndo Modify m s) = s++    fromEndo e =+        ApplyEndo . MonadState.state $ \s -> let s' = appEndo e s in (s', s')++-- | Evaluates 'ApplyEndo' in terms of 'MonadState.state' operation.+applyModify :: MonadState s m => ApplyEndo Modify m s -> m s+applyModify = applyEndo++-- | Evaluates 'ApplyEndo' in a 'Monad' by joining it with the monad it+-- contains. It can be also viewed as a variant of 'applyModify' defined as:+--+-- @+-- 'joinApplyModify' = ('>>=' 'applyModify')+-- @+joinApplyModify :: MonadState s m => m (ApplyEndo Modify m s) -> m s+joinApplyModify = (>>= applyEndo)++-- | Same as 'Modify', but strictness is implied.+data Modify'+  deriving+    ( Generic+#ifdef HAVE_KIND_POLYMORPHIC_TYPEABLE+    , Typeable+#endif+    )++-- | Evaluates 'ApplyEndo' in terms of 'MonadState.state' operation:+--+-- @+-- 'fromEndo' ('Endo' f) = 'ApplyEndo' . 'MonadState.state' $ \\s ->+--     let s' = f s in s' \`seq\` (s', s')+-- @+instance MonadState s m => FromEndo (ApplyEndo Modify' m s) where+    type EndoOperatedOn (ApplyEndo Modify' m s) = s++    fromEndo (Endo f) =+        ApplyEndo . MonadState.state $ \s -> let s' = f s in s' `seq` (s', s')++-- | Evaluates 'ApplyEndo' in terms of 'MonadState.state' operation.+applyModify' :: MonadState r m => ApplyEndo Modify' m () -> m ()+applyModify' = void . applyEndo++-- | Evaluates 'ApplyEndo' in a 'Monad' by joining it with the monad it+-- contains. It can be also viewed as a variant of 'applyModify'' defined as:+--+-- @+-- 'joinApplyModify'' = ('>>=' 'applyModify'')+-- @+joinApplyModify' :: MonadState r m => m (ApplyEndo Modify' m r) -> m r+joinApplyModify' = (>>= applyEndo)++-- }}} ApplyEndo Modify -------------------------------------------------------++-- {{{ Helper functions (not exported) ----------------------------------------++#ifndef HAVE_APPLICATIVE_MONAD+void :: Monad m => m a -> m ()+void = liftM $ const ()+#endif++-- {{{ Helper functions (not exported) ----------------------------------------
src/Data/Monoid/Endo/Fold.hs view
@@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-}--#ifdef KIND_POLYMORPHIC_TYPEABLE-{-# LANGUAGE DeriveDataTypeable #-}-#endif+{-# LANGUAGE TypeOperators #-}  #if MIN_VERSION_transformers(0,4,0) -- ExceptT was introduced in transformers == 0.4.0.0 and it deprecated ErrorT.@@ -14,22 +11,16 @@ #define HAVE_EXCEPTT #endif -#if MIN_VERSION_base(4,7,0)--- Module Data.Proxy, that defines Proxy data type, was introduced in--- base == 4.7.0.0.-#define HAVE_PROXY-#endif- -- | -- Module:       $HEADER$ -- Description:  Generic folding for various endomorphism representations.--- Copyright:    (c) 2014-2015, Peter Trško+-- Copyright:    (c) 2014-2016, Peter Trško -- License:      BSD3 -- -- Maintainer:   peter.trsko@gmail.com -- Stability:    experimental -- Portability:  CPP, DeriveDataTypeable, DeriveGeneric, FlexibleInstances,---               NoImplicitPrelude, TypeFamilies+--               NoImplicitPrelude, RankNTypes, TypeOperators, TypeFamilies -- -- Generic folding for various endomorphism representations. module Data.Monoid.Endo.Fold@@ -65,7 +56,8 @@     -- ** Type Wrappers     , WrappedFoldable(..) -    -- * Utility Functions+    -- * Utility Functions and Types+    , (:->)     , (&$)     , (<&$>)     , embedEndoWith@@ -73,29 +65,24 @@     )   where -import Control.Applicative (Applicative(pure), Const(Const))+import Control.Applicative+    ( Applicative(pure)+#ifndef HAVE_FUNCTOR_CONST_MODULE+    , Const(Const)+#endif+    ) import Control.Monad (Monad(return)) import Data.Either (Either(Right))-import Data.Foldable (Foldable(foldMap)) import Data.Function ((.), id) import Data.Functor (Functor(fmap))+#ifdef HAVE_FUNCTOR_CONST_MODULE+import Data.Functor.Const (Const(Const))+#endif import Data.Functor.Identity (Identity(Identity))-import Data.Maybe (Maybe(Just, Nothing))-import Data.Monoid (Dual(Dual, getDual), Endo(Endo), Monoid(mempty, mconcat), (<>))-import GHC.Generics (Generic)+import Data.Maybe (Maybe(Just))+import Data.Monoid (Dual(Dual), Endo, Monoid(mempty), (<>)) import System.IO (IO)-import Text.Read (Read)-import Text.Show (Show) -#ifdef KIND_POLYMORPHIC_TYPEABLE-import Data.Data (Data)-import Data.Typeable (Typeable)-#endif--#ifdef HAVE_PROXY-import Data.Proxy (Proxy(Proxy))-#endif- #ifdef HAVE_EXCEPTT import Control.Monad.Trans.Except (ExceptT) #endif@@ -111,9 +98,15 @@ import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT) import Data.Functor.Compose (Compose) import Data.Functor.Product (Product)-import Data.Functor.Reverse (Reverse) +import Data.Monoid.Endo.AnEndo+    ( AnEndo(..)+    , WrappedFoldable(..)+    , embedDualEndoWith+    , embedEndoWith+    ) + -- | Fold all variously represented endomorphisms in to one endomorphism. -- -- Order in which endomorphisms are folded is preserved:@@ -141,7 +134,7 @@ -- Order in which endomorphisms are folded is reversed: -- -- >>> dualFoldEndo (Endo (1:)) [(2:), (3:)] `appEndo` []--- [2,3,1]+-- [3,2,1] -- -- For numbers it would look like: --@@ -230,8 +223,8 @@ -- Examples: -- -- @--- 'foldEndo' \<*\> ((++) \<$\> getLine) \<*\> ((++) \<$\> getLine)---     :: :: ('FoldEndoArgs' r, 'ResultOperatesOn' r ~ String) => IO r+-- 'foldEndo' \<*\> ((<>) \<$\> getLine) \<*\> ((<>) \<$\> getLine)+--     :: ('FoldEndoArgs' r, 'ResultOperatesOn' r ~ String) => IO r -- @ -- -- In the next example, prefix @ghci\>@ indicates GHCi prompt, @ghci|@ is GHCi@@ -304,7 +297,7 @@ #ifdef HAVE_EXCEPTT instance     ( Monad m-#ifndef APPLICATIVE_MONAD+#ifndef HAVE_APPLICATIVE_MONAD     , Functor m #endif     , FoldEndoArgs r@@ -324,7 +317,7 @@  instance     ( Monad m-#ifndef APPLICATIVE_MONAD+#ifndef HAVE_APPLICATIVE_MONAD     , Functor m #endif     , FoldEndoArgs r@@ -342,7 +335,7 @@  instance     ( Monad m-#ifndef APPLICATIVE_MONAD+#ifndef HAVE_APPLICATIVE_MONAD     , Functor m #endif     , Monoid w@@ -356,7 +349,7 @@  instance     ( Monad m-#ifndef APPLICATIVE_MONAD+#ifndef HAVE_APPLICATIVE_MONAD     , Functor m #endif     , Monoid w@@ -401,422 +394,29 @@  -- }}} Transformers ----------------------------------------------------------- --- {{{ FoldEndoArgs Type Class ------------------------------------------------+-- }}} FoldEndoArgs Type Class ------------------------------------------------ --- {{{ AnEndo Type Class ------------------------------------------------------+-- {{{ Utility Functions and Types -------------------------------------------- --- | Class that represents various endomorphism representation. In other words--- anything that encodes @a -> a@ can be instance of this class.------ Here are some important instances with not so obvious definitions.+-- | Type alias that restricts type of endomorphism folding result, and it+-- looks similar to @->@. Example of creating version of 'foldEndo' with+-- specific result: -- -- @--- instance 'AnEndo' ('Proxy' a) where---     type 'EndoOperatesOn' ('Proxy' a) = a------     'anEndo'    _ = 'mempty' -- = Endo 'id'---     'aDualEndo' _ = 'mempty'+-- foldToEndoString :: 'FoldEndoArgs' args => args ':->' 'Endo' String+-- foldToEndoString = 'foldEndo' -- @ ----- It got quite common to use 'Proxy' data type as an explicit way to pass--- types around. Above instance allows you to restrict type of result of--- endomorphism folding, to some extent.------ @--- instance 'AnEndo' a => 'AnEndo' (Maybe a) where---     type 'EndoOperatesOn' (Maybe a) = 'EndoOperatesOn' a+-- >>> foldToEndoString ("foo" <>) ("bar" <>) `appEndo` "baz"+-- "foobarbaz" -----     'anEndo' Nothing  = 'mempty' -- = Endo 'id'---     'anEndo' (Just e) = 'anEndo' e+-- Following type signatures for 'foldEndoArgs' are equivalent: -----     -- Definition of 'aDualEndo' is analogous. -- @------ Instance for @Maybe@ lets us conditionally inject endomorphism in to a--- folding chain.-class AnEndo a where-    -- | Extract type on which endomorphism operates, e.g. for-    -- @'Endo' a@ it would be @a@.-    type EndoOperatesOn a--    -- | Convert value encoding @a -> a@ in to 'Endo'. Default implementation:-    ---    -- @-    -- 'anEndo' = 'getDual' . 'aDualEndo'-    -- @-    anEndo :: a -> Endo (EndoOperatesOn a)-    anEndo = getDual . aDualEndo--    -- | Dual to 'anEndo'. Default implementation:-    ---    -- @-    -- 'aDualEndo' = 'Dual' . 'anEndo'-    -- @-    aDualEndo :: a -> Dual (Endo (EndoOperatesOn a))-    aDualEndo = Dual . anEndo--#if HAVE_MINIMAL_PRAGMA-    {-# MINIMAL anEndo | aDualEndo #-}-#endif--instance AnEndo (Endo a) where-    type EndoOperatesOn (Endo a) = a-    anEndo = id--instance AnEndo (a -> a) where-    type EndoOperatesOn (a -> a) = a-    anEndo = Endo--instance AnEndo a => AnEndo (Maybe a) where-    type EndoOperatesOn (Maybe a) = EndoOperatesOn a--    anEndo Nothing  = mempty-    anEndo (Just e) = anEndo e--    aDualEndo Nothing  = mempty-    aDualEndo (Just e) = aDualEndo e--#ifdef HAVE_PROXY--- | Constructs identity endomorphism for specified phantom type.-instance AnEndo (Proxy a) where-    type EndoOperatesOn (Proxy a) = a--    anEndo    Proxy = mempty-    aDualEndo Proxy = mempty-#endif---- {{{ Foldable Instances --------------------------------------------------------- | Wrapper for 'Foldable' instances.------ This allows using 'foldEndo' and 'dualFoldEndo' for any 'Foldable' instance--- without the need for @OverlappingInstances@ language extension.-newtype WrappedFoldable f a = WrapFoldable {getFoldable :: f a}-  deriving-    ( Generic-    , Read-    , Show-#ifdef KIND_POLYMORPHIC_TYPEABLE-    , Data-    , Typeable-#endif-    )--instance (Foldable f, AnEndo a) => AnEndo (WrappedFoldable f a) where-    type EndoOperatesOn (WrappedFoldable f a) = EndoOperatesOn a-    anEndo    (WrapFoldable fa) = foldMap anEndo    fa-    aDualEndo (WrapFoldable fa) = foldMap aDualEndo fa--instance AnEndo a => AnEndo [a] where-    type EndoOperatesOn [a] = EndoOperatesOn a-    anEndo    = anEndo    . WrapFoldable-    aDualEndo = aDualEndo . WrapFoldable---- {{{ Transformers --------------------------------------------------------------- | Fold in reverese order.-instance (Foldable f, AnEndo a) => AnEndo (Reverse f a) where-    type EndoOperatesOn (Reverse f a) = EndoOperatesOn a-    anEndo    = anEndo    . WrapFoldable-    aDualEndo = aDualEndo . WrapFoldable---- }}} Transformers --------------------------------------------------------------- }}} Foldable Instances --------------------------------------------------------- {{{ Instances For Tuples -----------------------------------------------------instance-    ( AnEndo a-    , AnEndo b-    , EndoOperatesOn a ~ EndoOperatesOn b-    ) => AnEndo (a, b)-  where-    type EndoOperatesOn (a, b) = EndoOperatesOn a-    anEndo    (a, b) = anEndo    a <> anEndo    b-    aDualEndo (a, b) = aDualEndo a <> aDualEndo b--instance-    ( AnEndo a-    , AnEndo b-    , AnEndo c-    , EndoOperatesOn a ~ EndoOperatesOn b-    , EndoOperatesOn a ~ EndoOperatesOn c-    ) => AnEndo (a, b, c)-  where-    type EndoOperatesOn (a, b, c) = EndoOperatesOn a-    anEndo    (a, b, c) = anEndo    a <> anEndo    b <> anEndo    c-    aDualEndo (a, b, c) = aDualEndo a <> aDualEndo b <> aDualEndo c--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    ) => AnEndo (a1, a2, a3, a4)-  where-    type EndoOperatesOn (a1, a2, a3, a4) = EndoOperatesOn a1-    anEndo (a1, a2, a3, a4) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        ]--    aDualEndo (a1, a2, a3, a4) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    ) => AnEndo (a1, a2, a3, a4, a5)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        ]--    aDualEndo (a1, a2, a3, a4, a5) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , AnEndo a6-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a6-    ) => AnEndo (a1, a2, a3, a4, a5, a6)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5, a6) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5, a6) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        , anEndo a6-        ]--    aDualEndo (a1, a2, a3, a4, a5, a6) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        , aDualEndo a6-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , AnEndo a6-    , AnEndo a7-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a6-    , EndoOperatesOn a1 ~ EndoOperatesOn a7-    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5, a6, a7) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        , anEndo a6-        , anEndo a7-        ]--    aDualEndo (a1, a2, a3, a4, a5, a6, a7) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        , aDualEndo a6-        , aDualEndo a7-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , AnEndo a6-    , AnEndo a7-    , AnEndo a8-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a6-    , EndoOperatesOn a1 ~ EndoOperatesOn a7-    , EndoOperatesOn a1 ~ EndoOperatesOn a8-    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5, a6, a7, a8) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        , anEndo a6-        , anEndo a7-        , anEndo a8-        ]--    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        , aDualEndo a6-        , aDualEndo a7-        , aDualEndo a8-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , AnEndo a6-    , AnEndo a7-    , AnEndo a8-    , AnEndo a9-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a6-    , EndoOperatesOn a1 ~ EndoOperatesOn a7-    , EndoOperatesOn a1 ~ EndoOperatesOn a8-    , EndoOperatesOn a1 ~ EndoOperatesOn a9-    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8, a9) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        , anEndo a6-        , anEndo a7-        , anEndo a8-        , anEndo a9-        ]--    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        , aDualEndo a6-        , aDualEndo a7-        , aDualEndo a8-        , aDualEndo a9-        ]--instance-    ( AnEndo a1-    , AnEndo a2-    , AnEndo a3-    , AnEndo a4-    , AnEndo a5-    , AnEndo a6-    , AnEndo a7-    , AnEndo a8-    , AnEndo a9-    , AnEndo a10-    , EndoOperatesOn a1 ~ EndoOperatesOn a2-    , EndoOperatesOn a1 ~ EndoOperatesOn a3-    , EndoOperatesOn a1 ~ EndoOperatesOn a4-    , EndoOperatesOn a1 ~ EndoOperatesOn a5-    , EndoOperatesOn a1 ~ EndoOperatesOn a6-    , EndoOperatesOn a1 ~ EndoOperatesOn a7-    , EndoOperatesOn a1 ~ EndoOperatesOn a8-    , EndoOperatesOn a1 ~ EndoOperatesOn a9-    , EndoOperatesOn a1 ~ EndoOperatesOn a10-    ) => AnEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)-  where-    type EndoOperatesOn (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = EndoOperatesOn a1--    anEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = mconcat-        [ anEndo a1-        , anEndo a2-        , anEndo a3-        , anEndo a4-        , anEndo a5-        , anEndo a6-        , anEndo a7-        , anEndo a8-        , anEndo a9-        , anEndo a10-        ]--    aDualEndo (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = mconcat-        [ aDualEndo a1-        , aDualEndo a2-        , aDualEndo a3-        , aDualEndo a4-        , aDualEndo a5-        , aDualEndo a6-        , aDualEndo a7-        , aDualEndo a8-        , aDualEndo a9-        , aDualEndo a10-        ]---- }}} Instances For Tuples ------------------------------------------------------ }}} AnEndo Type Class ---------------------------------------------------------- {{{ Utility Functions ------------------------------------------------------+-- 'FoldEndoArgs' args => args ':->' 'Endo' String+-- ('FoldEndoArgs' args, 'Result' args ~ 'Endo' String) => args+-- @+type args :-> r = (Result args ~ r) => args  -- | Variant of function @('Data.Function.$') :: (a -> b) -> a -> b@, from -- "Data.Function" module, but with fixity as@@ -833,39 +433,7 @@ (<&$>) = fmap infixl 1 <&$> --- | Use 'Endo' (possibly result of 'foldEndo') and use it to create value of--- different type.------ Examples:------ @--- 'embedEndoWith' 'Control.Monad.Trans.Writer.Lazy.tell'---     :: (Monad m, 'AnEndo' e, w ~ 'EndoOperatesOn' e)---     => e---     -> 'Control.Monad.Trans.Writer.Lazy.WriterT' ('Endo' w) m ()------ 'embedEndoWith' 'Control.Monad.Trans.State.Lazy.modify'---     :: (Monad m, 'AnEndo' e, s ~ 'EndoOperatesOn' e)---     => e---     -> 'Control.Monad.Trans.State.Lazy.StateT' s m ()--- @------ See also 'embedDualEndoWith'.-embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a)-    => (Endo a -> b)-    -- ^ Embedding function.-    -> e -> b-embedEndoWith = (. anEndo)---- | Dual to 'embedEndoWith', which uses 'aDualEndo' instead of 'anEndo'.-embedDualEndoWith-    :: (AnEndo e, EndoOperatesOn e ~ a)-    => (Dual (Endo a) -> b)-    -- ^ Embedding function.-    -> e -> b-embedDualEndoWith = (. aDualEndo)---- }}} Utility Functions ------------------------------------------------------+-- }}} Utility Functions and Types --------------------------------------------  -- $basicIdea --@@ -873,7 +441,7 @@ -- -- @ -- data Verbosity = Silent | Normal | Verbose | Annoying---   deriving (Bounded, Data, Enum, Eq, Ord, Show, Typeable)+--   deriving (Show) -- -- data Config = Config --     { _verbosity :: Verbosity
+ src/Data/Monoid/Endo/FromEndo.hs view
@@ -0,0 +1,194 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module:       $HEADER$+-- Description:  Convert endomorphism in to a value.+-- Copyright:    (c) 2015, Peter Trško+-- License:      BSD3+--+-- Maintainer:   peter.trsko@gmail.com+-- Stability:    experimental+-- Portability:  NoImplicitPrelude+--+-- Convert endomorphism in to a value.+module Data.Monoid.Endo.FromEndo+    (+    -- * Convert Endo to a Value+      FromEndo(..)+    , fromEndoWith+    , fromEndoWithF+    , fromDualEndoWith+    , fromDualEndoWithF+    , fromEndoTo+    , fromDualEndoTo+    )+  where++import Control.Monad (Monad)+import Data.Function ((.), id)+import Data.Functor (Functor(fmap))+import Data.Monoid (Dual(Dual, getDual), Endo(Endo, appEndo), Monoid)++import Control.Monad.Trans.Reader (ReaderT)+import Control.Monad.Trans.Reader as Reader (asks)+import Control.Monad.Trans.RWS.Lazy as Lazy (RWST)+import Control.Monad.Trans.RWS.Lazy as Lazy.RWS (modify)+import Control.Monad.Trans.RWS.Strict as Strict (RWST)+import Control.Monad.Trans.RWS.Strict as Strict.RWS (modify)+import Control.Monad.Trans.State.Lazy as Lazy (StateT)+import Control.Monad.Trans.State.Lazy as Lazy.State (modify)+import Control.Monad.Trans.State.Strict as Strict (StateT)+import Control.Monad.Trans.State.Strict as Strict.State (modify)+++-- | Type class provides functionality for converting @'Endo' b@ and @'Dual'+-- ('Endo' b)@ in to some type @a@. Type @b@, on which endomorphism operates,+-- is implied by type @a@, but generally aren't the same type. In other words+-- it is dual type class to 'Data.Monoid.Endo.AnEndo'.+class FromEndo a where+    type EndoOperatedOn a++    -- | Convert endomorphism in to a value of type @a@.+    fromEndo :: Endo (EndoOperatedOn a) -> a++    -- | Provided default implementation:+    --+    -- @+    -- 'fromDualEndo' = 'fromEndo' '.' 'getDual'+    -- @+    fromDualEndo :: Dual (Endo (EndoOperatedOn a)) -> a+    fromDualEndo = fromEndo . getDual++#ifdef HAVE_MINIMAL_PRAGMA+    {-# MINIMAL fromEndo #-}+#endif++instance FromEndo (a -> a) where+    type EndoOperatedOn (a -> a) = a++    fromEndo = appEndo+    fromDualEndo = appEndo . getDual++instance FromEndo (Endo a) where+    type EndoOperatedOn (Endo a) = a++    fromEndo = id+    fromDualEndo = getDual++instance FromEndo e => FromEndo (Dual e) where+    type EndoOperatedOn (Dual e) = EndoOperatedOn e++    fromEndo = Dual . fromEndo+    fromDualEndo = Dual . fromDualEndo++-- {{{ Transformers instances for FromEndo ------------------------------------++-- | Retrieve environment modified by endomorphism.+--+-- @+-- 'fromEndo' ('Endo' f) = 'Reader.asks' f+-- @+instance Monad f => FromEndo (ReaderT r f r) where+    type EndoOperatedOn (ReaderT r f r) = r++    fromEndo (Endo f) = Reader.asks f++-- | Modify state.+--+-- @+-- 'fromEndo' ('Endo' f) = 'Lazy.RWS.modify' f+-- @+instance (Monoid w, Monad f) => FromEndo (Lazy.RWST r w s f ()) where+    type EndoOperatedOn (Lazy.RWST r w s f ()) = s++    fromEndo (Endo f) = Lazy.RWS.modify f++-- | Modify state.+--+-- @+-- 'fromEndo' ('Endo' f) = 'Strict.RWS.modify' f+-- @+instance (Monoid w, Monad f) => FromEndo (Strict.RWST r w s f ()) where+    type EndoOperatedOn (Strict.RWST r w s f ()) = s++    fromEndo (Endo f) = Strict.RWS.modify f++-- | Modify state.+--+-- @+-- 'fromEndo' ('Endo' f) = 'Lazy.State.modify' f+-- @+instance Monad f => FromEndo (Lazy.StateT s f ()) where+    type EndoOperatedOn (Lazy.StateT s f ()) = s++    fromEndo (Endo f) = Lazy.State.modify f++-- | Modify state.+--+-- @+-- 'fromEndo' ('Endo' f) = 'Strict.State.modify' f+-- @+instance Monad f => FromEndo (Strict.StateT s f ()) where+    type EndoOperatedOn (Strict.StateT s f ()) = s++    fromEndo (Endo f) = Strict.State.modify f++-- }}} Transformers instances for FromEndo ------------------------------------++-- | In a lot of cases it is necessary to evaluate result of 'fromEndo'.+-- Example:+--+-- >>> fromEndoWith ((`runState` def) :: State Int () -> ((), Int)) (Endo (+10))+-- ((), 10)+--+-- Following property holds:+--+-- @+-- 'fromEndoWith' 'id' = 'fromEndo'+-- @+--+-- See also 'fromDualEndoWith'.+fromEndoWith :: (FromEndo a, EndoOperatedOn a ~ c) => (a -> b) -> Endo c -> b+fromEndoWith = (. fromEndo)++-- | Same as 'fromEndoWith', but deals with 'Endo' wrapped inside a 'Functor'.+fromEndoWithF+    :: (Functor f, FromEndo a, EndoOperatedOn a ~ c)+    => (f a -> b) -> f (Endo c) -> b+fromEndoWithF = (. fmap fromEndo)++-- | In a lot of cases it is necessary to evaluate result of 'fromDualEndo'.+-- Example:+--+-- >>> fromEndoWith ((`runState` def) :: State Int () -> ((), Int)) (Dual (Endo (+10)))+-- ((), 10)+--+-- Following property holds:+--+-- @+-- 'fromDualEndoWith' 'id' = 'fromDualEndo'+-- @+--+-- See also 'fromEndoWith'.+fromDualEndoWith+    :: (FromEndo a, EndoOperatedOn a ~ c) => (a -> b) -> Dual (Endo c) -> b+fromDualEndoWith = (. fromDualEndo)++-- | Same as 'fromDualEndoWith', but deals with @'Dual' 'Endo'@ wrapped inside+-- a 'Functor'.+fromDualEndoWithF+    :: (Functor f, FromEndo a, EndoOperatedOn a ~ c)+    => (f a -> b) -> f (Dual (Endo c)) -> b+fromDualEndoWithF = (. fmap fromDualEndo)++-- | Variant of 'fromEndo' that takes type restriction on the result type @a@+-- as an argument.+fromEndoTo :: FromEndo a => Endo (EndoOperatedOn a) -> proxy a -> a+fromEndoTo e _ = fromEndo e++-- | Variant of 'fromDualEndo' that takes type restriction on the result type+-- @a@ as an argument.+fromDualEndoTo :: FromEndo a => Dual (Endo (EndoOperatedOn a)) -> proxy a -> a+fromDualEndoTo e _ = fromDualEndo e