mtl-unleashed (empty) → 0.2
raw patch · 4 files changed
+142/−0 lines, 4 filesdep +basedep +mtlsetup-changed
Dependencies added: base, mtl
Files
- Control/Monad/Readers.hs +54/−0
- Control/Monad/States.hs +54/−0
- Setup.hs +3/−0
- mtl-unleashed.cabal +31/−0
+ Control/Monad/Readers.hs view
@@ -0,0 +1,54 @@+-- | MonadState without the function dependency @m -> s@.+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Control.Monad.Readers+ ( module Control.Monad.Reader+ , MonadReaders(ask, local)+ , asks+ ) where++import Control.Monad.Reader hiding (MonadReader(ask, local, reader), asks)+import qualified Control.Monad.Reader as MTL (ask, local)+import Control.Monad.State (StateT, get, evalStateT)+import Control.Monad.Writer (runWriterT, WriterT)++-- | Version of MonadReader modified to remove the functional dependency.+class Monad m => MonadReaders r m where+ ask :: m r+ ask = reader id++ local :: (r -> r) -> m a -> m a++ reader :: (r -> a) -> m a+ reader f = do+ r <- ask+ return (f r)++instance Monad m => MonadReaders r (ReaderT r m) where+ ask = MTL.ask+ local = MTL.local++instance (Monad m, MonadReaders r m) => MonadReaders r (StateT s m) where+ ask = lift ask+ local f action = get >>= lift . local f . evalStateT action++instance (Monad m, Monoid w, MonadReaders r m) => MonadReaders r (WriterT w m) where+ ask = lift ask+ local f action = lift (local f (runWriterT action >>= return . fst))++{-+-- Here is how you create a MonadReaders instance for a type that is+-- nested inside another MonadReaders instances. You need to declare+-- this with the exact parent type (here Bar) or you will get+-- overlapping instances.++instance (Monad m, MonadReaders Foo m) => MonadReaders Foo (ReaderT Bar m) where+ ask = lift ask+ local f action = MTL.ask >>= runReaderT (local f (lift action))+-}++-- | Retrieves a function of the current environment.+asks :: MonadReaders r m+ => (r -> a) -- ^ The selector function to apply to the environment.+ -> m a+asks = reader
+ Control/Monad/States.hs view
@@ -0,0 +1,54 @@+-- | MonadState without the function dependency @m -> s@.+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Control.Monad.States+ ( module Control.Monad.State+ , MonadStates(get, put)+ , modify+ , modify'+ , gets+ ) where++import Control.Monad.Reader+import Control.Monad.State hiding (MonadState(get, put, state), modify, modify', gets)+import qualified Control.Monad.State as MTL (get, put)+import Control.Monad.Writer (WriterT)++-- | Copy of 'Control.Monad.State.MonadState' with functional dependency m -> s removed.+class Monad m => MonadStates s m where+ get :: m s+ get = state (\s -> (s, s))+ put :: s -> m ()+ put s = state (\_ -> ((), s))+ state :: (s -> (a, s)) -> m a+ state f = do+ s <- get+ let ~(a, s') = f s+ put s'+ return a++-- | Copy of 'Control.Monad.State.mondify'+modify :: MonadStates s m => (s -> s) -> m ()+modify f = state (\s -> ((), f s))++-- | Copy of 'Control.Monad.State.modify''+modify' :: MonadStates s m => (s -> s) -> m ()+modify' f = state (\s -> let s' = f s in s' `seq` ((), s'))++-- | Copy of 'Control.Monad.State.gets'+gets :: MonadStates s m => (s -> a) -> m a+gets f = do+ s <- get+ return (f s)++instance Monad m => MonadStates s (StateT s m) where+ get = MTL.get+ put = MTL.put++instance (Monad m, MonadStates s m) => MonadStates s (ReaderT r m) where+ get = lift get+ put s = lift $ put s++instance (Monad m, Monoid w, MonadStates s m) => MonadStates s (WriterT w m) where+ get = lift get+ put = lift . put
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple+main :: IO ()+main = defaultMain
+ mtl-unleashed.cabal view
@@ -0,0 +1,31 @@+name: mtl-unleashed+version: 0.2+cabal-version: >= 1.10+build-type: Simple+license: BSD3+category: Control+author: David Fox+copyright: (c) 2015 David Fox+maintainer: David Fox <dsf@seereason.com>+homepage: https://github.com/seereason/mtl-unleashed+bug-reports: https://github.com/seereason/mtl-unleashed/issues+stability: experimental+synopsis: MTL classes without the functional dependency+description:+ Classes MonadState and MonadReader without the functional+ dependency from the monad to the contained type. This allows+ more flexibility to extract bits and pieces of state based on+ type, but increases ambiguities that need to be resolved with+ extra type signatures.++library+ build-depends: base < 5, mtl+ ghc-options: -Wall -O2+ exposed-modules:+ Control.Monad.Readers+ Control.Monad.States+ default-language: Haskell2010++source-repository head+ type: git+ location: git://github.com/seereason/mtl-unleashed.git