endo 0.1.0.2 → 0.2.0.0
raw patch · 7 files changed
+142/−21 lines, 7 filesdep ~basedep ~betweendep ~transformersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, between, transformers
API changes (from Hackage documentation)
+ Data.Monoid.Endo.Fold: embedDualEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Dual (Endo a) -> b) -> e -> b
+ Data.Monoid.Endo.Fold: embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Endo a -> b) -> e -> b
+ Data.Monoid.Endo.Fold: instance (Monoid c, FoldEndoArgs r) => FoldEndoArgs (Const c r)
+ Data.Monoid.Endo.Fold: instance AnEndo (Proxy a)
- Data.Monoid.Endo.Fold: class AnEndo a where type family EndoOperatesOn a aDualEndo = Dual . anEndo
+ Data.Monoid.Endo.Fold: class AnEndo a where type family EndoOperatesOn a anEndo = getDual . aDualEndo aDualEndo = Dual . anEndo
- Data.Monoid.Endo.Fold: class FoldEndoArgs a where type family ResultOperatesOn a
+ Data.Monoid.Endo.Fold: class FoldEndoArgs a where type family ResultOperatesOn a type family Result a
Files
- ChangeLog.md +35/−6
- README.md +2/−0
- endo.cabal +9/−9
- example/Example2.hs +1/−0
- example/Example6.hs +1/−0
- src/Data/Monoid/Endo.hs +4/−2
- src/Data/Monoid/Endo/Fold.hs +90/−4
ChangeLog.md view
@@ -1,32 +1,61 @@ # ChangeLog / ReleaseNotes +## Version 0.2.0.0++* 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)+* 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)+* Introducing functions `embedEndoWith` and `embedDualEndoWith`. Both can be+ used to simplify application of endomorphisms that are result of folding.+ (new)+ - `embedEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Endo a -> b) -> e+ -> b`+ - `embedDualEndoWith :: (AnEndo e, EndoOperatesOn e ~ a) => (Dual (Endo a)+ -> b) -> e -> b`+* 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)+* 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)+* Bumping upper bounds on base and between, therefore it now builds on GHC 7.10+ 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). * Minor documentation updates.-* Uploaded to [Hackage][]- <http://hackage.haskell.org/package/endo-0.1.0.2>+* Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.1.0.2> ## Version 0.1.0.1 * Bugfix release. * Bugfix: Unable to compile with transformers >= 0.4.-* Uploaded to [Hackage][]:- <http://hackage.haskell.org/package/endo-0.1.0.1>+* 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.** * First public release.-* Uploaded to [Hackage][]:- <http://hackage.haskell.org/package/endo-0.1.0.0>+* Uploaded to [Hackage][]: <http://hackage.haskell.org/package/endo-0.1.0.0> [Hackage]: http://hackage.haskell.org/ "HackageDB (or just Hackage) is a collection of releases of Haskell packages."++<!--+ vim: filetype=markdown softtabstop=4 shiftwidth=4 expandtab+-->
README.md view
@@ -4,6 +4,8 @@ [][Haskell.org] [][tl;dr Legal: BSD3] +[](https://travis-ci.org/trskop/endo)+ ## Description
endo.cabal view
@@ -1,5 +1,5 @@ name: endo-version: 0.1.0.2+version: 0.2.0.0 synopsis: Endomorphism utilities. description: Package defines extra functions for 'Data.Monoid.Endo' data type, and also@@ -21,11 +21,11 @@ > where > options' :: IdentityT Parser (Endo Config) > options' = foldEndo- > <*> outputOption -- IdentityT Parser (Maybe (E Config))- > <*> verbosityOption -- IdentityT Parser (Maybe (E Config))- > <*> annoyingFlag -- IdentityT Parser (E Config)- > <*> silentFlag -- IdentityT Parser (E Config)- > <*> verboseFlag -- IdentityT Parser (E Config)+ > <*> outputOption -- :: IdentityT Parser (Maybe (E Config))+ > <*> verbosityOption -- :: IdentityT Parser (Maybe (E Config))+ > <*> annoyingFlag -- :: IdentityT Parser (E Config)+ > <*> silentFlag -- :: IdentityT Parser (E Config)+ > <*> verboseFlag -- :: IdentityT Parser (E Config) > > defaultConfig :: Config > defaultConfig = Config Normal ""@@ -87,11 +87,11 @@ build-depends: -- {{{ Distributed with GHC or Haskell Platform ---------------------------- base >=4.6 && <4.8+ base >=4.6 && <4.9 , transformers >=0.3 && <0.5 -- }}} Distributed with GHC or Haskell Platform --------------------------- - , between == 0.9.*+ , between >=0.9 && <0.11 if impl(GHC >= 7.8) cpp-options: -DHAVE_MINIMAL_PRAGMA@@ -113,4 +113,4 @@ source-repository this type: git location: git://github.com/trskop/endo.git- tag: 0.1.0.2+ tag: 0.2.0.0
example/Example2.hs view
@@ -15,6 +15,7 @@ import Data.Function (($), id) import Data.Monoid (Endo(appEndo))+import System.IO (FilePath) import Data.Monoid.Endo (E) import Data.Monoid.Endo.Fold ((&$), foldEndo)
example/Example6.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module: $HEADER$ -- Description: Example 6
src/Data/Monoid/Endo.hs view
@@ -20,7 +20,7 @@ , mapEndo2 , liftEndo - -- ** Lens+ -- * Lens , endo ) where@@ -57,7 +57,9 @@ -- | Lens for 'Endo'. In terms of /lens/ package it would have type: ----- > endo :: Lens (Endo a) (Endo b) (E a) (E b)+-- @+-- 'endo' :: Lens ('Endo' a) ('Endo' b) ('E' a) ('E' b)+-- @ -- -- For details see <http://hackage.haskell.org/package/lens lens package>. endo :: Functor f => (E a -> f (E b)) -> Endo a -> f (Endo b)
src/Data/Monoid/Endo/Fold.hs view
@@ -14,6 +14,12 @@ #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.@@ -48,10 +54,12 @@ -- * Utility Functions , (&$) , (<&$>)+ , embedEndoWith+ , embedDualEndoWith ) where -import Control.Applicative (Applicative(pure))+import Control.Applicative (Applicative(pure), Const(Const)) import Control.Monad (Monad(return)) import Data.Either (Either(Right)) import Data.Foldable (Foldable(foldMap))@@ -59,7 +67,7 @@ import Data.Functor (Functor(fmap)) import Data.Functor.Identity (Identity(Identity)) import Data.Maybe (Maybe(Just, Nothing))-import Data.Monoid (Dual(Dual), Endo(Endo), Monoid(mempty, mconcat), (<>))+import Data.Monoid (Dual(Dual, getDual), Endo(Endo), Monoid(mempty, mconcat), (<>)) import GHC.Generics (Generic) import System.IO (IO) import Text.Read (Read)@@ -70,6 +78,10 @@ import Data.Typeable (Typeable) #endif +#ifdef HAVE_PROXY+import Data.Proxy (Proxy(Proxy))+#endif+ #ifdef HAVE_EXCEPTT import Control.Monad.Trans.Except (ExceptT) #endif@@ -139,6 +151,9 @@ -- | Extracts type of a value that is modified by the result. type ResultOperatesOn a + -- | Result type of the whole endomorphism folding.+ type Result a+ foldEndoArgs :: Endo (ResultOperatesOn a) -> a dualFoldEndoArgs :: Dual (Endo (ResultOperatesOn a)) -> a #ifdef HAVE_MINIMAL_PRAGMA@@ -152,31 +167,43 @@ ) => FoldEndoArgs (a -> r) where type ResultOperatesOn (a -> r) = ResultOperatesOn r+ type Result (a -> r) = Result r foldEndoArgs e e' = foldEndoArgs (e <> anEndo e') dualFoldEndoArgs e e' = dualFoldEndoArgs (e <> aDualEndo e') instance FoldEndoArgs (Endo a) where type ResultOperatesOn (Endo a) = a+ type Result (Endo a) = Endo a foldEndoArgs = id dualFoldEndoArgs (Dual e) = e +instance (Monoid c, FoldEndoArgs r) => FoldEndoArgs (Const c r) where+ type ResultOperatesOn (Const c r) = ResultOperatesOn r+ type Result (Const c r) = Const c (Result r)+ foldEndoArgs _ = Const mempty+ dualFoldEndoArgs _ = Const mempty+ instance FoldEndoArgs r => FoldEndoArgs (Either e r) where type ResultOperatesOn (Either e r) = ResultOperatesOn r+ type Result (Either e r) = Either e (Result r) foldEndoArgs = Right . foldEndoArgs dualFoldEndoArgs = Right . dualFoldEndoArgs instance FoldEndoArgs r => FoldEndoArgs (Identity r) where type ResultOperatesOn (Identity r) = ResultOperatesOn r+ type Result (Identity r) = Identity (Result r) foldEndoArgs = Identity . foldEndoArgs dualFoldEndoArgs = Identity . dualFoldEndoArgs instance FoldEndoArgs r => FoldEndoArgs (IO r) where type ResultOperatesOn (IO r) = ResultOperatesOn r+ type Result (IO r) = IO (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs instance FoldEndoArgs r => FoldEndoArgs (Maybe r) where type ResultOperatesOn (Maybe r) = ResultOperatesOn r+ type Result (Maybe r) = Maybe (Result r) foldEndoArgs = Just . foldEndoArgs dualFoldEndoArgs = Just . dualFoldEndoArgs @@ -189,6 +216,7 @@ => FoldEndoArgs (Compose f g r) where type ResultOperatesOn (Compose f g r) = ResultOperatesOn r+ type Result (Compose f g r) = Compose f g (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -197,6 +225,7 @@ => FoldEndoArgs (Product f g r) where type ResultOperatesOn (Product f g r) = ResultOperatesOn r+ type Result (Product f g r) = Product f g (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -214,6 +243,7 @@ -- @ instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (IdentityT f r) where type ResultOperatesOn (IdentityT f r) = ResultOperatesOn r+ type Result (IdentityT f r) = IdentityT f (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -227,12 +257,14 @@ ) => FoldEndoArgs (ExceptT e m r) where type ResultOperatesOn (ExceptT e m r) = ResultOperatesOn r+ type Result (ExceptT e m r) = ExceptT e m (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs #endif instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (ListT f r) where type ResultOperatesOn (ListT f r) = ResultOperatesOn r+ type Result (ListT f r) = ListT f (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -244,11 +276,13 @@ , FoldEndoArgs r ) => FoldEndoArgs (MaybeT m r) where type ResultOperatesOn (MaybeT m r) = ResultOperatesOn r+ type Result (MaybeT m r) = MaybeT m (Result r) foldEndoArgs = return . foldEndoArgs dualFoldEndoArgs = return . dualFoldEndoArgs instance (Applicative f, FoldEndoArgs r) => FoldEndoArgs (ReaderT r' f r) where type ResultOperatesOn (ReaderT r' f r) = ResultOperatesOn r+ type Result (ReaderT r' f r) = ReaderT r' f (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -262,6 +296,7 @@ ) => FoldEndoArgs (RWST r' w s m r) where type ResultOperatesOn (RWST r' w s m r) = ResultOperatesOn r+ type Result (RWST r' w s m r) = RWST r' w s m (Result r) foldEndoArgs = return . foldEndoArgs dualFoldEndoArgs = return . dualFoldEndoArgs @@ -275,16 +310,19 @@ ) => FoldEndoArgs (Strict.RWST r' w s m r) where type ResultOperatesOn (Strict.RWST r' w s m r) = ResultOperatesOn r+ type Result (Strict.RWST r' w s m r) = Strict.RWST r' w s m (Result r) foldEndoArgs = return . foldEndoArgs dualFoldEndoArgs = return . dualFoldEndoArgs instance (Monad m, FoldEndoArgs r) => FoldEndoArgs (StateT s m r) where type ResultOperatesOn (StateT s m r) = ResultOperatesOn r+ type Result (StateT s m r) = StateT s m (Result r) foldEndoArgs = return . foldEndoArgs dualFoldEndoArgs = return . dualFoldEndoArgs instance (Monad m, FoldEndoArgs r) => FoldEndoArgs (Strict.StateT s m r) where type ResultOperatesOn (Strict.StateT s m r) = ResultOperatesOn r+ type Result (Strict.StateT s m r) = Strict.StateT s m (Result r) foldEndoArgs = return . foldEndoArgs dualFoldEndoArgs = return . dualFoldEndoArgs @@ -292,6 +330,7 @@ (Applicative f, FoldEndoArgs r, Monoid w) => FoldEndoArgs (WriterT w f r) where type ResultOperatesOn (WriterT w f r) = ResultOperatesOn r+ type Result (WriterT w f r) = WriterT w f (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -300,6 +339,7 @@ => FoldEndoArgs (Strict.WriterT w f r) where type ResultOperatesOn (Strict.WriterT w f r) = ResultOperatesOn r+ type Result (Strict.WriterT w f r) = Strict.WriterT w f (Result r) foldEndoArgs = pure . foldEndoArgs dualFoldEndoArgs = pure . dualFoldEndoArgs @@ -318,8 +358,13 @@ -- @'Endo' a@ it would be @a@. type EndoOperatesOn a - -- | Convert value encoding @a -> a@ in to 'Endo'.+ -- | 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: --@@ -330,7 +375,7 @@ aDualEndo = Dual . anEndo #if HAVE_MINIMAL_PRAGMA- {-# MINIMAL anEndo #-}+ {-# MINIMAL anEndo | aDualEndo #-} #endif instance AnEndo (Endo a) where@@ -347,6 +392,15 @@ anEndo Nothing = mempty anEndo (Just e) = anEndo 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.@@ -693,6 +747,38 @@ (<&$>) :: Functor f => (a -> b) -> f a -> f b (<&$>) = 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 ------------------------------------------------------