transformers 0.1.4.0 → 0.2.0.0
raw patch · 21 files changed
+591/−307 lines, 21 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Control.Monad.Identity: Identity :: a -> Identity a
- Control.Monad.Identity: instance Applicative Identity
- Control.Monad.Identity: instance Functor Identity
- Control.Monad.Identity: instance Monad Identity
- Control.Monad.Identity: instance MonadFix Identity
- Control.Monad.Identity: newtype Identity a
- Control.Monad.Identity: runIdentity :: Identity a -> a
- Control.Monad.Trans: class (Monad m) => MonadIO m
- Control.Monad.Trans: class MonadTrans t
- Control.Monad.Trans: instance MonadIO IO
- Control.Monad.Trans: lift :: (MonadTrans t, Monad m) => m a -> t m a
- Control.Monad.Trans: liftIO :: (MonadIO m) => IO a -> m a
- Control.Monad.Trans.Cont: instance (Monad m) => Monad (ContT r m)
+ Control.Monad.IO.Class: class (Monad m) => MonadIO m
+ Control.Monad.IO.Class: instance MonadIO IO
+ Control.Monad.IO.Class: liftIO :: (MonadIO m) => IO a -> m a
+ Control.Monad.Trans.Class: class MonadTrans t
+ Control.Monad.Trans.Class: lift :: (MonadTrans t, Monad m) => m a -> t m a
+ Control.Monad.Trans.Cont: instance Monad (ContT r m)
+ Data.Functor.Compose: Compose :: f (g a) -> Compose f g a
+ Data.Functor.Compose: getCompose :: Compose f g a -> f (g a)
+ Data.Functor.Compose: instance (Applicative f, Applicative g) => Applicative (Compose f g)
+ Data.Functor.Compose: instance (Foldable f, Foldable g) => Foldable (Compose f g)
+ Data.Functor.Compose: instance (Functor f, Functor g) => Functor (Compose f g)
+ Data.Functor.Compose: instance (Traversable f, Traversable g) => Traversable (Compose f g)
+ Data.Functor.Compose: newtype Compose f g a
+ Data.Functor.Constant: Constant :: a -> Constant a b
+ Data.Functor.Constant: getConstant :: Constant a b -> a
+ Data.Functor.Constant: instance (Monoid a) => Applicative (Constant a)
+ Data.Functor.Constant: instance Foldable (Constant a)
+ Data.Functor.Constant: instance Functor (Constant a)
+ Data.Functor.Constant: instance Traversable (Constant a)
+ Data.Functor.Constant: newtype Constant a b
+ Data.Functor.Identity: Identity :: a -> Identity a
+ Data.Functor.Identity: instance Applicative Identity
+ Data.Functor.Identity: instance Foldable Identity
+ Data.Functor.Identity: instance Functor Identity
+ Data.Functor.Identity: instance Monad Identity
+ Data.Functor.Identity: instance MonadFix Identity
+ Data.Functor.Identity: instance Traversable Identity
+ Data.Functor.Identity: newtype Identity a
+ Data.Functor.Identity: runIdentity :: Identity a -> a
Files
- Control/Monad/IO/Class.hs +37/−0
- Control/Monad/Identity.hs +0/−91
- Control/Monad/Trans.hs +0/−136
- Control/Monad/Trans/Class.hs +123/−0
- Control/Monad/Trans/Cont.hs +4/−3
- Control/Monad/Trans/Error.hs +15/−22
- Control/Monad/Trans/Identity.hs +6/−2
- Control/Monad/Trans/List.hs +3/−1
- Control/Monad/Trans/Maybe.hs +3/−1
- Control/Monad/Trans/RWS.hs +1/−1
- Control/Monad/Trans/RWS/Lazy.hs +4/−2
- Control/Monad/Trans/RWS/Strict.hs +4/−2
- Control/Monad/Trans/Reader.hs +6/−2
- Control/Monad/Trans/State/Lazy.hs +137/−27
- Control/Monad/Trans/State/Strict.hs +105/−6
- Control/Monad/Trans/Writer/Lazy.hs +4/−2
- Control/Monad/Trans/Writer/Strict.hs +4/−2
- Data/Functor/Compose.hs +34/−0
- Data/Functor/Constant.hs +35/−0
- Data/Functor/Identity.hs +57/−0
- transformers.cabal +9/−7
+ Control/Monad/IO/Class.hs view
@@ -0,0 +1,37 @@+-----------------------------------------------------------------------------+-- |+-- Module : Control.Monad.IO.Class+-- Copyright : (c) Andy Gill 2001,+-- (c) Oregon Graduate Institute of Science and Technology, 2001+-- License : BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- Class of monads based on @IO@.+-----------------------------------------------------------------------------++module Control.Monad.IO.Class (+ MonadIO(..)+ ) where++import System.IO (IO)++-- | Monads in which 'IO' computations may be embedded.+-- Any monad built by applying a sequence of monad transformers to the+-- 'IO' monad will be an instance of this class.+--+-- Instances should satisfy the following laws, which state that 'liftIO'+-- is a transformer of monads:+--+-- * @'liftIO' . 'return' = 'return'@+--+-- * @'liftIO' (m >>= f) = 'liftIO' m >>= ('liftIO' . f)@++class (Monad m) => MonadIO m where+ -- | Lift a computation from the 'IO' monad.+ liftIO :: IO a -> m a++instance MonadIO IO where+ liftIO = id
− Control/Monad/Identity.hs
@@ -1,91 +0,0 @@-{- |-Module : Control.Monad.Identity-Copyright : (c) Andy Gill 2001,- (c) Oregon Graduate Institute of Science and Technology 2001,- (c) Jeff Newbern 2003-2006,- (c) Andriy Palamarchuk 2006-License : BSD-style (see the file libraries/base/LICENSE)--Maintainer : libraries@haskell.org-Stability : experimental-Portability : portable--[Computation type:] Simple function application.--[Binding strategy:] The bound function is applied to the input value.-@'Identity' x >>= f == 'Identity' (f x)@--[Useful for:] Monads can be derived from monad transformers applied to the-'Identity' monad.--[Zero and plus:] None.--[Example type:] @'Identity' a@--The @Identity@ monad is a monad that does not embody any computational strategy.-It simply applies the bound function to its input without any modification.-Computationally, there is no reason to use the @Identity@ monad-instead of the much simpler act of simply applying functions to their arguments.-The purpose of the @Identity@ monad is its fundamental role in the theory-of monad transformers.-Any monad transformer applied to the @Identity@ monad yields a non-transformer-version of that monad.--}--module Control.Monad.Identity (- Identity(..),- ) where--import Control.Applicative-import Control.Monad-import Control.Monad.Fix--{- | Identity wrapper.-Abstraction for wrapping up a object.-If you have an monadic function, say:--> example :: Int -> Identity Int-> example x = return (x*x)-- you can \"run\" it, using--> Main> runIdentity (example 42)-> 1764 :: Int--A typical use of the Identity monad is to derive a monad-from a monad transformer.--@--- derive the 'Control.Monad.State.State' monad using the 'Control.Monad.State.StateT' monad transformer-type 'Control.Monad.State.State' s a = 'Control.Monad.State.StateT' s 'Identity' a-@--The @'runIdentity'@ label is used in the type definition because it follows-a style of monad definition that explicitly represents monad values as-computations. In this style, a monadic computation is built up using the monadic-operators and then the value of the computation is extracted-using the @run******@ function.-Because the @Identity@ monad does not do any computation, its definition-is trivial.-For a better example of this style of monad,-see the @'Control.Monad.State.State'@ monad.--}--newtype Identity a = Identity { runIdentity :: a }---- ------------------------------------------------------------------------------ Identity instances for Functor and Monad--instance Functor Identity where- fmap f m = Identity (f (runIdentity m))--instance Applicative Identity where- pure a = Identity a- Identity f <*> Identity x = Identity (f x)--instance Monad Identity where- return a = Identity a- m >>= k = k (runIdentity m)--instance MonadFix Identity where- mfix f = Identity (fix (runIdentity . f))
− Control/Monad/Trans.hs
@@ -1,136 +0,0 @@--------------------------------------------------------------------------------- |--- Module : Control.Monad.Trans--- Copyright : (c) Andy Gill 2001,--- (c) Oregon Graduate Institute of Science and Technology, 2001--- License : BSD-style (see the file libraries/base/LICENSE)------ Maintainer : libraries@haskell.org--- Stability : experimental--- Portability : portable------ Classes for monad transformers.------ A monad transformer makes new monad out of an existing monad, such--- that computations of the old monad may be embedded in the new one.--- To construct a monad with a desired set of features, one typically--- starts with a base monad, such as @Identity@, @[]@ or 'IO', and--- applies a sequence of monad transformers.------ Most monad transformer modules include the special case of applying the--- transformer to @Identity@. For example, @State s@ is an abbreviation--- for @StateT s Identity@.------ Each monad transformer also comes with an operation @run@/XXX/ to--- unwrap the transformer, exposing a computation of the inner monad.--------------------------------------------------------------------------------module Control.Monad.Trans (- -- * Transformer classes- MonadTrans(..),- MonadIO(..),-- -- * Examples- -- ** Parsing- -- $example1-- -- ** Parsing and counting- -- $example2- ) where--import System.IO---- | The class of monad transformers. Instances should satisfy the laws------ * @'lift' . 'return' = 'return'@------ * @'lift' (m >>= f) = 'lift' m >>= ('lift' . f)@--class MonadTrans t where- -- | Lift a computation from the argument monad to the constructed monad.- lift :: Monad m => m a -> t m a---- | Monads in which 'IO' computations may be embedded.--- Any monad built by applying a sequence of monad transformers to the--- 'IO' monad will be an instance of this class.-class (Monad m) => MonadIO m where- -- | Lift a computation from the 'IO' monad.- liftIO :: IO a -> m a--instance MonadIO IO where- liftIO = id--{- $example1--One might define a parsing monad by adding a state, consisting of the-'String' remaining to be parsed, to the @[]@ monad, which provides-non-determinism:--> import Control.Monad.Trans.State->-> type Parser = StateT String []--Then @Parser@ is an instance of @MonadPlus@: monadic sequencing implements-concatenation of parsers, while @mplus@ provides choice.-To use parsers, we need a primitive to run a constructed parser on an-input string:--> runParser :: Parser a -> String -> [a]-> runParser p s = [x | (x, "") <- runStateT p s]--Finally, we need a primitive parser that matches a single character,-from which arbitrarily complex parsers may be constructed:--> item :: Parser Char-> item = do-> c:cs <- get-> put cs-> return c--In this example we use the operations @get@ and @put@ from-"Control.Monad.Trans.State", which are defined only for monads that are-applications of @StateT@. Alternatively one could use monad classes-from other packages, which contain methods @get@ and @put@ with types-generalized over all suitable monads.--}--{- $example2--We can define a parser that also counts by adding a @WriterT@ transformer:--> import Control.Monad.Trans-> import Control.Monad.Trans.State-> import Control.Monad.Trans.Writer-> import Data.Monoid->-> type Parser = WriterT (Sum Int) (StateT String [])--The function that applies a parser must now unwrap each of the monad-transformers in turn:--> runParser :: Parser a -> String -> [(a, Int)]-> runParser p s = [(x, n) | ((x, Sum n), "") <- runStateT (runWriterT p) s]--To define @item@ parser, we need to lift the @StateT@ operations through-the @WriterT@ transformers.--> item :: Parser Char-> item = do-> c:cs <- lift get-> lift (put cs)-> return c--In this case, we were able to do this with 'lift', but operations with-more complex types require special lifting functions, which are provided-by monad transformers for which they can be implemented. If you use-one of packages of monad classes, this lifting is handled automatically-by the instances of the classes, and you need only use the generalized-methods @get@ and @put@.--We can also define a primitive using the Writer:--> tick :: Parser ()-> tick = tell (Sum 1)--Then the parser will keep track of how many @tick@s it executes.--}
+ Control/Monad/Trans/Class.hs view
@@ -0,0 +1,123 @@+-----------------------------------------------------------------------------+-- |+-- Module : Control.Monad.Trans.Class+-- Copyright : (c) Andy Gill 2001,+-- (c) Oregon Graduate Institute of Science and Technology, 2001+-- License : BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- Classes for monad transformers.+--+-- A monad transformer makes new monad out of an existing monad, such+-- that computations of the old monad may be embedded in the new one.+-- To construct a monad with a desired set of features, one typically+-- starts with a base monad, such as @Identity@, @[]@ or 'IO', and+-- applies a sequence of monad transformers.+--+-- Most monad transformer modules include the special case of applying the+-- transformer to @Identity@. For example, @State s@ is an abbreviation+-- for @StateT s Identity@.+--+-- Each monad transformer also comes with an operation @run@/XXX/ to+-- unwrap the transformer, exposing a computation of the inner monad.+-----------------------------------------------------------------------------++module Control.Monad.Trans.Class (+ -- * Transformer class+ MonadTrans(..)++ -- * Examples+ -- ** Parsing+ -- $example1++ -- ** Parsing and counting+ -- $example2+ ) where++-- | The class of monad transformers. Instances should satisfy the+-- following laws, which state that 'lift' is a transformer of monads:+--+-- * @'lift' . 'return' = 'return'@+--+-- * @'lift' (m >>= f) = 'lift' m >>= ('lift' . f)@++class MonadTrans t where+ -- | Lift a computation from the argument monad to the constructed monad.+ lift :: Monad m => m a -> t m a++{- $example1++One might define a parsing monad by adding a state (the 'String' remaining+to be parsed) to the @[]@ monad, which provides non-determinism:++> import Control.Monad.Trans.State+>+> type Parser = StateT String []++Then @Parser@ is an instance of @MonadPlus@: monadic sequencing implements+concatenation of parsers, while @mplus@ provides choice.+To use parsers, we need a primitive to run a constructed parser on an+input string:++> runParser :: Parser a -> String -> [a]+> runParser p s = [x | (x, "") <- runStateT p s]++Finally, we need a primitive parser that matches a single character,+from which arbitrarily complex parsers may be constructed:++> item :: Parser Char+> item = do+> c:cs <- get+> put cs+> return c++In this example we use the operations @get@ and @put@ from+"Control.Monad.Trans.State", which are defined only for monads that are+applications of @StateT@. Alternatively one could use monad classes+from other packages, which contain methods @get@ and @put@ with types+generalized over all suitable monads.+-}++{- $example2++We can define a parser that also counts by adding a @WriterT@ transformer:++> import Control.Monad.Trans.Class+> import Control.Monad.Trans.State+> import Control.Monad.Trans.Writer+> import Data.Monoid+>+> type Parser = WriterT (Sum Int) (StateT String [])++The function that applies a parser must now unwrap each of the monad+transformers in turn:++> runParser :: Parser a -> String -> [(a, Int)]+> runParser p s = [(x, n) | ((x, Sum n), "") <- runStateT (runWriterT p) s]++To define @item@ parser, we need to lift the @StateT@ operations through+the @WriterT@ transformers.++> item :: Parser Char+> item = do+> c:cs <- lift get+> lift (put cs)+> return c++In this case, we were able to do this with 'lift', but operations with+more complex types require special lifting functions, which are provided+by monad transformers for which they can be implemented. If you use+one of packages of monad classes, this lifting is handled automatically+by the instances of the classes, and you need only use the generalized+methods @get@ and @put@.++We can also define a primitive using the Writer:++> tick :: Parser ()+> tick = tell (Sum 1)++Then the parser will keep track of how many @tick@s it executes.+-}
Control/Monad/Trans/Cont.hs view
@@ -28,8 +28,9 @@ liftLocal, ) where -import Control.Monad.Identity-import Control.Monad.Trans+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity import Control.Applicative import Control.Monad@@ -81,7 +82,7 @@ pure a = ContT ($ a) f <*> v = ContT $ \ k -> runContT f $ \ g -> runContT v (k . g) -instance (Monad m) => Monad (ContT r m) where+instance Monad (ContT r m) where return a = ContT ($ a) m >>= k = ContT $ \c -> runContT m (\a -> runContT (k a) c)
Control/Monad/Trans/Error.hs view
@@ -9,21 +9,12 @@ Stability : experimental Portability : portable -[Computation type:] Computations which may fail or throw exceptions.--[Binding strategy:] Failure records information about the cause\/location-of the failure. Failure values bypass the bound function,-other values are used as inputs to the bound function.--[Useful for:] Building computations from sequences of functions that may fail-or using exception handling to structure error handling.--[Zero and plus:] Zero is represented by an empty error and the plus operation-executes its second argument if the first fails.--[Example type:] @'Data.Either' String a@+This monad transformer adds the ability to fail or throw exceptions+to a monad. -The Error monad (also called the Exception monad).+A sequence of actions succeeds, producing a value, only if all the actions+in the sequence are successful. If one fails with an error, the rest+of the sequence is skipped and the composite action fails with that error. -} module Control.Monad.Trans.Error (@@ -40,12 +31,13 @@ liftPass, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+ import Control.Applicative import Control.Exception (IOException) import Control.Monad import Control.Monad.Fix-import Control.Monad.Trans- import Control.Monad.Instances () import System.IO @@ -54,24 +46,25 @@ m `mplus` n = m `catch` \_ -> n -- | An exception to be thrown.--- An instance must redefine at least one of 'noMsg', 'strMsg'.+--+-- Minimal complete definition: 'noMsg' or 'strMsg'. class Error a where -- | Creates an exception without a message.- -- Default implementation is @'strMsg' \"\"@.+ -- The default implementation is @'strMsg' \"\"@. noMsg :: a -- | Creates an exception with a message.- -- Default implementation is 'noMsg'.+ -- The default implementation of @'strMsg' s@ is 'noMsg'. strMsg :: String -> a noMsg = strMsg "" strMsg _ = noMsg +instance Error IOException where+ strMsg = userError+ -- | A string can be thrown as an error. instance ErrorList a => Error [a] where strMsg = listMsg--instance Error IOException where- strMsg = userError -- | Workaround so that we can have a Haskell 98 instance @'Error' 'String'@. class ErrorList a where
Control/Monad/Trans/Identity.hs view
@@ -8,7 +8,9 @@ -- Stability : experimental -- Portability : portable ----- Declaration of the identity monad transformer.+-- The identity monad transformer.+--+-- This is useful for functions parameterized by a monad transformer. ----------------------------------------------------------------------------- module Control.Monad.Trans.Identity (@@ -22,8 +24,10 @@ import Control.Applicative import Control.Monad (MonadPlus(mzero, mplus))-import Control.Monad.Trans (MonadIO(liftIO), MonadTrans(lift))+import Control.Monad.IO.Class (MonadIO(liftIO))+import Control.Monad.Trans.Class (MonadTrans(lift)) +-- | The trivial monad transformer, which maps a monad to an equivalent monad. newtype IdentityT m a = IdentityT { runIdentityT :: m a } instance (Functor m) => Functor (IdentityT m) where
Control/Monad/Trans/List.hs view
@@ -22,9 +22,11 @@ liftCatch, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+ import Control.Applicative import Control.Monad-import Control.Monad.Trans -- | Parameterizable list monad, with an inner monad. --
Control/Monad/Trans/Maybe.hs view
@@ -22,9 +22,11 @@ liftPass, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+ import Control.Applicative import Control.Monad (MonadPlus(mzero, mplus), liftM, ap)-import Control.Monad.Trans (MonadIO(liftIO), MonadTrans(lift)) newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
Control/Monad/Trans/RWS.hs view
@@ -9,7 +9,7 @@ -- Stability : experimental -- Portability : portable ----- A monad transformer that combines 'ReaderT', 'WriterT' and 'State'.+-- A monad transformer that combines 'ReaderT', 'WriterT' and 'StateT'. -- This version is lazy; for a strict version, see -- "Control.Monad.Trans.RWS.Strict", which has the same interface. -----------------------------------------------------------------------------
Control/Monad/Trans/RWS/Lazy.hs view
@@ -48,11 +48,13 @@ liftCatch, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans import Data.Monoid type RWS r w s = RWST r w s Identity
Control/Monad/Trans/RWS/Strict.hs view
@@ -48,11 +48,13 @@ liftCatch, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans import Data.Monoid type RWS r w s = RWST r w s Identity
Control/Monad/Trans/Reader.hs view
@@ -11,6 +11,9 @@ -- -- Declaration of the 'ReaderT' monad transformer, which adds a static -- environment to a given monad.+--+-- If the computation is to modify the stored information, use+-- "Control.Monad.Trans.State" instead. ----------------------------------------------------------------------------- module Control.Monad.Trans.Reader (@@ -33,8 +36,9 @@ liftCatch, ) where -import Control.Monad.Identity-import Control.Monad.Trans+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity import Control.Applicative import Control.Monad
Control/Monad/Trans/State/Lazy.hs view
@@ -9,8 +9,15 @@ -- Stability : experimental -- Portability : portable ----- Lazy state monads.+-- Lazy state monads, passing an updateable state through a computation. --+-- Some computations may not require the full power if state transformers:+--+-- * For a read-only state, see "Control.Monad.Trans.Reader".+--+-- * To accumulate a value without using it on the way, see+-- "Control.Monad.Trans.Writer".+-- -- See below for examples. ----------------------------------------------------------------------------- @@ -40,42 +47,53 @@ liftCatch, liftListen, liftPass,+ -- * Examples+ -- $examples ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans -- ------------------------------------------------------------------------------ | A parameterizable state monad where /s/ is the type of the state--- to carry and /a/ is the type of the /return value/.+-- | A parameterizable state monad where @s@ is the type of the state+-- to carry. type State s = StateT s Identity -runState :: State s a -> s -> (a, s)-runState m = runIdentity . runStateT m--state :: (s -> (a, s)) -> State s a+-- | Construct a state monad computation from a function.+-- (The inverse of 'runState'.)+state :: (s -> (a, s)) -- ^pure state transformer+ -> State s a -- ^equivalent state-passing computation state f = StateT (Identity . f) --- |Evaluate this state monad with the given initial state,throwing--- away the final state. Very much like @fst@ composed with--- @runstate@.+-- | Unwrap a state monad computation as a function.+-- (The inverse of 'state'.)+runState :: State s a -- ^state-passing computation to execute+ -> s -- ^initial state+ -> (a, s) -- ^return value and final state+runState m = runIdentity . runStateT m -evalState :: State s a -- ^The state to evaluate- -> s -- ^An initial value- -> a -- ^The return value of the state application+-- | Evaluate a state computation with the given initial state+-- and return the final value, discarding the final state.+--+-- @'evalState' m s = 'fst' ('runState' m s)@+evalState :: State s a -- ^state-passing computation to execute+ -> s -- ^initial value+ -> a -- ^return value of the state computation evalState m s = fst (runState m s) --- |Execute this state and return the new state, throwing away the--- return value. Very much like @snd@ composed with--- @runstate@.--execState :: State s a -- ^The state to evaluate- -> s -- ^An initial value- -> s -- ^The new state+-- | Evaluate a state computation with the given initial state+-- and return the final state, discarding the final value.+--+-- @'execState' m s = 'snd' ('runState' m s)@+execState :: State s a -- ^state-passing computation to execute+ -> s -- ^initial value+ -> s -- ^final state execState m s = snd (runState m s) -- |Map a stateful computation from one (return value, state) pair to@@ -128,23 +146,37 @@ newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } --- |Similar to 'evalState'+-- | Evaluate a state computation with the given initial state+-- and return the final value, discarding the final state.+--+-- @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@ evalStateT :: (Monad m) => StateT s m a -> s -> m a evalStateT m s = do ~(a, _) <- runStateT m s return a --- |Similar to 'execState'+-- | Evaluate a state computation with the given initial state+-- and return the final state, discarding the final value.+--+-- @'execStateT' m s = 'liftM' 'snd' ('runStateT' m s)@ execStateT :: (Monad m) => StateT s m a -> s -> m s execStateT m s = do ~(_, s') <- runStateT m s return s' --- |Similar to 'mapState'+-- | Map a stateful computation from one (return value, state) pair to+-- another. For instance, to convert numberTree from a function that+-- returns a tree to a function that returns the sum of the numbered+-- tree (see the Examples section for numberTree and sumTree) you may+-- write:+--+-- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int+-- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab)) . numberTree+ mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b mapStateT f m = StateT $ f . runStateT m --- |Similar to 'withState'+-- | Apply this function to this state and return the resulting state. withStateT :: (s -> s) -> StateT s m a -> StateT s m a withStateT f m = StateT $ runStateT m . f @@ -182,9 +214,11 @@ instance (MonadIO m) => MonadIO (StateT s m) where liftIO = lift . liftIO +-- | Fetch the current value of the state within the monad. get :: (Monad m) => StateT s m s get = StateT $ \s -> return (s, s) +-- | @'put' s@ sets the state within the monad to @s@. put :: (Monad m) => s -> StateT s m () put s = StateT $ \_ -> return ((), s) @@ -198,7 +232,7 @@ s <- get put (f s) --- | Gets specific component of the state, using a projection function+-- | Get a specific component of the state, using a projection function -- supplied. gets :: (Monad m) => (s -> a) -> StateT s m a@@ -217,6 +251,7 @@ -- | In-situ lifting of a @callCC@ operation to the new monad. -- This version uses the current state on entering the continuation.+-- It does not satisfy the laws of a monad transformer. liftCallCC' :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) -> ((a -> StateT s m b) -> StateT s m a) -> StateT s m a liftCallCC' callCC f = StateT $ \s ->@@ -242,3 +277,78 @@ liftPass pass m = StateT $ \s -> pass $ do ~((a, f), s') <- runStateT m s return ((a, s'), f)++{- $examples++A function to increment a counter. Taken from the paper+/Generalising Monads to Arrows/, John+Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:++> tick :: State Int Int+> tick = do n <- get+> put (n+1)+> return n++Add one to the given number using the state monad:++> plusOne :: Int -> Int+> plusOne n = execState tick n++A contrived addition example. Works only with positive numbers:++> plus :: Int -> Int -> Int+> plus n x = execState (sequence $ replicate n tick) x++An example from /The Craft of Functional Programming/, Simon+Thompson (<http://www.cs.kent.ac.uk/people/staff/sjt/>),+Addison-Wesley 1999: \"Given an arbitrary tree, transform it to a+tree of integers in which the original elements are replaced by+natural numbers, starting from 0. The same element has to be+replaced by the same number at every occurrence, and when we meet+an as-yet-unvisited element we have to find a \'new\' number to match+it with:\"++> data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Eq)+> type Table a = [a]++> numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)+> numberTree Nil = return Nil+> numberTree (Node x t1 t2)+> = do num <- numberNode x+> nt1 <- numberTree t1+> nt2 <- numberTree t2+> return (Node num nt1 nt2)+> where+> numberNode :: Eq a => a -> State (Table a) Int+> numberNode x+> = do table <- get+> (newTable, newPos) <- return (nNode x table)+> put newTable+> return newPos+> nNode:: (Eq a) => a -> Table a -> (Table a, Int)+> nNode x table+> = case (findIndexInList (== x) table) of+> Nothing -> (table ++ [x], length table)+> Just i -> (table, i)+> findIndexInList :: (a -> Bool) -> [a] -> Maybe Int+> findIndexInList = findIndexInListHelp 0+> findIndexInListHelp _ _ [] = Nothing+> findIndexInListHelp count f (h:t)+> = if (f h)+> then Just count+> else findIndexInListHelp (count+1) f t++numTree applies numberTree with an initial state:++> numTree :: (Eq a) => Tree a -> Tree Int+> numTree t = evalState (numberTree t) []++> testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil+> numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil++sumTree is a little helper function that does not use the State monad:++> sumTree :: (Num a) => Tree a -> a+> sumTree Nil = 0+> sumTree (Node e t1 t2) = e + (sumTree t1) + (sumTree t2)+-}
Control/Monad/Trans/State/Strict.hs view
@@ -40,13 +40,17 @@ liftCatch, liftListen, liftPass,+ -- * Examples+ -- $examples ) where +import Data.Functor.Identity+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans -- --------------------------------------------------------------------------- -- | A parameterizable state monad where /s/ is the type of the state@@ -54,9 +58,13 @@ type State s = StateT s Identity +-- | Construct a state monad computation from a function.+-- (The inverse of 'runState'.) state :: (s -> (a, s)) -> State s a state f = StateT (Identity . f) +-- | Unwrap a state monad computation as a function.+-- (The inverse of 'state'.) runState :: State s a -> s -> (a, s) runState m = runIdentity . runStateT m @@ -128,23 +136,38 @@ newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } --- |Similar to 'evalState'+-- | Evaluate a state computation with the given initial state+-- and return the final value, discarding the final state.+--+-- @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@+ evalStateT :: (Monad m) => StateT s m a -> s -> m a evalStateT m s = do (a, _) <- runStateT m s return a --- |Similar to 'execState'+-- | Evaluate a state computation with the given initial state+-- and return the final state, discarding the final value.+--+-- @'execStateT' m s = 'liftM' 'snd' ('runStateT' m s)@ execStateT :: (Monad m) => StateT s m a -> s -> m s execStateT m s = do (_, s') <- runStateT m s return s' --- |Similar to 'mapState'+-- | Map a stateful computation from one (return value, state) pair to+-- another. For instance, to convert numberTree from a function that+-- returns a tree to a function that returns the sum of the numbered+-- tree (see the Examples section for numberTree and sumTree) you may+-- write:+--+-- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int+-- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab)) . numberTree+ mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b mapStateT f m = StateT $ f . runStateT m --- |Similar to 'withState'+-- | Apply this function to this state and return the resulting state. withStateT :: (s -> s) -> StateT s m a -> StateT s m a withStateT f m = StateT $ runStateT m . f @@ -217,6 +240,7 @@ -- | In-situ lifting of a @callCC@ operation to the new monad. -- This version uses the current state on entering the continuation.+-- It does not satisfy the laws of a monad transformer. liftCallCC' :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) -> ((a -> StateT s m b) -> StateT s m a) -> StateT s m a liftCallCC' callCC f = StateT $ \s ->@@ -242,3 +266,78 @@ liftPass pass m = StateT $ \s -> pass $ do ((a, f), s') <- runStateT m s return ((a, s'), f)++{- $examples++A function to increment a counter. Taken from the paper+/Generalising Monads to Arrows/, John+Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:++> tick :: State Int Int+> tick = do n <- get+> put (n+1)+> return n++Add one to the given number using the state monad:++> plusOne :: Int -> Int+> plusOne n = execState tick n++A contrived addition example. Works only with positive numbers:++> plus :: Int -> Int -> Int+> plus n x = execState (sequence $ replicate n tick) x++An example from /The Craft of Functional Programming/, Simon+Thompson (<http://www.cs.kent.ac.uk/people/staff/sjt/>),+Addison-Wesley 1999: \"Given an arbitrary tree, transform it to a+tree of integers in which the original elements are replaced by+natural numbers, starting from 0. The same element has to be+replaced by the same number at every occurrence, and when we meet+an as-yet-unvisited element we have to find a \'new\' number to match+it with:\"++> data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Eq)+> type Table a = [a]++> numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)+> numberTree Nil = return Nil+> numberTree (Node x t1 t2)+> = do num <- numberNode x+> nt1 <- numberTree t1+> nt2 <- numberTree t2+> return (Node num nt1 nt2)+> where+> numberNode :: Eq a => a -> State (Table a) Int+> numberNode x+> = do table <- get+> (newTable, newPos) <- return (nNode x table)+> put newTable+> return newPos+> nNode:: (Eq a) => a -> Table a -> (Table a, Int)+> nNode x table+> = case (findIndexInList (== x) table) of+> Nothing -> (table ++ [x], length table)+> Just i -> (table, i)+> findIndexInList :: (a -> Bool) -> [a] -> Maybe Int+> findIndexInList = findIndexInListHelp 0+> findIndexInListHelp _ _ [] = Nothing+> findIndexInListHelp count f (h:t)+> = if (f h)+> then Just count+> else findIndexInListHelp (count+1) f t++numTree applies numberTree with an initial state:++> numTree :: (Eq a) => Tree a -> Tree Int+> numTree t = evalState (numberTree t) []++> testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil+> numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil++sumTree is a little helper function that does not use the State monad:++> sumTree :: (Num a) => Tree a -> a+> sumTree Nil = 0+> sumTree (Node e t1 t2) = e + (sumTree t1) + (sumTree t2)+-}
Control/Monad/Trans/Writer/Lazy.hs view
@@ -34,11 +34,13 @@ liftCatch, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans import Data.Monoid -- ---------------------------------------------------------------------------
Control/Monad/Trans/Writer/Strict.hs view
@@ -34,11 +34,13 @@ liftCatch, ) where +import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Data.Functor.Identity+ import Control.Applicative import Control.Monad import Control.Monad.Fix-import Control.Monad.Identity-import Control.Monad.Trans import Data.Monoid -- ---------------------------------------------------------------------------
+ Data/Functor/Compose.hs view
@@ -0,0 +1,34 @@+-- |+-- Module : Data.Functor.Compose+-- Copyright : (c) Ross Paterson 2010+-- License : BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- Composition of functors.++module Data.Functor.Compose (+ Compose(..),+ ) where++import Control.Applicative+import Data.Foldable (Foldable(foldMap))+import Data.Traversable (Traversable(traverse))++-- | Right-to-left composition of functors.+newtype Compose f g a = Compose { getCompose :: f (g a) }++instance (Functor f, Functor g) => Functor (Compose f g) where+ fmap f (Compose x) = Compose (fmap (fmap f) x)++instance (Foldable f, Foldable g) => Foldable (Compose f g) where+ foldMap f (Compose t) = foldMap (foldMap f) t++instance (Traversable f, Traversable g) => Traversable (Compose f g) where+ traverse f (Compose t) = Compose <$> traverse (traverse f) t++instance (Applicative f, Applicative g) => Applicative (Compose f g) where+ pure x = Compose (pure (pure x))+ Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
+ Data/Functor/Constant.hs view
@@ -0,0 +1,35 @@+-- |+-- Module : Data.Functor.Constant+-- Copyright : (c) Ross Paterson 2010+-- License : BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- The constant functor.++module Data.Functor.Constant (+ Constant(..),+ ) where++import Control.Applicative+import Data.Foldable (Foldable(foldMap))+import Data.Monoid (Monoid(..))+import Data.Traversable (Traversable(traverse))++-- | Constant functor.+newtype Constant a b = Constant { getConstant :: a }++instance Functor (Constant a) where+ fmap f (Constant x) = Constant x++instance Foldable (Constant a) where+ foldMap f (Constant x) = mempty++instance Traversable (Constant a) where+ traverse f (Constant x) = pure (Constant x)++instance (Monoid a) => Applicative (Constant a) where+ pure _ = Constant mempty+ Constant x <*> Constant y = Constant (x `mappend` y)
+ Data/Functor/Identity.hs view
@@ -0,0 +1,57 @@+-- |+-- Module : Data.Functor.Identity+-- Copyright : (c) Andy Gill 2001,+-- (c) Oregon Graduate Institute of Science and Technology 2001+-- License : BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer : libraries@haskell.org+-- Stability : experimental+-- Portability : portable+--+-- The identity functor and monad.+--+-- This trivial type constructor serves two purposes:+--+-- * It can be used with functions parameterized by a 'Functor' or 'Monad'.+--+-- * It can be used as a base monad to which a series of monad+-- transformers may be applied to construct a composite monad.+-- Most monad transformer modules include the special case of+-- applying the transformer to 'Identity'. For example, @State s@+-- is an abbreviation for @StateT s 'Identity'@.++module Data.Functor.Identity (+ Identity(..),+ ) where++import Control.Applicative+import Control.Monad+import Control.Monad.Fix+import Data.Foldable (Foldable(foldMap))+import Data.Traversable (Traversable(traverse))++-- | Identity functor and monad.+newtype Identity a = Identity { runIdentity :: a }++-- ---------------------------------------------------------------------------+-- Identity instances for Functor and Monad++instance Functor Identity where+ fmap f m = Identity (f (runIdentity m))++instance Foldable Identity where+ foldMap f (Identity x) = f x++instance Traversable Identity where+ traverse f (Identity x) = Identity <$> f x++instance Applicative Identity where+ pure a = Identity a+ Identity f <*> Identity x = Identity (f x)++instance Monad Identity where+ return a = Identity a+ m >>= k = k (runIdentity m)++instance MonadFix Identity where+ mfix f = Identity (fix (runIdentity . f))
transformers.cabal view
@@ -1,11 +1,11 @@ name: transformers-version: 0.1.4.0+version: 0.2.0.0 license: BSD3 license-file: LICENSE-author: Andy Gill+author: Andy Gill, Ross Paterson maintainer: Ross Paterson <ross@soi.city.ac.uk> category: Control-synopsis: Concrete monad transformers+synopsis: Concrete functor and monad transformers description: Haskell 98 part of a monad transformer library, inspired by the paper \"Functional Programming with Overloading and Higher-Order Polymorphism\",@@ -26,12 +26,12 @@ library if flag(ApplicativeInBase)- build-depends: base >= 2+ build-depends: base >= 2 && < 6 else build-depends: base >= 1.0 && < 2, special-functors >=1.0 && <1.1 exposed-modules:- Control.Monad.Identity- Control.Monad.Trans+ Control.Monad.IO.Class+ Control.Monad.Trans.Class Control.Monad.Trans.Cont Control.Monad.Trans.Error Control.Monad.Trans.Identity@@ -47,4 +47,6 @@ Control.Monad.Trans.Writer Control.Monad.Trans.Writer.Lazy Control.Monad.Trans.Writer.Strict- extensions: CPP+ Data.Functor.Compose+ Data.Functor.Constant+ Data.Functor.Identity