mtl 2.2.0.1 → 2.2.1
raw patch · 8 files changed
+179/−4 lines, 8 filesdep ~basedep ~transformers
Dependency ranges changed: base, transformers
Files
- CHANGELOG.markdown +7/−0
- Control/Monad/Error.hs +2/−1
- Control/Monad/Error/Class.hs +1/−1
- Control/Monad/Except.hs +153/−0
- Control/Monad/Reader/Class.hs +5/−0
- Control/Monad/State/Class.hs +4/−0
- Control/Monad/Writer/Class.hs +4/−0
- mtl.cabal +3/−2
CHANGELOG.markdown view
@@ -1,3 +1,10 @@+2.2.1+-------+* Provide MINIMAL pragmas for `MonadState`, `MonadWriter`, `MonadReader`+* Added a cyclic definition of `ask` in terms of `reader` for consistency with `get`/`put` vs. `state` and `tell` vs. `writer`+* Fix deprecation warnings caused by `transformers` 0.4 deprecating `ErrorT`.+* Added `Control.Monad.Except` in the style of the other `mtl` re-export modules+ 2.2.0.1 ------- * Fixed a bug caused by the change in how `transformers` 0.4 exports its data types. We will now export `runFooT` for each transformer again!
Control/Monad/Error.hs view
@@ -32,7 +32,8 @@ inspired by the Haskell Monad Template Library from Andy Gill (<http://web.cecs.pdx.edu/~andy/>) -}-module Control.Monad.Error (+module Control.Monad.Error+ {-# DEPRECATED "Use Control.Monad.Except instead" #-} ( -- * Monads with error handling MonadError(..), Error(..),
Control/Monad/Error/Class.hs view
@@ -40,7 +40,7 @@ MonadError(..), ) where -import Control.Monad.Trans.Except (Except(..), ExceptT)+import Control.Monad.Trans.Except (Except, ExceptT) import Control.Monad.Trans.Error (Error(..), ErrorT) import qualified Control.Monad.Trans.Except as ExceptT (throwE, catchE) import qualified Control.Monad.Trans.Error as ErrorT (throwError, catchError)
+ Control/Monad/Except.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE CPP #-}+{- |+Module : Control.Monad.Error+Copyright : (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,+ (c) Jeff Newbern 2003-2006,+ (c) Andriy Palamarchuk 2006+License : BSD-style (see the file LICENSE)++Maintainer : libraries@haskell.org+Stability : experimental+Portability : non-portable (multi-parameter type classes)++[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.++[Example type:] @'Data.Either' String a@++The Error monad (also called the Exception monad).+-}++{-+ Rendered by Michael Weber <mailto:michael.weber@post.rwth-aachen.de>,+ inspired by the Haskell Monad Template Library from+ Andy Gill (<http://web.cecs.pdx.edu/~andy/>)+-}+module Control.Monad.Except+ (+ -- * Monads with error handling+ MonadError(..),+ -- * The ErrorT monad transformer+ ExceptT(ExceptT),+ Except,++ runExceptT,+ mapExceptT,+ withExceptT,+ runExcept,+ mapExcept,+ withExcept,++ module Control.Monad,+ module Control.Monad.Fix,+ module Control.Monad.Trans,+ -- * Example 1: Custom Error Data Type+ -- $customErrorExample++ -- * Example 2: Using ExceptT Monad Transformer+ -- $ExceptTExample+ ) where++import Control.Monad.Error.Class+import Control.Monad.Trans+import Control.Monad.Trans.Except+ ( ExceptT(ExceptT), Except, except+ , runExcept, runExceptT+ , mapExcept, mapExceptT+ , withExcept, withExceptT+ )++import Control.Monad+import Control.Monad.Fix++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 707+import Control.Monad.Instances ()+#endif++{- $customErrorExample+Here is an example that demonstrates the use of a custom error data type with+the 'throwError' and 'catchError' exception mechanism from 'MonadError'.+The example throws an exception if the user enters an empty string+or a string longer than 5 characters. Otherwise it prints length of the string.++>-- This is the type to represent length calculation error.+>data LengthError = EmptyString -- Entered string was empty.+> | StringTooLong Int -- A string is longer than 5 characters.+> -- Records a length of the string.+> | OtherError String -- Other error, stores the problem description.+>+>-- Converts LengthError to a readable message.+>instance Show LengthError where+> show EmptyString = "The string was empty!"+> show (StringTooLong len) =+> "The length of the string (" ++ (show len) ++ ") is bigger than 5!"+> show (OtherError msg) = msg+>+>-- For our monad type constructor, we use Either LengthError+>-- which represents failure using Left LengthError+>-- or a successful result of type a using Right a.+>type LengthMonad = Either LengthError+>+>main = do+> putStrLn "Please enter a string:"+> s <- getLine+> reportResult (calculateLength s)+>+>-- Wraps length calculation to catch the errors.+>-- Returns either length of the string or an error.+>calculateLength :: String -> LengthMonad Int+>calculateLength s = (calculateLengthOrFail s) `catchError` Left+>+>-- Attempts to calculate length and throws an error if the provided string is+>-- empty or longer than 5 characters.+>-- The processing is done in Either monad.+>calculateLengthOrFail :: String -> LengthMonad Int+>calculateLengthOrFail [] = throwError EmptyString+>calculateLengthOrFail s | len > 5 = throwError (StringTooLong len)+> | otherwise = return len+> where len = length s+>+>-- Prints result of the string length calculation.+>reportResult :: LengthMonad Int -> IO ()+>reportResult (Right len) = putStrLn ("The length of the string is " ++ (show len))+>reportResult (Left e) = putStrLn ("Length calculation failed with error: " ++ (show e))+-}++{- $ExceptTExample+@'ExceptT'@ monad transformer can be used to add error handling to another monad.+Here is an example how to combine it with an @IO@ monad:++>import Control.Monad.Except+>+>-- An IO monad which can return String failure.+>-- It is convenient to define the monad type of the combined monad,+>-- especially if we combine more monad transformers.+>type LengthMonad = ExceptT String IO+>+>main = do+> -- runExceptT removes the ExceptT wrapper+> r <- runExceptT calculateLength+> reportResult r+>+>-- Asks user for a non-empty string and returns its length.+>-- Throws an error if user enters an empty string.+>calculateLength :: LengthMonad Int+>calculateLength = do+> -- all the IO operations have to be lifted to the IO monad in the monad stack+> liftIO $ putStrLn "Please enter a non-empty string: "+> s <- liftIO getLine+> if null s+> then throwError "The string was empty!"+> else return $ length s+>+>-- Prints result of the string length calculation.+>reportResult :: Either String Int -> IO ()+>reportResult (Right len) = putStrLn ("The length of the string is " ++ (show len))+>reportResult (Left e) = putStrLn ("Length calculation failed with error: " ++ (show e))+-}
Control/Monad/Reader/Class.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed {- |@@ -69,8 +70,12 @@ -- Note, the partially applied function type @(->) r@ is a simple reader monad. -- See the @instance@ declaration below. class Monad m => MonadReader r m | m -> r where+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+ {-# MINIMAL (ask | reader), local #-}+#endif -- | Retrieves the monad environment. ask :: m r+ ask = reader id -- | Executes a computation in a modified environment. local :: (r -> r) -- ^ The function to modify the environment.
Control/Monad/State/Class.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed @@ -65,6 +66,9 @@ let ~(a, s') = f s put s' return a+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+ {-# MINIMAL state | get, put #-}+#endif -- | Monadic state transformer. --
Control/Monad/Writer/Class.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed @@ -59,6 +60,9 @@ -- the written object. class (Monoid w, Monad m) => MonadWriter w m | m -> w where+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707+ {-# MINIMAL (writer | tell), listen, pass #-}+#endif -- | @'writer' (a,w)@ embeds a simple writer action. writer :: (a,w) -> m a writer ~(a, w) = do
mtl.cabal view
@@ -1,5 +1,5 @@ name: mtl-version: 2.2.0.1+version: 2.2.1 cabal-version: >= 1.6 license: BSD3 license-file: LICENSE@@ -28,6 +28,7 @@ Control.Monad.Cont.Class Control.Monad.Error Control.Monad.Error.Class+ Control.Monad.Except Control.Monad.Identity Control.Monad.List Control.Monad.RWS@@ -50,4 +51,4 @@ MultiParamTypeClasses FunctionalDependencies FlexibleInstances- ghc-options: -Wall -fno-warn-unused-imports+ ghc-options: -Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations