monad-gen 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+115/−56 lines, 3 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Monad.Gen: instance (Monad m, Enum e) => MonadGen e (GenT e m)
- Control.Monad.Gen: instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m)
- Control.Monad.Gen: instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m)
- Control.Monad.Gen: instance MonadGen e m => MonadGen e (IdentityT m)
- Control.Monad.Gen: instance MonadGen e m => MonadGen e (ListT m)
- Control.Monad.Gen: instance MonadGen e m => MonadGen e (MaybeT m)
- Control.Monad.Gen: instance MonadGen e m => MonadGen e (ReaderT s m)
- Control.Monad.Gen: instance MonadGen e m => MonadGen e (StateT s m)
- Control.Monad.Gen: runGenInt :: Gen Integer a -> a
- Control.Monad.Gen: runGenTInt :: Monad m => GenT Integer m a -> m a
+ Control.Monad.Gen: instance (Monad m, Functor m, MonadPlus m) => Alternative (GenT e m)
+ Control.Monad.Gen: instance MonadCont m => MonadCont (GenT e m)
+ Control.Monad.Gen: instance MonadError e m => MonadError e (GenT e m)
+ Control.Monad.Gen: instance MonadFix m => MonadFix (GenT e m)
+ Control.Monad.Gen: instance MonadIO m => MonadIO (GenT e m)
+ Control.Monad.Gen: instance MonadPlus m => MonadPlus (GenT e m)
+ Control.Monad.Gen: runGenTWith :: Monad m => e -> GenT e m a -> m a
+ Control.Monad.Gen: runGenWith :: e -> Gen e a -> a
+ Control.Monad.Gen.Class: class Monad m => MonadGen e m | m -> e
+ Control.Monad.Gen.Class: gen :: MonadGen e m => m e
+ Control.Monad.Gen.Class: instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m)
+ Control.Monad.Gen.Class: instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m)
+ Control.Monad.Gen.Class: instance (Monoid w, MonadGen e m) => MonadGen e (RWST r w s m)
+ Control.Monad.Gen.Class: instance (Monoid w, MonadGen e m) => MonadGen e (WriterT w m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (ContT r m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (IdentityT m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (ListT m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (MaybeT m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (ReaderT s m)
+ Control.Monad.Gen.Class: instance MonadGen e m => MonadGen e (StateT s m)
- Control.Monad.Gen: runGen :: e -> Gen e a -> a
+ Control.Monad.Gen: runGen :: Enum e => Gen e a -> a
- Control.Monad.Gen: runGenT :: Monad m => e -> GenT e m a -> m a
+ Control.Monad.Gen: runGenT :: (Enum e, Monad m) => GenT e m a -> m a
Files
- monad-gen.cabal +9/−12
- src/Control/Monad/Gen.hs +48/−44
- src/Control/Monad/Gen/Class.hs +58/−0
monad-gen.cabal view
@@ -1,26 +1,23 @@ name: monad-gen-version: 0.1.0.0+version: 0.2.0.0 synopsis: A simple monad for generating fresh integers-description: It's a common in Haskell programs to thread some state- through the application using @State@ or some other similar pattern.-- This package simply wraps @State@ and uses it to generate fresh values,- any @Enum@ value will work.+description:+ This module provides a simple monad transformer @GenT@ to enumerate unique values within+ a monadic computation. It also plays nicely with everything in the MTL. license: MIT license-file: LICENSE author: Danny Gratzer maintainer: danny.gratzer@gmail.com category: Utility- build-type: Simple- cabal-version: >=1.10 +source-repository head+ type: hg+ location: https://bitbucket.org/jozefg/monad-gen library- exposed-modules: Control.Monad.Gen- other-extensions: FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, DeriveFunctor- build-depends: base >=4.6 && <5.0, mtl == 2.*, transformers > 0.3+ exposed-modules: Control.Monad.Gen, Control.Monad.Gen.Class+ build-depends: base >=4 && <5.0, mtl == 2.*, transformers > 0.3 hs-source-dirs: src default-language: Haskell2010-
src/Control/Monad/Gen.hs view
@@ -1,24 +1,28 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances, DeriveFunctor, FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances, DeriveFunctor #-}+{-# LANGUAGE CPP #-} module Control.Monad.Gen ( GenT , Gen , MonadGen(..) , runGenT , runGen- , runGenTInt- , runGenInt) where+ , runGenTWith+ , runGenWith) where+#if MIN_VERSION_mtl(2, 2, 1)+import Control.Monad.Except+#else+import Control.Monad.Error+#endif+ import Control.Applicative-import Control.Monad.Cont import Control.Monad.Identity-import Control.Monad.Reader+import Control.Monad.Cont.Class+import Control.Monad.Reader.Class import Control.Monad.State-import Control.Monad.Writer-import Control.Monad.Trans.Identity-import Control.Monad.Error-import Control.Monad.Trans.Maybe-import Control.Monad.Trans.List-import qualified Control.Monad.Trans.State as State+import Control.Monad.Writer.Class+import Control.Monad.Gen.Class+ -- | The monad transformer for generating fresh values. newtype GenT e m a = GenT {unGenT :: StateT e m a} deriving(Functor)@@ -28,6 +32,9 @@ instance (Functor f, Monad f) => Applicative (GenT e f) where pure = GenT . pure (GenT f) <*> (GenT a) = GenT $ f <*> a+instance (Monad m, Functor m, MonadPlus m) => Alternative (GenT e m) where+ empty = mzero+ (<|>) = mplus type Gen e = GenT e Identity @@ -44,40 +51,37 @@ tell m = lift $ tell m listen = GenT . listen . unGenT pass = GenT . pass . unGenT---- | The MTL style class for generating fresh values-class Monad m => MonadGen e m | m -> e where- -- | Generate a fresh value @e@, @gen@ should never produce the- -- same value within a monadic computation.- gen :: m e+instance MonadFix m => MonadFix (GenT e m) where+ mfix = GenT . mfix . (unGenT .)+instance MonadPlus m => MonadPlus (GenT e m) where+ mzero = GenT mzero+ mplus (GenT m) (GenT m') = GenT $ mplus m m'+instance MonadIO m => MonadIO (GenT e m) where+ liftIO = GenT . liftIO+instance MonadCont m => MonadCont (GenT e m) where+ callCC f = GenT $ callCC (unGenT . f . (GenT .)) -instance (Monad m, Enum e) => MonadGen e (GenT e m) where- gen = GenT $ modify succ >> get-instance MonadGen e m => MonadGen e (IdentityT m) where- gen = lift gen-instance MonadGen e m => MonadGen e (StateT s m) where- gen = lift gen-instance MonadGen e m => MonadGen e (ReaderT s m) where- gen = lift gen-instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m) where- gen = lift gen-instance MonadGen e m => MonadGen e (ListT m) where- gen = lift gen-instance MonadGen e m => MonadGen e (MaybeT m) where- gen = lift gen-instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m) where- gen = lift gen+#if MIN_VERSION_mtl(2, 2, 1)+#else+instance MonadError e m => MonadError e (GenT e m) where+ throwError = GenT . throwError+ catchError m h = GenT $ catchError (unGenT m) (unGenT . h)+#endif -runGenT :: Monad m => e -> GenT e m a -> m a-runGenT e = flip evalStateT e . unGenT+-- | Run a @GenT@ computation starting from the value+-- @toEnum 0@+runGenT :: (Enum e, Monad m) => GenT e m a -> m a+runGenT = runGenTWith (toEnum 0) -runGen :: e -> Gen e a -> a-runGen e = runIdentity . runGenT e+-- | Run a @Gen@ computation starting from the value+-- @toEnum 0@+runGen :: Enum e => Gen e a -> a+runGen = runGenWith (toEnum 0) --- | A shortcut for the common case where we want fresh--- `Integer`s.-runGenTInt :: Monad m => GenT Integer m a -> m a-runGenTInt = runGenT 0+-- | Run a @GenT@ computation starting from a specific value @e@.+runGenTWith :: Monad m => e -> GenT e m a -> m a+runGenTWith e = flip evalStateT e . unGenT -runGenInt :: Gen Integer a -> a-runGenInt = runIdentity . runGenTInt +-- | Run a @Gen@ computation starting from a specific value @e@.+runGenWith :: e -> Gen e a -> a+runGenWith e = runIdentity . runGenTWith e
+ src/Control/Monad/Gen/Class.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE CPP #-}+module Control.Monad.Gen.Class where+-- Import the non-depricated one+#if MIN_VERSION_mtl(2, 2, 1)+import Control.Monad.Except+#else+import Control.Monad.Trans.Error+#endif++import Control.Monad.Cont+import Control.Monad.List+import Control.Monad.RWS+import Control.Monad.Reader+import Control.Monad.State+import qualified Control.Monad.State.Strict as SS+import Control.Monad.Trans.Identity+import Control.Monad.Trans.Maybe+import Control.Monad.Writer+import qualified Control.Monad.Writer.Strict as SW++-- | The MTL style class for generating fresh values+class Monad m => MonadGen e m | m -> e where+ -- | Generate a fresh value @e@, @gen@ should never produce the+ -- same value within a monadic computation.+ gen :: m e++instance MonadGen e m => MonadGen e (IdentityT m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (StateT s m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (ReaderT s m) where+ gen = lift gen+instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (ListT m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (MaybeT m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (ContT r m) where+ gen = lift gen+instance (Monoid w, MonadGen e m) => MonadGen e (RWST r w s m) where+ gen = lift gen+instance MonadGen e m => MonadGen e (SS.StateT s m) where+ gen = lift gen+instance (Monoid w, MonadGen e m) => MonadGen e (SW.WriterT w m) where+ gen = lift gen++#if MIN_VERSION_mtl(2, 2, 1)+instance (MonadGen e m) => MonadGen e (ExceptT e m) where+ gen = lift gen+#else+instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m) where+ gen = lift gen+#endif