packages feed

phantom-state 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+173/−79 lines, 4 filesdep +criteriondep +phantom-statedep +vectordep ~transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: criterion, phantom-state, vector

Dependency ranges changed: transformers

API changes (from Hackage documentation)

- Control.Monad.PhantomState: PhantomStateT :: (s -> m s) -> PhantomStateT s m a
- Control.Monad.PhantomState: changeState :: Applicative m => (s -> s) -> PhantomStateT s m ()
- Control.Monad.PhantomState: instance Functor (PhantomStateT s m)
- Control.Monad.PhantomState: instance Monad m => Applicative (PhantomStateT s m)
- Control.Monad.PhantomState: instance Monad m => Monad (PhantomStateT s m)
- Control.Monad.PhantomState: instance MonadTrans (PhantomStateT s)
- Control.Monad.PhantomState: newtype PhantomStateT s m a
- Control.Monad.PhantomState: runPhantomState :: PhantomState s a -> s -> s
- Control.Monad.PhantomState: runPhantomStateT :: PhantomStateT s m a -> s -> m s
- Control.Monad.PhantomState: type PhantomState s a = PhantomStateT s Identity a
- Control.Monad.PhantomState: useState :: Applicative m => (s -> m a) -> PhantomStateT s m ()
+ Control.Applicative.PhantomState: changeState :: Applicative m => (s -> s) -> PhantomStateT s m ()
+ Control.Applicative.PhantomState: data PhantomStateT s m a
+ Control.Applicative.PhantomState: instance Functor (PhantomStateT s m)
+ Control.Applicative.PhantomState: instance Monad m => Applicative (PhantomStateT s m)
+ Control.Applicative.PhantomState: runPhantomState :: PhantomState s a -> s -> s
+ Control.Applicative.PhantomState: runPhantomStateT :: PhantomStateT s m a -> s -> m s
+ Control.Applicative.PhantomState: type PhantomState s = PhantomStateT s Identity
+ Control.Applicative.PhantomState: useAndChangeState :: (s -> m s) -> PhantomStateT s m ()
+ Control.Applicative.PhantomState: useState :: Applicative m => (s -> m a) -> PhantomStateT s m ()

Files

+ Control/Applicative/PhantomState.hs view
@@ -0,0 +1,100 @@++-- | Phantom State Transformer type and functions.+module Control.Applicative.PhantomState (+    PhantomStateT+  , PhantomState+  , useState+  , changeState+  , useAndChangeState+  , runPhantomStateT+  , runPhantomState+  ) where++import Control.Applicative+import Data.Functor.Identity++-- | The Phantom State Transformer is like the+--   State Monad Transformer, but it does not hold+--   any value. Therefore, it automatically discards+--   the result of any computation. Only changes in+--   the state and effects will remain. This transformer+--   produces a new 'Applicative' functor from any 'Monad'.+--   The primitive operations in this functor are:+--+-- * 'useState': Performs effects. State is unchanged.+-- * 'changeState': Changes state. No effect is performed.+-- * 'useAndChangeState': Changes state and performs effects.+--+--   Although 'useState' and 'changeState' are defined in+--   terms of 'useAndChangeState':+--+-- >    useState f = useAndChangeState (\s -> f s *> pure s)+-- > changeState f = useAndChangeState (pure . f)+--+--   So 'useAndChangeState' is the only actual primitive.+--+--   Use 'runPhantomStateT' (or 'runPhantomState') to get+--   the result of a phantom state computation.+--+newtype PhantomStateT s m a = PhantomStateT (s -> m s)++-- | Type synonym of 'PhantomStateT' where the underlying 'Monad' is the 'Identity' monad.+type PhantomState s = PhantomStateT s Identity++-- | Perform an applicative action using the current state, leaving+--   the state unchanged. The result will be discarded, so only the+--   effect will remain.+useState :: Applicative m => (s -> m a) -> PhantomStateT s m ()+{-# INLINE useState #-}+useState f = useAndChangeState $ \s -> f s *> pure s++-- | Modify the state using a pure function. No effect will be produced,+--   only the state will be modified.+changeState :: Applicative m => (s -> s) -> PhantomStateT s m ()+{-# INLINE changeState #-}+changeState f = useAndChangeState $ \s -> pure (f s)++-- | Combination of 'useState' and 'changeState'. It allows you to change the state while+--   performing any effects. The new state will be the result of applying the argument+--   function to the old state. The following equations hold:+--+-- >    useState f *> changeState g }+-- >                                } = useAndChangeState (\s -> f s *> g s)+-- > changeState g *>    useState f }+--+useAndChangeState :: (s -> m s) -> PhantomStateT s m ()+{-# INLINE useAndChangeState #-}+useAndChangeState = PhantomStateT++-- | Perform a phantom state computation by setting an initial state+--   and running all the actions from there.+runPhantomStateT :: PhantomStateT s m a -- ^ Phantom state computation+                 -> s -- ^ Initial state+                 -> m s -- ^ Final result+{-# INLINE runPhantomStateT #-}+runPhantomStateT (PhantomStateT f) x = f x++-- | Specialized version of 'runPhantomStateT' where the underlying+--   'Monad' is the 'Identity' monad.+runPhantomState :: PhantomState s a -- ^ Phantom state computation+                -> s -- ^ Initial state+                -> s -- ^ Final result+{-# INLINE runPhantomState #-}+runPhantomState f = runIdentity . runPhantomStateT f++-- Instances++instance Functor (PhantomStateT s m) where+  {-# INLINE fmap #-}+  fmap _ (PhantomStateT f) = PhantomStateT f++instance Monad m => Applicative (PhantomStateT s m) where+  {-# INLINE pure #-}+  pure _ = PhantomStateT return+  {-# INLINE (<*>) #-}+  PhantomStateT f <*> PhantomStateT g = PhantomStateT (\x -> f x >>= g)+  {-# INLINE  (*>) #-}+  PhantomStateT f  *> PhantomStateT g = PhantomStateT (\x -> f x >>= g)+  {-# INLINE (<*) #-}+  PhantomStateT f <*  PhantomStateT g = PhantomStateT (\x -> f x >>= g)+
− Control/Monad/PhantomState.hs
@@ -1,77 +0,0 @@---- | Phantom Monad State Transformer constructor and functions.-module Control.Monad.PhantomState (-    PhantomStateT (..)-  , PhantomState-  , useState-  , changeState-  , runPhantomStateT-  , runPhantomState-  ) where--import Control.Applicative-import Control.Monad.Trans.Class-import Data.Functor.Identity---- | The Phantom State Monad Transformer is like the---   State Monad Transformer, but it does not hold---   any value.-newtype PhantomStateT s m a = PhantomStateT (s -> m s)---- | Type synonym of 'PhantomStateT' where the underlying 'Monad' is the 'Identity' monad.-type PhantomState s a = PhantomStateT s Identity a---- | Perform an applicative action using the current state, leaving---   the state unchanged.-useState :: Applicative m => (s -> m a) -> PhantomStateT s m ()-{-# INLINE useState #-}-useState f = PhantomStateT $ \x -> f x *> pure x---- | Modify the state using a pure function.-changeState :: Applicative m => (s -> s) -> PhantomStateT s m ()-{-# INLINE changeState #-}-changeState f = PhantomStateT $ pure . f---- | Perform a phantom state computation by setting an initial state---   and running all the actions from there.-runPhantomStateT :: PhantomStateT s m a -- ^ Phantom state computation-                 -> s -- ^ Initial state-                 -> m s -- ^ Final result-{-# INLINE runPhantomStateT #-}-runPhantomStateT (PhantomStateT f) x = f x---- | Specialized version of 'runPhantomStateT' where the underlying---   'Monad' is the 'Identity' monad.-runPhantomState :: PhantomState s a -- ^ Phantom state computation-                -> s -- ^ Initial state-                -> s -- ^ Final result-{-# INLINE runPhantomState #-}-runPhantomState f = runIdentity . runPhantomStateT f---- Instances--instance Functor (PhantomStateT s m) where-  {-# INLINE fmap #-}-  fmap _ (PhantomStateT f) = PhantomStateT f--instance Monad m => Applicative (PhantomStateT s m) where-  {-# INLINE pure #-}-  pure _ = PhantomStateT return-  {-# INLINE (<*>) #-}-  PhantomStateT f <*> PhantomStateT g = PhantomStateT (\x -> f x >>= g)-  {-# INLINE  (*>) #-}-  PhantomStateT f  *> PhantomStateT g = PhantomStateT (\x -> f x >>= g)-  {-# INLINE (<*) #-}-  PhantomStateT f <*  PhantomStateT g = PhantomStateT (\x -> f x >>= g)--instance Monad m => Monad (PhantomStateT s m) where-  {-# INLINE return #-}-  return = pure-  {-# INLINE (>>=) #-}-  x >>= f = x *> f undefined-  {-# INLINE (>>) #-}-  (>>) = (*>)--instance MonadTrans (PhantomStateT s) where-  {-# INLINE lift #-}-  lift m = PhantomStateT (\x -> m >> return x)
+ bench/Main.hs view
@@ -0,0 +1,54 @@++import Criterion.Main++-- vectors+import qualified Data.Vector.Unboxed as V+import qualified Data.Vector.Unboxed.Mutable as MV++-- functors+import Control.Applicative+import Control.Monad (mapM_,replicateM)+import Data.Foldable (sequenceA_)+import Control.Monad.Trans.Class+-- state+import Control.Monad.Trans.State++-- phantom-state+import Control.Applicative.PhantomState++createVector1 :: Int -> V.Vector Int+createVector1 n = V.create $ do+  v <- MV.unsafeNew n+  let step = do +        i <- get+        lift $ MV.write v i i+        put (i+1)+  execStateT (replicateM n step) 0+  return v++replicateA_ :: Applicative f => Int -> f a -> f ()+replicateA_ n f = sequenceA_ (replicate n f)++createVector2 :: Int -> V.Vector Int+createVector2 n = V.create $ do+  v <- MV.unsafeNew n+  let step = useState (\i -> MV.write v i i)+          *> changeState (+1)+  runPhantomStateT (replicateA_ n step) 0+  return v++createVector3 :: Int -> V.Vector Int+createVector3 n = V.create $ do+  v <- MV.unsafeNew n+  mapM_ (\i -> MV.write v i i) [0..n-1]+  return v++main :: IO ()+main = defaultMain+  [ bgroup "vector"+      [ bench "generate" $ nf (\i -> V.generate i id) 10000+      , bench "state" $ nf createVector1 10000+      , bench "phantom-state" $ nf createVector2 10000+      , bench "mapM_" $ nf createVector3 10000+        ]+  ]
phantom-state.cabal view
@@ -1,5 +1,5 @@ name:                phantom-state-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Phantom State Monad Transformer. Like State Monad, but without values. description:         A monad transformer that mimics the State Monad Transformer from the                      <http://hackage.haskell.org/package/transformers transformers> package,@@ -10,13 +10,30 @@ license-file:        LICENSE author:              Daniel Díaz maintainer:          dhelta.diaz@gmail.com+bug-reports:         https://github.com/Daniel-Diaz/phantom-state/issues category:            Control build-type:          Simple cabal-version:       >=1.10 +Source-repository head+  type: git+  location: git://github.com/Daniel-Diaz/phantom-state.git+ library-  exposed-modules:     Control.Monad.PhantomState+  exposed-modules:     Control.Applicative.PhantomState   build-depends:       base == 4.*                      , transformers >= 0.3 && < 0.5   default-language:    Haskell2010   ghc-options: -O2 -Wall++benchmark phantom-state-bench+  default-language: Haskell2010+  type: exitcode-stdio-1.0+  hs-source-dirs: bench+  main-is: Main.hs+  build-depends: base == 4.*+               , criterion+               , vector+               , phantom-state+               , transformers+  ghc-options: -O2