packages feed

mtl 2.2.2 → 2.3

raw patch · 29 files changed

+1284/−520 lines, 29 filesdep ~basedep ~transformersnew-uploader

Dependency ranges changed: base, transformers

Files

CHANGELOG.markdown view
@@ -1,3 +1,23 @@+2.3 -- 2022-05-07+---+* Add instances for `Control.Monad.Trans.Writer.CPS` and +  `Control.Monad.Trans.RWS.CPS` from `transformers` 0.5.6 and add +  `Control.Monad.Writer.CPS` and `Control.Monad.RWS.CPS`.+* `Control.Monad.Cont` now re-exports `evalCont` and `evalContT`.+* Add `tryError`, `withError`, `handleError`, and `mapError` to+  `Control.Monad.Error.Class`, and re-export from `Control.Monad.Except`.+* Remove `Control.Monad.List` and `Control.Monad.Error`.+* Remove instances of deprecated `ListT` and `ErrorT`.+* Remove re-exports of `Error`.+* Add instances for `Control.Monad.Trans.Accum` and +  `Control.Monad.Trans.Select`.+* Require GHC 8.6 or higher, and `cabal-install` 3.0 or higher.+* Require `transformers-0.5.6` or higher.+* Add `Control.Monad.Accum` for the `MonadAccum` type class, as well as the+  `LiftingAccum` deriving helper.+* Add `Control.Monad.Select` for the `MonadSelect` type class, as well as the+  `LiftingSelect` deriving helper.+ 2.2.2 ----- * `Control.Monad.Identity` now re-exports `Control.Monad.Trans.Identity`
+ Control/Monad/Accum.hs view
@@ -0,0 +1,313 @@+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE UndecidableInstances #-}+-- Later GHCs infer DerivingVia as not Safe+-- We just downgrade to Trustworthy and go fish+{-# OPTIONS_GHC -Wno-trustworthy-safe #-}++-- | Module: Control.Monad.Accum+-- Copyright: (C) Koz Ross 2022, Manuel Bärenz 2021+-- License: BSD-3-Clause (see the LICENSE file)+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Experimental+-- Portability: GHC only+--+-- [Computation type:] Accumulation (either append-only state, or writer with+-- the ability to read all previous input).+--+-- [Binding strategy:] Binding a function to a monadic value monoidally+-- accumulates the subcomputations (that is, using '<>').+--+-- [Useful for:] Logging, patch-style tracking.+--+-- [Zero and plus:] None.+--+-- [Example type:] @'Control.Monad.Trans.Accum.Accum' w a@+--+-- = A note on commutativity+--+-- Some effects are /commutative/: it doesn't matter which you resolve first, as+-- all possible orderings of commutative effects are isomorphic. Consider, for+-- example, the reader and state effects, as exemplified by 'ReaderT' and+-- 'StrictState.StateT' respectively. If we have+-- @'ReaderT' r ('StrictState.State' s) a@, this is+-- effectively @r -> 'StrictState.State' s a ~ r -> s -> (a, s)@; if we instead have+-- @'StrictState.StateT' s ('Control.Monad.Trans.Reader.Reader' r) a@, this is effectively+-- @s -> 'Control.Monad.Trans.Reader' r (a, s) ~ s -> r -> (a, s)@. Since we+-- can always reorder function arguments (for example, using 'flip', as in+-- this case) without changing the result, these are+-- isomorphic, showing that reader and state are /commutative/, or, more+-- precisely, /commute with each other/.+--+-- However, this isn't generally the case. Consider instead the error and state+-- effects, as exemplified by 'MaybeT' and 'StrictState.StateT' respectively.+-- If we have @'MaybeT' ('Control.Monad.Trans.State.Strict.State' s) a@, this+-- is effectively @'State' s ('Maybe' a) ~ s -> ('Maybe' a, s)@: put simply,+-- the error can occur only in the /result/, but+-- not the state, which always \'survives\'. On the other hand, if we have+-- @'StrictState.StateT' s 'Maybe' a@, this is instead @s -> 'Maybe' (a, s)@: here,+-- if we error, we lose /both/ the state and the result! Thus, error and state effects+-- do /not/ commute with each other.+--+-- As the MTL is capability-based, we support any ordering of non-commutative+-- effects on an equal footing. Indeed, if you wish to use+-- 'Control.Monad.State.Class.MonadState', for+-- example, whether your final monadic stack ends up being @'MaybeT'+-- ('Control.Monad.Trans.State.Strict.State' s)+-- a@, @'StrictState.StateT' s 'Maybe' a@, or anything else, you will be able to write your+-- desired code without having to consider such differences. However, the way we+-- /implement/ these capabilities for any given transformer (or rather, any+-- given transformed stack) /is/ affected by this ordering unless the effects in+-- question are commutative.+--+-- We note in this module which effects the accumulation effect does and doesn't+-- commute with; we also note on implementations with non-commutative+-- transformers what the outcome will be. Note that, depending on how the+-- \'inner monad\' is structured, this may be more complex than we note: we+-- describe only what impact the \'outer effect\' has, not what else might be in+-- the stack.+--+-- = Commutativity of accumulation+--+-- The accumulation effect commutes with the identity effect ('IdentityT'),+-- reader, writer or state effects ('ReaderT', 'StrictWriter.WriterT', 'StrictState.StateT' and any+-- combination, including 'StrictRWS.RWST' for example) and with itself. It does /not/+-- commute with anything else.+module Control.Monad.Accum+  ( -- * Type class+    MonadAccum (..),++    -- * Lifting helper type+    LiftingAccum (..),++    -- * Other functions+    looks,+  )+where++import Control.Monad.Trans.Accum (AccumT)+import qualified Control.Monad.Trans.Accum as Accum+import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Cont (ContT)+import Control.Monad.Trans.Except (ExceptT)+import Control.Monad.Trans.Identity (IdentityT)+import Control.Monad.Trans.Maybe (MaybeT)+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import Control.Monad.Trans.Reader (ReaderT)+import Control.Monad.Trans.Select (SelectT)+import qualified Control.Monad.Trans.State.Lazy as LazyState+import qualified Control.Monad.Trans.State.Strict as StrictState+import qualified Control.Monad.Trans.Writer.CPS as CPSWriter+import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter+import qualified Control.Monad.Trans.Writer.Strict as StrictWriter+import Data.Functor (($>))+import Data.Functor.Identity (Identity)+import Data.Kind (Type)++-- | The capability to accumulate. This can be seen in one of two ways:+--+-- * A 'Control.Monad.State.Class.MonadState' which can only append (using '<>'); or+-- * A 'Control.Monad.Writer.Class.MonadWriter' (limited to+-- 'Control.Monad.Writer.Class.tell') with the ability to view the result of all previous+-- 'Control.Monad.Writer.Class.tell's.+--+-- = Laws+--+-- 'accum' should obey the following:+--+-- 1. @'accum' ('const' (x, 'mempty'))@ @=@ @'pure' x@+-- 2. @'accum' f '*>' 'accum' g@ @=@+-- @'accum' '$' \acc -> let (_, v) = f acc+--                          (res, w) = g (acc '<>' v) in (res, v '<>' w)@+--+-- If you choose to define 'look' and 'add' instead, their definitions must obey+-- the following:+--+-- 1. @'look' '*>' 'look'@ @=@ @'look'@+-- 2. @'add' 'mempty'@ @=@ @'pure' ()@+-- 3. @'add' x '*>' 'add' y@ @=@ @'add' (x '<>' y)@+-- 4. @'add' x '*>' 'look'@ @=@ @'look' '>>=' \w -> 'add' x '$>' w '<>' x@+--+-- If you want to define both, the relationship between them is as follows.+-- These are also the default definitions.+--+-- 1. @'look'@ @=@ @'accum' '$' \acc -> (acc, mempty)@+-- 2. @'add' x@ @=@ @'accum' '$' \acc -> ('()', x)@+-- 3. @'accum' f@ @=@ @'look' >>= \acc -> let (res, v) = f acc in 'add' v '$>' res@+--+-- @since 2.3+class (Monoid w, Monad m) => MonadAccum w m | m -> w where+  -- | Retrieve the accumulated result so far.+  look :: m w+  look = accum (,mempty)++  -- | Append a value to the result.+  add :: w -> m ()+  add x = accum $ const ((), x)++  -- | Embed a simple accumulation action into the monad.+  accum :: (w -> (a, w)) -> m a+  accum f = look >>= \acc -> let (res, v) = f acc in add v $> res++  {-# MINIMAL accum | look, add #-}++-- | @since 2.3+instance (Monoid w) => MonadAccum w (AccumT w Identity) where+  look = Accum.look+  add = Accum.add+  accum = Accum.accum++-- | The accumulated value \'survives\' an error: even if the+-- computation fails to deliver a result, we still have an accumulated value.+--+-- @since 2.3+deriving via+  (LiftingAccum MaybeT m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (MaybeT m)++-- | The continuation can see, and interact with, the accumulated value.+--+-- @since 2.3+deriving via+  (LiftingAccum (ContT r) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (ContT r m)++-- | The accumulated value \'survives\' an exception: even if the computation+-- fails to deliver a result, we still have an accumulated value.+--+-- @since 2.3+deriving via+  (LiftingAccum (ExceptT e) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (ExceptT e m)++-- | @since 2.3+deriving via+  (LiftingAccum IdentityT m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (IdentityT m)++-- | @since 2.3+deriving via+  (LiftingAccum (CPSRWS.RWST r w s) m)+  instance+    (MonadAccum w' m) =>+    MonadAccum w' (CPSRWS.RWST r w s m)++-- | @since 2.3+deriving via+  (LiftingAccum (LazyRWS.RWST r w s) m)+  instance+    (MonadAccum w' m, Monoid w) =>+    MonadAccum w' (LazyRWS.RWST r w s m)++-- | @since 2.3+deriving via+  (LiftingAccum (StrictRWS.RWST r w s) m)+  instance+    (MonadAccum w' m, Monoid w) =>+    MonadAccum w' (StrictRWS.RWST r w s m)++-- | @since 2.3+deriving via+  (LiftingAccum (ReaderT r) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (ReaderT r m)++-- | The \'ranking\' function gains the ability to accumulate @w@s each time it+-- is called. The final result will include the entire log of all such calls.+--+-- @since 2.3+deriving via+  (LiftingAccum (SelectT r) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (SelectT r m)++-- | @since 2.3+deriving via+  (LiftingAccum (LazyState.StateT s) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (LazyState.StateT s m)++-- | @since 2.3+deriving via+  (LiftingAccum (StrictState.StateT s) m)+  instance+    (MonadAccum w m) =>+    MonadAccum w (StrictState.StateT s m)++-- | @since 2.3+deriving via+  (LiftingAccum (CPSWriter.WriterT w) m)+  instance+    (MonadAccum w' m) =>+    MonadAccum w' (CPSWriter.WriterT w m)++-- | @since 2.3+deriving via+  (LiftingAccum (LazyWriter.WriterT w) m)+  instance+    (MonadAccum w' m, Monoid w) =>+    MonadAccum w' (LazyWriter.WriterT w m)++-- | @since 2.3+deriving via+  (LiftingAccum (StrictWriter.WriterT w) m)+  instance+    (MonadAccum w' m, Monoid w) =>+    MonadAccum w' (StrictWriter.WriterT w m)++-- | A helper type to decrease boilerplate when defining new transformer+-- instances of 'MonadAccum'.+--+-- Most of the instances in this module are derived using this method; for+-- example, our instance of 'ExceptT' is derived as follows:+--+-- > deriving via (LiftingAccum (ExceptT e) m) instance (MonadAccum w m) =>+-- >  MonadAccum w (ExceptT e m)+--+-- @since 2.3+newtype LiftingAccum (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) (a :: Type)+  = LiftingAccum (t m a)+  deriving+    ( -- | @since 2.3+      Functor,+      -- | @since 2.3+      Applicative,+      -- | @since 2.3+      Monad+    )+    via (t m)++-- | @since 2.3+instance (MonadTrans t, Monad (t m), MonadAccum w m) => MonadAccum w (LiftingAccum t m) where+  look = LiftingAccum . lift $ look+  add x = LiftingAccum . lift $ add x+  accum f = LiftingAccum . lift $ accum f++-- | Retrieve a function of the accumulated value.+--+-- @since 2.3+looks ::+  forall (a :: Type) (m :: Type -> Type) (w :: Type).+  (MonadAccum w m) =>+  (w -> a) ->+  m a+looks f = f <$> look
Control/Monad/Cont.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Safe #-}+ {- | Module      :  Control.Monad.Cont Copyright   :  (c) The University of Glasgow 2001,@@ -50,20 +52,20 @@  module Control.Monad.Cont (     -- * MonadCont class-    MonadCont(..),+    MonadCont.MonadCont(..),     -- * The Cont monad-    Cont,-    cont,-    runCont,-    mapCont,-    withCont,+    Cont.Cont,+    Cont.cont,+    Cont.runCont,+    Cont.evalCont,+    Cont.mapCont,+    Cont.withCont,     -- * The ContT monad transformer-    ContT(ContT),-    runContT,-    mapContT,-    withContT,-    module Control.Monad,-    module Control.Monad.Trans,+    Cont.ContT(ContT),+    Cont.runContT,+    Cont.evalContT,+    Cont.mapContT,+    Cont.withContT,     -- * Example 1: Simple Continuation Usage     -- $simpleContExample @@ -74,12 +76,8 @@     -- $ContTExample   ) where -import Control.Monad.Cont.Class--import Control.Monad.Trans-import Control.Monad.Trans.Cont--import Control.Monad+import qualified Control.Monad.Cont.Class as MonadCont+import qualified Control.Monad.Trans.Cont as Cont  {- $simpleContExample Calculating length of a list continuation-style:
Control/Monad/Cont/Class.hs view
@@ -1,4 +1,9 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-}+-- Needed because the CPSed versions of Writer and State are secretly State+-- wrappers, which don't force such constraints, even though they should legally+-- be there.+{-# OPTIONS_GHC -Wno-redundant-constraints #-}+ {- | Module      :  Control.Monad.Cont.Class Copyright   :  (c) The University of Glasgow 2001,@@ -55,21 +60,24 @@  import Control.Monad.Trans.Cont (ContT) import qualified Control.Monad.Trans.Cont as ContT-import Control.Monad.Trans.Error as Error-import Control.Monad.Trans.Except as Except-import Control.Monad.Trans.Identity as Identity-import Control.Monad.Trans.List as List-import Control.Monad.Trans.Maybe as Maybe-import Control.Monad.Trans.Reader as Reader-import Control.Monad.Trans.RWS.Lazy as LazyRWS-import Control.Monad.Trans.RWS.Strict as StrictRWS-import Control.Monad.Trans.State.Lazy as LazyState-import Control.Monad.Trans.State.Strict as StrictState-import Control.Monad.Trans.Writer.Lazy as LazyWriter-import Control.Monad.Trans.Writer.Strict as StrictWriter--import Control.Monad-import Data.Monoid+import Control.Monad.Trans.Except (ExceptT)+import qualified Control.Monad.Trans.Except as Except+import Control.Monad.Trans.Identity (IdentityT)+import qualified Control.Monad.Trans.Identity as Identity+import Control.Monad.Trans.Maybe (MaybeT)+import qualified Control.Monad.Trans.Maybe as Maybe+import Control.Monad.Trans.Reader (ReaderT)+import qualified Control.Monad.Trans.Reader as Reader+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import qualified Control.Monad.Trans.State.Lazy as LazyState+import qualified Control.Monad.Trans.State.Strict as StrictState+import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter+import qualified Control.Monad.Trans.Writer.Strict as StrictWriter+import Control.Monad.Trans.Accum (AccumT)+import qualified Control.Monad.Trans.Accum as Accum+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.Writer.CPS as CPSWriter  class Monad m => MonadCont m where     {- | @callCC@ (call-with-current-continuation)@@ -77,9 +85,9 @@     Provides an escape continuation mechanism for use with Continuation monads.     Escape continuations allow to abort the current computation and return     a value immediately.-    They achieve a similar effect to 'Control.Monad.Error.throwError'-    and 'Control.Monad.Error.catchError'-    within an 'Control.Monad.Error.Error' monad.+    They achieve a similar effect to 'Control.Monad.Error.Class.throwError'+    and 'Control.Monad.Error.Class.catchError'+    within an 'Control.Monad.Except.Except' monad.     Advantage of this function over calling @return@ is that it makes     the continuation explicit,     allowing more flexibility and better control@@ -91,9 +99,7 @@     even if it is many layers deep within nested computations.     -}     callCC :: ((a -> m b) -> m a) -> m a-#if __GLASGOW_HASKELL__ >= 707     {-# MINIMAL callCC #-}-#endif  instance MonadCont (ContT r m) where     callCC = ContT.callCC@@ -101,9 +107,6 @@ -- --------------------------------------------------------------------------- -- Instances for other mtl transformers -instance (Error e, MonadCont m) => MonadCont (ErrorT e m) where-    callCC = Error.liftCallCC callCC- {- | @since 2.2 -} instance MonadCont m => MonadCont (ExceptT e m) where     callCC = Except.liftCallCC callCC@@ -111,9 +114,6 @@ instance MonadCont m => MonadCont (IdentityT m) where     callCC = Identity.liftCallCC callCC -instance MonadCont m => MonadCont (ListT m) where-    callCC = List.liftCallCC callCC- instance MonadCont m => MonadCont (MaybeT m) where     callCC = Maybe.liftCallCC callCC @@ -137,3 +137,18 @@  instance (Monoid w, MonadCont m) => MonadCont (StrictWriter.WriterT w m) where     callCC = StrictWriter.liftCallCC callCC++-- | @since 2.3+instance (Monoid w, MonadCont m) => MonadCont (CPSRWS.RWST r w s m) where+    callCC = CPSRWS.liftCallCC' callCC++-- | @since 2.3+instance (Monoid w, MonadCont m) => MonadCont (CPSWriter.WriterT w m) where+    callCC = CPSWriter.liftCallCC callCC++-- | @since 2.3+instance+  ( Monoid w+  , MonadCont m+  ) => MonadCont (AccumT w m) where+    callCC = Accum.liftCallCC callCC
− Control/Monad/Error.hs
@@ -1,151 +0,0 @@-{-# 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.--[Zero and plus:] Zero is represented by an empty error and the plus operation-executes its second argument if the first fails.--[Example type:] @'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.Error-  {-# DEPRECATED "Use \"Control.Monad.Except\" instead" #-} (-    -- * Monads with error handling-    MonadError(..),-    Error(..),-    -- * The ErrorT monad transformer-    ErrorT(ErrorT),-    runErrorT,-    mapErrorT,-    module Control.Monad,-    module Control.Monad.Fix,-    module Control.Monad.Trans,-    -- * Example 1: Custom Error Data Type-    -- $customErrorExample--    -- * Example 2: Using ErrorT Monad Transformer-    -- $ErrorTExample-  ) where--import Control.Monad.Error.Class-import Control.Monad.Trans-import Control.Monad.Trans.Error (ErrorT(ErrorT), runErrorT, mapErrorT)--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.->->-- We make LengthError an instance of the Error class->-- to be able to throw it as an exception.->instance Error LengthError where->  noMsg    = OtherError "A String Error!"->  strMsg s = OtherError s->->-- 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))--}--{- $ErrorTExample-@'ErrorT'@ 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.Error->->-- 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 = ErrorT String IO->->main = do->  -- runErrorT removes the ErrorT wrapper->  r <- runErrorT 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/Error/Class.hs view
@@ -1,8 +1,12 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE Safe #-}+-- Needed because the CPSed versions of Writer and State are secretly State+-- wrappers, which don't force such constraints, even though they should legally+-- be there.+{-# OPTIONS_GHC -Wno-redundant-constraints #-}  {- | Module      :  Control.Monad.Error.Class@@ -39,36 +43,37 @@     Andy Gill (<http://web.cecs.pdx.edu/~andy/>) -} module Control.Monad.Error.Class (-    Error(..),     MonadError(..),     liftEither,+    tryError,+    withError,+    handleError,+    mapError,   ) where -import Control.Monad.Trans.Except (Except, ExceptT)-import Control.Monad.Trans.Error (Error(..), ErrorT)+import Control.Monad.Trans.Except (ExceptT) import qualified Control.Monad.Trans.Except as ExceptT (throwE, catchE)-import qualified Control.Monad.Trans.Error as ErrorT (throwError, catchError)-import Control.Monad.Trans.Identity as Identity-import Control.Monad.Trans.List as List-import Control.Monad.Trans.Maybe as Maybe-import Control.Monad.Trans.Reader as Reader-import Control.Monad.Trans.RWS.Lazy as LazyRWS-import Control.Monad.Trans.RWS.Strict as StrictRWS-import Control.Monad.Trans.State.Lazy as LazyState-import Control.Monad.Trans.State.Strict as StrictState-import Control.Monad.Trans.Writer.Lazy as LazyWriter-import Control.Monad.Trans.Writer.Strict as StrictWriter-+import Control.Monad.Trans.Identity (IdentityT)+import qualified Control.Monad.Trans.Identity as Identity+import Control.Monad.Trans.Maybe (MaybeT)+import qualified Control.Monad.Trans.Maybe as Maybe+import Control.Monad.Trans.Reader (ReaderT)+import qualified Control.Monad.Trans.Reader as Reader+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import qualified Control.Monad.Trans.State.Lazy as LazyState+import qualified Control.Monad.Trans.State.Strict as StrictState+import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter+import qualified Control.Monad.Trans.Writer.Strict as StrictWriter+import Control.Monad.Trans.Accum (AccumT)+import qualified Control.Monad.Trans.Accum as Accum+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.Writer.CPS as CPSWriter import Control.Monad.Trans.Class (lift) import Control.Exception (IOException, catch, ioError)-import Control.Monad--#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 707-import Control.Monad.Instances ()-#endif--import Data.Monoid-import Prelude (Either(..), Maybe(..), either, (.), IO)+import Control.Monad (Monad)+import Data.Monoid (Monoid)+import Prelude (Either (Left, Right), Maybe (Nothing), either, flip, (.), IO, pure, (<$>), (>>=))  {- | The strategy of combining computations that can throw exceptions@@ -102,9 +107,7 @@     Note that @handler@ and the do-block must have the same return type.     -}     catchError :: m a -> (e -> m a) -> m a-#if __GLASGOW_HASKELL__ >= 707     {-# MINIMAL throwError, catchError #-}-#endif  {- | Lifts an @'Either' e@ into any @'MonadError' e@.@@ -116,7 +119,7 @@ @since 2.2.2 -} liftEither :: MonadError e m => Either e a -> m a-liftEither = either throwError return+liftEither = either throwError pure  instance MonadError IOException IO where     throwError = ioError@@ -136,10 +139,6 @@     Left  l `catchError` h = h l     Right r `catchError` _ = Right r -instance (Monad m, Error e) => MonadError e (ErrorT e m) where-    throwError = ErrorT.throwError-    catchError = ErrorT.catchError- {- | @since 2.2 -} instance Monad m => MonadError e (ExceptT e m) where     throwError = ExceptT.throwE@@ -155,10 +154,6 @@     throwError = lift . throwError     catchError = Identity.liftCatch catchError -instance MonadError e m => MonadError e (ListT m) where-    throwError = lift . throwError-    catchError = List.liftCatch catchError- instance MonadError e m => MonadError e (MaybeT m) where     throwError = lift . throwError     catchError = Maybe.liftCatch catchError@@ -190,3 +185,43 @@ instance (Monoid w, MonadError e m) => MonadError e (StrictWriter.WriterT w m) where     throwError = lift . throwError     catchError = StrictWriter.liftCatch catchError++-- | @since 2.3+instance (Monoid w, MonadError e m) => MonadError e (CPSRWS.RWST r w s m) where+    throwError = lift . throwError+    catchError = CPSRWS.liftCatch catchError++-- | @since 2.3+instance (Monoid w, MonadError e m) => MonadError e (CPSWriter.WriterT w m) where+    throwError = lift . throwError+    catchError = CPSWriter.liftCatch catchError++-- | @since 2.3+instance+  ( Monoid w+  , MonadError e m+  ) => MonadError e (AccumT w m) where+    throwError = lift . throwError+    catchError = Accum.liftCatch catchError++-- | 'MonadError' analogue to the 'Control.Exception.try' function.+tryError :: MonadError e m => m a -> m (Either e a)+tryError action = (Right <$> action) `catchError` (pure . Left)++-- | 'MonadError' analogue to the 'withExceptT' function.+-- Modify the value (but not the type) of an error.  The type is+-- fixed because of the functional dependency @m -> e@.  If you need+-- to change the type of @e@ use 'mapError'.+withError :: MonadError e m => (e -> e) -> m a -> m a+withError f action = tryError action >>= either (throwError . f) pure++-- | As 'handle' is flipped 'Control.Exception.catch', 'handleError'+-- is flipped 'catchError'.+handleError :: MonadError e m => (e -> m a) -> m a -> m a+handleError = flip catchError++-- | 'MonadError' analogue of the 'mapExceptT' function.  The+-- computation is unwrapped, a function is applied to the @Either@, and+-- the result is lifted into the second 'MonadError' instance.+mapError :: (MonadError e m, MonadError e' n) => (m (Either e a) -> n (Either e' b)) -> m a -> n b+mapError f action = f (tryError action) >>= liftEither
Control/Monad/Except.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-} {- | Module      :  Control.Monad.Except Copyright   :  (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,@@ -36,22 +36,12 @@     -- * Warning     -- $warning     -- * Monads with error handling-    MonadError(..),-    liftEither,-    -- * The ExceptT monad transformer-    ExceptT(ExceptT),-    Except,--    runExceptT,-    mapExceptT,-    withExceptT,-    runExcept,-    mapExcept,-    withExcept,--    module Control.Monad,-    module Control.Monad.Fix,-    module Control.Monad.Trans,+    Error.MonadError(..),+    Error.liftEither,+    Error.tryError,+    Error.withError,+    Error.handleError,+    Error.mapError,     -- * Example 1: Custom Error Data Type     -- $customErrorExample @@ -59,21 +49,7 @@     -- $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+import qualified Control.Monad.Error.Class as Error  {- $warning Please do not confuse 'ExceptT' and 'throwError' with 'Control.Exception.Exception' /
Control/Monad/Identity.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} {- | Module      :  Control.Monad.Identity Copyright   :  (c) Andy Gill 2001,@@ -35,13 +36,7 @@ module Control.Monad.Identity (     module Data.Functor.Identity,     module Control.Monad.Trans.Identity,--    module Control.Monad,-    module Control.Monad.Fix,    ) where  import Data.Functor.Identity import Control.Monad.Trans.Identity--import Control.Monad-import Control.Monad.Fix
− Control/Monad/List.hs
@@ -1,25 +0,0 @@--------------------------------------------------------------------------------- |--- Module      :  Control.Monad.List--- Copyright   :  (c) Andy Gill 2001,---                (c) Oregon Graduate Institute of Science and Technology, 2001--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  libraries@haskell.org--- Stability   :  experimental--- Portability :  portable------ The List monad.-----------------------------------------------------------------------------------module Control.Monad.List (-    ListT(..),-    mapListT,-    module Control.Monad,-    module Control.Monad.Trans,-  ) where--import Control.Monad-import Control.Monad.Trans-import Control.Monad.Trans.List
Control/Monad/RWS.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Safe #-}+ ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.RWS
+ Control/Monad/RWS/CPS.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE Safe #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Control.Monad.RWS.Strict+-- Copyright   :  (c) Andy Gill 2001,+--                (c) Oregon Graduate Institute of Science and Technology, 2001+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  experimental+-- Portability :  non-portable (multi-param classes, functional dependencies)+--+-- Strict RWS monad that uses continuation-passing-style to achieve constant+-- space usage.+--+--      Inspired by the paper+--      /Functional Programming with Overloading and Higher-Order Polymorphism/,+--        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)+--          Advanced School of Functional Programming, 1995.+--+-- /Since: mtl-2.3, transformers-0.5.6/+-----------------------------------------------------------------------------++module Control.Monad.RWS.CPS (+    -- * The RWS monad+    RWS,+    rws,+    runRWS,+    evalRWS,+    execRWS,+    mapRWS,+    withRWS,+    -- * The RWST monad transformer+    RWST,+    runRWST,+    evalRWST,+    execRWST,+    mapRWST,+    withRWST,+    -- * Strict Reader-writer-state monads+    module Control.Monad.RWS.Class,+    module Control.Monad.Trans,+  ) where++import Control.Monad.RWS.Class++import Control.Monad.Trans+import Control.Monad.Trans.RWS.CPS (+    RWS, rws, runRWS, evalRWS, execRWS, mapRWS, withRWS,+    RWST, runRWST, evalRWST, execRWST, mapRWST, withRWST)
Control/Monad/RWS/Class.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE Safe #-}  ----------------------------------------------------------------------------- -- |@@ -34,23 +35,23 @@ import Control.Monad.State.Class import Control.Monad.Writer.Class -import Control.Monad.Trans.Class-import Control.Monad.Trans.Error(Error, ErrorT)-import Control.Monad.Trans.Except(ExceptT)-import Control.Monad.Trans.Maybe(MaybeT)-import Control.Monad.Trans.Identity(IdentityT)-import Control.Monad.Trans.RWS.Lazy as Lazy (RWST)+import Control.Monad.Trans.Except (ExceptT)+import Control.Monad.Trans.Maybe (MaybeT)+import Control.Monad.Trans.Identity (IdentityT)+import qualified Control.Monad.Trans.RWS.CPS as CPS (RWST)+import qualified Control.Monad.Trans.RWS.Lazy as Lazy (RWST) import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST) -import Data.Monoid- class (Monoid w, MonadReader r m, MonadWriter w m, MonadState s m)    => MonadRWS r w s m | m -> r, m -> w, m -> s +-- | @since 2.3+instance (Monoid w, Monad m) => MonadRWS r w s (CPS.RWST r w s m)+ instance (Monoid w, Monad m) => MonadRWS r w s (Lazy.RWST r w s m)  instance (Monoid w, Monad m) => MonadRWS r w s (Strict.RWST r w s m)- + --------------------------------------------------------------------------- -- Instances for other mtl transformers --@@ -59,6 +60,5 @@  -- | @since 2.2 instance MonadRWS r w s m => MonadRWS r w s (ExceptT e m)-instance (Error e, MonadRWS r w s m) => MonadRWS r w s (ErrorT e m) instance MonadRWS r w s m => MonadRWS r w s (IdentityT m) instance MonadRWS r w s m => MonadRWS r w s (MaybeT m)
Control/Monad/RWS/Lazy.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.RWS.Lazy@@ -35,10 +36,7 @@     withRWST,     -- * Lazy Reader-writer-state monads     module Control.Monad.RWS.Class,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,-    module Data.Monoid,   ) where  import Control.Monad.RWS.Class@@ -47,7 +45,3 @@ import Control.Monad.Trans.RWS.Lazy (     RWS, rws, runRWS, evalRWS, execRWS, mapRWS, withRWS,     RWST(RWST), runRWST, evalRWST, execRWST, mapRWST, withRWST)--import Control.Monad-import Control.Monad.Fix-import Data.Monoid
Control/Monad/RWS/Strict.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.RWS.Strict@@ -35,19 +36,12 @@     withRWST,     -- * Strict Reader-writer-state monads     module Control.Monad.RWS.Class,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,-    module Data.Monoid,   ) where  import Control.Monad.RWS.Class- import Control.Monad.Trans+ import Control.Monad.Trans.RWS.Strict (     RWS, rws, runRWS, evalRWS, execRWS, mapRWS, withRWS,     RWST(RWST), runRWST, evalRWST, execRWST, mapRWST, withRWST)--import Control.Monad-import Control.Monad.Fix-import Data.Monoid
Control/Monad/Reader.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} {- | Module      :  Control.Monad.Reader Copyright   :  (c) Andy Gill 2001,@@ -37,8 +38,8 @@  module Control.Monad.Reader (     -- * MonadReader class-    MonadReader(..),-    asks,+    MonadReader.MonadReader(..),+    MonadReader.asks,     -- * The Reader monad     Reader,     runReader,@@ -49,8 +50,6 @@     runReaderT,     mapReaderT,     withReaderT,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,     -- * Example 1: Simple Reader Usage     -- $simpleReaderExample@@ -62,16 +61,13 @@     -- $ReaderTExample     ) where -import Control.Monad.Reader.Class+import qualified Control.Monad.Reader.Class as MonadReader+import Control.Monad.Trans  import Control.Monad.Trans.Reader (     Reader, runReader, mapReader, withReader,     ReaderT(ReaderT), runReaderT, mapReaderT, withReaderT)-import Control.Monad.Trans -import Control.Monad-import Control.Monad.Fix- {- $simpleReaderExample  In this example the @Reader@ monad provides access to variable bindings.@@ -80,8 +76,12 @@ You can see how to run a Reader monad and retrieve data from it with 'runReader', how to access the Reader data with 'ask' and 'asks'. -> type Bindings = Map String Int;+>import           Control.Monad.Reader+>import           Data.Map (Map)+>import qualified Data.Map as Map >+>type Bindings = Map String Int+> >-- Returns True if the "count" variable contains correct bindings size. >isCountCorrect :: Bindings -> Bool >isCountCorrect bindings = runReader calc_isCountCorrect bindings@@ -93,22 +93,26 @@ >    bindings <- ask >    return (count == (Map.size bindings)) >->-- The selector function to  use with 'asks'.+>-- The selector function to use with 'asks'. >-- Returns value of the variable with specified name. >lookupVar :: String -> Bindings -> Int >lookupVar name bindings = maybe 0 id (Map.lookup name bindings) >->sampleBindings = Map.fromList [("count",3), ("1",1), ("b",2)]+>sampleBindings :: Bindings+>sampleBindings = Map.fromList [("count", 3), ("1", 1), ("b", 2)] >+>main :: IO () >main = do->    putStr $ "Count is correct for bindings " ++ (show sampleBindings) ++ ": ";->    putStrLn $ show (isCountCorrect sampleBindings);+>    putStr $ "Count is correct for bindings " ++ (show sampleBindings) ++ ": "+>    putStrLn $ show (isCountCorrect sampleBindings) -}  {- $localExample  Shows how to modify Reader content with 'local'. +>import Control.Monad.Reader+> >calculateContentLen :: Reader String Int >calculateContentLen = do >    content <- ask@@ -118,6 +122,7 @@ >calculateModifiedContentLen :: Reader String Int >calculateModifiedContentLen = local ("Prefix " ++) calculateContentLen >+>main :: IO () >main = do >    let s = "12345"; >    let modifiedLen = runReader calculateModifiedContentLen s@@ -133,12 +138,14 @@ This can be easily done with the 'ReaderT' monad transformer. This example shows how to combine @ReaderT@ with the IO monad. +>import Control.Monad.Reader+> >-- The Reader/IO combined monad, where Reader stores a string. >printReaderContent :: ReaderT String IO () >printReaderContent = do >    content <- ask >    liftIO $ putStrLn ("The Reader Content: " ++ content) >->main = do->    runReaderT printReaderContent "Some Content"+>main :: IO ()+>main = runReaderT printReaderContent "Some Content" -}
Control/Monad/Reader/Class.hs view
@@ -1,9 +1,13 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed+{-# LANGUAGE UndecidableInstances #-}+-- Needed because the CPSed versions of Writer and State are secretly State+-- wrappers, which don't force such constraints, even though they should legally+-- be there.+{-# OPTIONS_GHC -Wno-redundant-constraints #-} {- | Module      :  Control.Monad.Reader.Class Copyright   :  (c) Andy Gill 2001,@@ -46,24 +50,25 @@     asks,     ) where -import Control.Monad.Trans.Cont as Cont-import Control.Monad.Trans.Except-import Control.Monad.Trans.Error-import Control.Monad.Trans.Identity-import Control.Monad.Trans.List-import Control.Monad.Trans.Maybe+import qualified Control.Monad.Trans.Cont as Cont+import Control.Monad.Trans.Cont (ContT)+import Control.Monad.Trans.Except (ExceptT, mapExceptT)+import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)+import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT) import Control.Monad.Trans.Reader (ReaderT)-import qualified Control.Monad.Trans.Reader as ReaderT (ask, local, reader)-import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, ask, local, reader)-import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, ask, local, reader)-import Control.Monad.Trans.State.Lazy as Lazy-import Control.Monad.Trans.State.Strict as Strict-import Control.Monad.Trans.Writer.Lazy as Lazy-import Control.Monad.Trans.Writer.Strict as Strict-+import qualified Control.Monad.Trans.Reader as ReaderT+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import qualified Control.Monad.Trans.State.Lazy as Lazy+import qualified Control.Monad.Trans.State.Strict as Strict+import qualified Control.Monad.Trans.Writer.Lazy as Lazy+import qualified Control.Monad.Trans.Writer.Strict as Strict+import Control.Monad.Trans.Accum (AccumT)+import qualified Control.Monad.Trans.Accum as Accum+import Control.Monad.Trans.Select (SelectT (SelectT), runSelectT)+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.Writer.CPS as CPS import Control.Monad.Trans.Class (lift)-import Control.Monad-import Data.Monoid  -- ---------------------------------------------------------------------------- -- class MonadReader@@ -73,9 +78,7 @@ -- 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 __GLASGOW_HASKELL__ >= 707     {-# MINIMAL (ask | reader), local #-}-#endif     -- | Retrieves the monad environment.     ask   :: m r     ask = reader id@@ -111,6 +114,12 @@     local = ReaderT.local     reader = ReaderT.reader +-- | @since 2.3+instance (Monad m, Monoid w) => MonadReader r (CPSRWS.RWST r w s m) where+    ask = CPSRWS.ask+    local = CPSRWS.local+    reader = CPSRWS.reader+ instance (Monad m, Monoid w) => MonadReader r (LazyRWS.RWST r w s m) where     ask = LazyRWS.ask     local = LazyRWS.local@@ -132,11 +141,6 @@     local = Cont.liftLocal ask local     reader = lift . reader -instance (Error e, MonadReader r m) => MonadReader r (ErrorT e m) where-    ask   = lift ask-    local = mapErrorT . local-    reader = lift . reader- {- | @since 2.2 -} instance MonadReader r m => MonadReader r (ExceptT e m) where     ask   = lift ask@@ -148,11 +152,6 @@     local = mapIdentityT . local     reader = lift . reader -instance MonadReader r m => MonadReader r (ListT m) where-    ask   = lift ask-    local = mapListT . local-    reader = lift . reader- instance MonadReader r m => MonadReader r (MaybeT m) where     ask   = lift ask     local = mapMaybeT . local@@ -168,6 +167,12 @@     local = Strict.mapStateT . local     reader = lift . reader +-- | @since 2.3+instance (Monoid w, MonadReader r m) => MonadReader r (CPS.WriterT w m) where+    ask   = lift ask+    local = CPS.mapWriterT . local+    reader = lift . reader+ instance (Monoid w, MonadReader r m) => MonadReader r (Lazy.WriterT w m) where     ask   = lift ask     local = Lazy.mapWriterT . local@@ -176,4 +181,24 @@ instance (Monoid w, MonadReader r m) => MonadReader r (Strict.WriterT w m) where     ask   = lift ask     local = Strict.mapWriterT . local+    reader = lift . reader++-- | @since 2.3+instance+  ( Monoid w+  , MonadReader r m+  ) => MonadReader r (AccumT w m) where+    ask = lift ask+    local = Accum.mapAccumT . local+    reader = lift . reader++-- | @since 2.3+instance+  ( MonadReader r' m+  ) => MonadReader r' (SelectT r m) where+    ask = lift ask+    -- there is no Select.liftLocal+    local f m = SelectT $ \c -> do+      r <- ask+      local f (runSelectT m (local (const r) . c))     reader = lift . reader
+ Control/Monad/Select.hs view
@@ -0,0 +1,316 @@+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE UndecidableInstances #-}+-- Later GHCs infer DerivingVia as not Safe+-- We just downgrade to Trustworthy and go fish+{-# OPTIONS_GHC -Wno-trustworthy-safe #-}++-- | Module: Control.Monad.Select+-- Copyright: (C) Koz Ross 2022+-- License: BSD-3-Clause (see the LICENSE file)+-- Maintainer: koz.ross@retro-freedom.nz+-- Stability: Experimental+-- Portability: GHC only+--+-- [Computation type:] Backtracking search, with @r@ as a \'ranking\' or+-- \'evaluation\' type.+--+-- [Binding strategy:] Binding a function to a monadic value \'chains together\'+-- strategies; having seen the result of one search, decide which policy to use+-- to continue.+--+-- [Useful for:] Search problems.+--+-- [Zero and plus:] None.+--+-- [Example type:] @'Control.Monad.Trans.Select.Select' r a@+--+-- = A note on commutativity+--+-- Some effects are /commutative/: it doesn't matter which you resolve first, as+-- all possible orderings of commutative effects are isomorphic. Consider, for+-- example, the reader and state effects, as exemplified by 'ReaderT' and+-- 'StrictState.StateT' respectively. If we have+-- @'ReaderT' r ('StrictState.State' s) a@, this is+-- effectively @r -> 'StrictState.State' s a ~ r -> s -> (a, s)@; if we instead have+-- @'StrictState.StateT' s ('Control.Monad.Trans.Reader.Reader' r) a@, this is effectively+-- @s -> 'Control.Monad.Trans.Reader' r (a, s) ~ s -> r -> (a, s)@. Since we+-- can always reorder function arguments (for example, using 'flip', as in+-- this case) without changing the result, these are+-- isomorphic, showing that reader and state are /commutative/, or, more+-- precisely, /commute with each other/.+--+-- However, this isn't generally the case. Consider instead the error and state+-- effects, as exemplified by 'MaybeT' and 'StrictState.StateT' respectively.+-- If we have @'MaybeT' ('Control.Monad.Trans.State.Strict.State' s) a@, this+-- is effectively @'State' s ('Maybe' a) ~ s -> ('Maybe' a, s)@: put simply,+-- the error can occur only in the /result/, but+-- not the state, which always \'survives\'. On the other hand, if we have+-- @'StrictState.StateT' s 'Maybe' a@, this is instead @s -> 'Maybe' (a, s)@: here,+-- if we error, we lose /both/ the state and the result! Thus, error and state effects+-- do /not/ commute with each other.+--+-- As the MTL is capability-based, we support any ordering of non-commutative+-- effects on an equal footing. Indeed, if you wish to use+-- 'Control.Monad.State.Class.MonadState', for+-- example, whether your final monadic stack ends up being @'MaybeT'+-- ('Control.Monad.Trans.State.Strict.State' s)+-- a@, @'StrictState.StateT' s 'Maybe' a@, or anything else, you will be able to write your+-- desired code without having to consider such differences. However, the way we+-- /implement/ these capabilities for any given transformer (or rather, any+-- given transformed stack) /is/ affected by this ordering unless the effects in+-- question are commutative.+--+-- We note in this module which effects the accumulation effect does and doesn't+-- commute with; we also note on implementations with non-commutative+-- transformers what the outcome will be. Note that, depending on how the+-- \'inner monad\' is structured, this may be more complex than we note: we+-- describe only what impact the \'outer effect\' has, not what else might be in+-- the stack.+--+-- = Commutativity of selection+--+-- The selection effect commutes with the identity effect ('IdentityT'), but+-- nothing else.+module Control.Monad.Select+  ( -- * Type class+    MonadSelect (..),++    -- * Lifting helper type+    LiftingSelect (..),+  )+where++import Control.Monad.Trans.Accum (AccumT)+import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Cont (ContT)+import Control.Monad.Trans.Except (ExceptT)+import Control.Monad.Trans.Identity (IdentityT)+import Control.Monad.Trans.Maybe (MaybeT)+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import Control.Monad.Trans.Reader (ReaderT)+import Control.Monad.Trans.Select (SelectT)+import qualified Control.Monad.Trans.Select as Select+import qualified Control.Monad.Trans.State.Lazy as LazyState+import qualified Control.Monad.Trans.State.Strict as StrictState+import qualified Control.Monad.Trans.Writer.CPS as CPSWriter+import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter+import qualified Control.Monad.Trans.Writer.Strict as StrictWriter+import Data.Functor.Identity (Identity)+import Data.Kind (Type)++-- | The capability to search with backtracking. Essentially describes a+-- \'policy function\': given the state of the search (and a \'ranking\' or+-- \'evaluation\' of each possible result so far), pick the result that's+-- currently best.+--+-- = Laws+--+-- Any instance of 'MonadSelect' must follow these laws:+--+-- * @'select' ('const' x)@ @=@ @'pure' x@+-- * @'select' f '*>' 'select' g@ @=@ @'select' g@+--+-- @since 2.3+class (Monad m) => MonadSelect r m | m -> r where+  select :: ((a -> r) -> a) -> m a++-- | @since 2.3+instance MonadSelect r (SelectT r Identity) where+  select = Select.select++-- | \'Extends\' the possibilities considered by @m@ to include 'Nothing'; this+-- means that 'Nothing' gains a \'rank\' (namely, a value of @r@), and the+-- potential result could also be 'Nothing'.+--+-- @since 2.3+deriving via+  (LiftingSelect MaybeT m)+  instance+    (MonadSelect r m) =>+    MonadSelect r (MaybeT m)++-- | The continuation describes a way of choosing a \'search\' or \'ranking\'+-- strategy for @r@, based on a \'ranking\' using @r'@, given any @a@. We then+-- get a \'search\' strategy for @r@.+--+-- @since 2.3+deriving via+  (LiftingSelect (ContT r) m)+  instance+    (MonadSelect r' m) =>+    MonadSelect r' (ContT r m)++-- | \'Extends\' the possibilities considered by @m@ to include every value of+-- @e@; this means that the potential result could be either a 'Left' (making it+-- a choice of type @e@) or a 'Right' (making it a choice of type @a@).+--+-- @since 2.3+deriving via+  (LiftingSelect (ExceptT e) m)+  instance+    (MonadSelect r m) =>+    MonadSelect r (ExceptT e m)++-- | @since 2.3+deriving via+  (LiftingSelect IdentityT m)+  instance+    (MonadSelect r m) =>+    MonadSelect r (IdentityT m)++-- | Provides a read-only environment of type @r@ to the \'strategy\' function.+-- However, the \'ranking\' function (or more accurately, representation) has no+-- access to @r@. Put another way, you can influence what values get chosen by+-- changing @r@, but not how solutions are ranked.+--+-- @since 2.3+deriving via+  (LiftingSelect (ReaderT r) m)+  instance+    (MonadSelect r' m) =>+    MonadSelect r' (ReaderT r m)++-- | \'Readerizes\' the state: the \'ranking\' function can /see/ a value of+-- type @s@, but not modify it. Effectively, can be thought of as \'extending\'+-- the \'ranking\' by all values in @s@, but /which/ @s@ gets given to any rank+-- calls is predetermined by the \'outer state\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (LazyState.StateT s) m)+  instance+    (MonadSelect w m) =>+    MonadSelect w (LazyState.StateT s m)++-- | \'Readerizes\' the state: the \'ranking\' function can /see/ a value of+-- type @s@, but not modify it. Effectively, can be thought of as \'extending\'+-- the \'ranking\' by all values in @s@, but /which/ @s@ gets given to any rank+-- calls is predetermined by the \'outer state\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (StrictState.StateT s) m)+  instance+    (MonadSelect w m) =>+    MonadSelect w (StrictState.StateT s m)++-- | \'Readerizes\' the writer: the \'ranking\' function can see the value+-- that's been accumulated (of type @w@), but can't add anything to the log.+-- Effectively, can be thought of as \'extending\' the \'ranking\' by all values+-- of @w@, but /which/ @w@ gets given to any rank calls is predetermined by the+-- \'outer writer\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (CPSWriter.WriterT w) m)+  instance+    (MonadSelect w' m) =>+    MonadSelect w' (CPSWriter.WriterT w m)++-- | \'Readerizes\' the writer: the \'ranking\' function can see the value+-- that's been accumulated (of type @w@), but can't add anything to the log.+-- Effectively, can be thought of as \'extending\' the \'ranking\' by all values+-- of @w@, but /which/ @w@ gets given to any rank calls is predetermined by the+-- \'outer writer\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (LazyWriter.WriterT w) m)+  instance+    (MonadSelect w' m, Monoid w) =>+    MonadSelect w' (LazyWriter.WriterT w m)++-- | \'Readerizes\' the writer: the \'ranking\' function can see the value+-- that's been accumulated (of type @w@), but can't add anything to the log.+-- Effectively, can be thought of as \'extending\' the \'ranking\' by all values+-- of @w@, but /which/ @w@ gets given to any rank calls is predetermined by the+-- \'outer writer\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (StrictWriter.WriterT w) m)+  instance+    (MonadSelect w' m, Monoid w) =>+    MonadSelect w' (StrictWriter.WriterT w m)++-- | A combination of an \'outer\' 'ReaderT', 'WriterT' and 'StateT'. In short,+-- you get a value of type @r@ which can influence what gets picked, but not how+-- anything is ranked, and the \'ranking\' function gets access to an @s@ and a+-- @w@, but can modify neither.+--+-- @since 2.3+deriving via+  (LiftingSelect (CPSRWS.RWST r w s) m)+  instance+    (MonadSelect w' m) =>+    MonadSelect w' (CPSRWS.RWST r w s m)++-- | A combination of an \'outer\' 'ReaderT', 'WriterT' and 'StateT'. In short,+-- you get a value of type @r@ which can influence what gets picked, but not how+-- anything is ranked, and the \'ranking\' function gets access to an @s@ and a+-- @w@, but can modify neither.+--+-- @since 2.3+deriving via+  (LiftingSelect (LazyRWS.RWST r w s) m)+  instance+    (MonadSelect w' m, Monoid w) =>+    MonadSelect w' (LazyRWS.RWST r w s m)++-- | A combination of an \'outer\' 'ReaderT', 'WriterT' and 'StateT'. In short,+-- you get a value of type @r@ which can influence what gets picked, but not how+-- anything is ranked, and the \'ranking\' function gets access to an @s@ and a+-- @w@, but can modify neither.+--+-- @since 2.3+deriving via+  (LiftingSelect (StrictRWS.RWST r w s) m)+  instance+    (MonadSelect w' m, Monoid w) =>+    MonadSelect w' (StrictRWS.RWST r w s m)++-- | \'Readerizes\' the accumulator: the \'ranking\' function can see the value+-- that has been accumulated (of type @w@), but can't add anything to it.+-- Effectively, can be thought of as \'extending\' the \'ranking\' by all values+-- of @w@, but /which/ @w@ gets given to any rank calls is predetermined by the+-- \'outer accumulation\' (and cannot change).+--+-- @since 2.3+deriving via+  (LiftingSelect (AccumT w) m)+  instance+    (MonadSelect r m, Monoid w) =>+    MonadSelect r (AccumT w m)++-- | A helper type to decrease boilerplate when defining new transformer+-- instances of 'MonadSelect'.+--+-- Most of the instances in this module are derived using this method; for+-- example, our instance of 'ExceptT' is derived as follows:+--+-- > deriving via (LiftingSelect (ExceptT e) m) instance (MonadSelect r m) =>+-- >  MonadSelect r (ExceptT e m)+--+-- @since 2.3+newtype LiftingSelect (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) (a :: Type)+  = LiftingSelect (t m a)+  deriving+    ( -- | @since 2.3+      Functor,+      -- | @since 2.3+      Applicative,+      -- | @since 2.3+      Monad+    )+    via (t m)++-- | @since 2.3+instance (MonadTrans t, MonadSelect r m, Monad (t m)) => MonadSelect r (LiftingSelect t m) where+  select f = LiftingSelect . lift $ select f
Control/Monad/State.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.State
Control/Monad/State/Class.hs view
@@ -1,9 +1,13 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-} -- Search for UndecidableInstances to see why this is needed+{-# LANGUAGE UndecidableInstances #-}+-- Needed because the CPSed versions of Writer and State are secretly State+-- wrappers, which don't force such constraints, even though they should legally+-- be there.+{-# OPTIONS_GHC -Wno-redundant-constraints #-}  ----------------------------------------------------------------------------- -- |@@ -32,23 +36,22 @@     gets   ) where -import Control.Monad.Trans.Cont-import Control.Monad.Trans.Error-import Control.Monad.Trans.Except-import Control.Monad.Trans.Identity-import Control.Monad.Trans.List-import Control.Monad.Trans.Maybe-import Control.Monad.Trans.Reader-import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, get, put, state)-import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, get, put, state)-import qualified Control.Monad.Trans.State.Lazy as Lazy (StateT, get, put, state)-import qualified Control.Monad.Trans.State.Strict as Strict (StateT, get, put, state)-import Control.Monad.Trans.Writer.Lazy as Lazy-import Control.Monad.Trans.Writer.Strict as Strict-+import Control.Monad.Trans.Cont (ContT)+import Control.Monad.Trans.Except (ExceptT)+import Control.Monad.Trans.Identity (IdentityT)+import Control.Monad.Trans.Maybe (MaybeT) +import Control.Monad.Trans.Reader (ReaderT)+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS+import qualified Control.Monad.Trans.State.Lazy as Lazy+import qualified Control.Monad.Trans.State.Strict as Strict+import qualified Control.Monad.Trans.Writer.Lazy as Lazy+import qualified Control.Monad.Trans.Writer.Strict as Strict+import Control.Monad.Trans.Accum (AccumT)+import Control.Monad.Trans.Select (SelectT)+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.Writer.CPS as CPS import Control.Monad.Trans.Class (lift)-import Control.Monad-import Data.Monoid  -- --------------------------------------------------------------------------- @@ -69,9 +72,7 @@       let ~(a, s') = f s       put s'       return a-#if __GLASGOW_HASKELL__ >= 707     {-# MINIMAL state | get, put #-}-#endif  -- | Monadic state transformer. --@@ -113,6 +114,12 @@     put = Strict.put     state = Strict.state +-- | @since 2.3+instance (Monad m, Monoid w) => MonadState s (CPSRWS.RWST r w s m) where+    get = CPSRWS.get+    put = CPSRWS.put+    state = CPSRWS.state+ instance (Monad m, Monoid w) => MonadState s (LazyRWS.RWST r w s m) where     get = LazyRWS.get     put = LazyRWS.put@@ -134,11 +141,6 @@     put = lift . put     state = lift . state -instance (Error e, MonadState s m) => MonadState s (ErrorT e m) where-    get = lift get-    put = lift . put-    state = lift . state- -- | @since 2.2 instance MonadState s m => MonadState s (ExceptT e m) where     get = lift get@@ -150,17 +152,18 @@     put = lift . put     state = lift . state -instance MonadState s m => MonadState s (ListT m) where+instance MonadState s m => MonadState s (MaybeT m) where     get = lift get     put = lift . put     state = lift . state -instance MonadState s m => MonadState s (MaybeT m) where+instance MonadState s m => MonadState s (ReaderT r m) where     get = lift get     put = lift . put     state = lift . state -instance MonadState s m => MonadState s (ReaderT r m) where+-- | @since 2.3+instance (Monoid w, MonadState s m) => MonadState s (CPS.WriterT w m) where     get = lift get     put = lift . put     state = lift . state@@ -171,6 +174,21 @@     state = lift . state  instance (Monoid w, MonadState s m) => MonadState s (Strict.WriterT w m) where+    get = lift get+    put = lift . put+    state = lift . state++-- | @since 2.3+instance+  ( Monoid w+  , MonadState s m+  ) => MonadState s (AccumT w m) where+    get = lift get+    put = lift . put+    state = lift . state++-- | @since 2.3+instance MonadState s m => MonadState s (SelectT r m) where     get = lift get     put = lift . put     state = lift . state
Control/Monad/State/Lazy.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.State.Lazy@@ -20,10 +21,10 @@  module Control.Monad.State.Lazy (     -- * MonadState class-    MonadState(..),-    modify,-    modify',-    gets,+    MonadState.MonadState(..),+    MonadState.modify,+    MonadState.modify',+    MonadState.gets,     -- * The State monad     State,     runState,@@ -38,22 +39,17 @@     execStateT,     mapStateT,     withStateT,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,     -- * Examples     -- $examples   ) where -import Control.Monad.State.Class-+import qualified Control.Monad.State.Class as MonadState import Control.Monad.Trans+ import Control.Monad.Trans.State.Lazy         (State, runState, evalState, execState, mapState, withState,          StateT(StateT), runStateT, evalStateT, execStateT, mapStateT, withStateT)--import Control.Monad-import Control.Monad.Fix  -- --------------------------------------------------------------------------- -- $examples
Control/Monad/State/Strict.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.State.Strict@@ -20,10 +21,10 @@  module Control.Monad.State.Strict (     -- * MonadState class-    MonadState(..),-    modify,-    modify',-    gets,+    MonadState.MonadState(..),+    MonadState.modify,+    MonadState.modify',+    MonadState.gets,     -- * The State monad     State,     runState,@@ -38,22 +39,17 @@     execStateT,     mapStateT,     withStateT,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,     -- * Examples     -- $examples   ) where -import Control.Monad.State.Class-+import qualified Control.Monad.State.Class as MonadState import Control.Monad.Trans+ import Control.Monad.Trans.State.Strict         (State, runState, evalState, execState, mapState, withState,          StateT(StateT), runStateT, evalStateT, execStateT, mapStateT, withStateT)--import Control.Monad-import Control.Monad.Fix  -- --------------------------------------------------------------------------- -- $examples
Control/Monad/Trans.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.Trans
Control/Monad/Writer.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE Safe #-}+ ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.Writer
+ Control/Monad/Writer/CPS.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE Safe #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Control.Monad.Writer.Strict+-- Copyright   :  (c) Andy Gill 2001,+--                (c) Oregon Graduate Institute of Science and Technology, 2001+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  experimental+-- Portability :  non-portable (multi-param classes, functional dependencies)+--+-- Strict writer monads that use continuation-passing-style to achieve constant+-- space usage.+--+--      Inspired by the paper+--      /Functional Programming with Overloading and Higher-Order Polymorphism/,+--        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>)+--          Advanced School of Functional Programming, 1995.+--+-- /Since: mtl-2.3, transformers-0.5.6/+-----------------------------------------------------------------------------++module Control.Monad.Writer.CPS (+    -- * MonadWriter class+    MonadWriter.MonadWriter(..),+    MonadWriter.listens,+    MonadWriter.censor,+    -- * The Writer monad+    Writer,+    runWriter,+    execWriter,+    mapWriter,+    -- * The WriterT monad transformer+    WriterT,+    execWriterT,+    mapWriterT,+    module Control.Monad.Trans,+  ) where++import qualified Control.Monad.Writer.Class as MonadWriter+import Control.Monad.Trans+import Control.Monad.Trans.Writer.CPS (+        Writer, runWriter, execWriter, mapWriter,+        WriterT, execWriterT, mapWriterT)
Control/Monad/Writer/Class.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE Safe #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -30,25 +30,24 @@     censor,   ) where -import Control.Monad.Trans.Error as Error-import Control.Monad.Trans.Except as Except-import Control.Monad.Trans.Identity as Identity-import Control.Monad.Trans.Maybe as Maybe-import Control.Monad.Trans.Reader-import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (-        RWST, writer, tell, listen, pass)-import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (-        RWST, writer, tell, listen, pass)-import Control.Monad.Trans.State.Lazy as Lazy-import Control.Monad.Trans.State.Strict as Strict-import qualified Control.Monad.Trans.Writer.Lazy as Lazy (-        WriterT, writer, tell, listen, pass)-import qualified Control.Monad.Trans.Writer.Strict as Strict (-        WriterT, writer, tell, listen, pass)-+import Control.Monad.Trans.Except (ExceptT)+import qualified Control.Monad.Trans.Except as Except+import Control.Monad.Trans.Identity (IdentityT)+import qualified Control.Monad.Trans.Identity as Identity+import Control.Monad.Trans.Maybe (MaybeT)+import qualified Control.Monad.Trans.Maybe as Maybe+import Control.Monad.Trans.Reader (ReaderT, mapReaderT)+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS +import qualified Control.Monad.Trans.RWS.Strict as StrictRWS +import qualified Control.Monad.Trans.State.Lazy as Lazy+import qualified Control.Monad.Trans.State.Strict as Strict+import qualified Control.Monad.Trans.Writer.Lazy as Lazy+import qualified Control.Monad.Trans.Writer.Strict as Strict +import Control.Monad.Trans.Accum (AccumT)+import qualified Control.Monad.Trans.Accum as Accum+import qualified Control.Monad.Trans.RWS.CPS as CPSRWS+import qualified Control.Monad.Trans.Writer.CPS as CPS import Control.Monad.Trans.Class (lift)-import Control.Monad-import Data.Monoid  -- --------------------------------------------------------------------------- -- MonadWriter class@@ -63,9 +62,7 @@ -- the written object.  class (Monoid w, Monad m) => MonadWriter w m | m -> w where-#if __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@@ -103,17 +100,20 @@     a <- m     return (a, f) -#if MIN_VERSION_base(4,9,0)--- | __NOTE__: This instance is only defined for @base >= 4.9.0@.------ @since 2.2.2+-- | @since 2.2.2 instance (Monoid w) => MonadWriter w ((,) w) where   writer ~(a, w) = (w, a)   tell w = (w, ())   listen ~(w, a) = (w, (a, w))   pass ~(w, (a, f)) = (f w, a)-#endif +-- | @since 2.3+instance (Monoid w, Monad m) => MonadWriter w (CPS.WriterT w m) where+    writer = CPS.writer+    tell   = CPS.tell+    listen = CPS.listen+    pass   = CPS.pass+ instance (Monoid w, Monad m) => MonadWriter w (Lazy.WriterT w m) where     writer = Lazy.writer     tell   = Lazy.tell@@ -126,6 +126,13 @@     listen = Strict.listen     pass   = Strict.pass +-- | @since 2.3+instance (Monoid w, Monad m) => MonadWriter w (CPSRWS.RWST r w s m) where+    writer = CPSRWS.writer+    tell   = CPSRWS.tell+    listen = CPSRWS.listen+    pass   = CPSRWS.pass+ instance (Monoid w, Monad m) => MonadWriter w (LazyRWS.RWST r w s m) where     writer = LazyRWS.writer     tell   = LazyRWS.tell@@ -144,12 +151,6 @@ -- All of these instances need UndecidableInstances, -- because they do not satisfy the coverage condition. -instance (Error e, MonadWriter w m) => MonadWriter w (ErrorT e m) where-    writer = lift . writer-    tell   = lift . tell-    listen = Error.liftListen listen-    pass   = Error.liftPass pass- -- | @since 2.2 instance MonadWriter w m => MonadWriter w (ExceptT e m) where     writer = lift . writer@@ -186,3 +187,21 @@     tell   = lift . tell     listen = Strict.liftListen listen     pass   = Strict.liftPass pass++-- | There are two valid instances for 'AccumT'. It could either:+--+--   1. Lift the operations to the inner @MonadWriter@+--   2. Handle the operations itself, à la a @WriterT@.+--+--   This instance chooses (1), reflecting that the intent+--   of 'AccumT' as a type is different than that of @WriterT@.+--+-- @since 2.3+instance+  ( Monoid w+  , MonadWriter w m+  ) => MonadWriter w (AccumT w m) where+    writer = lift . writer+    tell   = lift . tell+    listen = Accum.liftListen listen+    pass   = Accum.liftPass pass
Control/Monad/Writer/Lazy.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.Writer.Lazy@@ -19,9 +20,9 @@  module Control.Monad.Writer.Lazy (     -- * MonadWriter class-    MonadWriter(..),-    listens,-    censor,+    MonadWriter.MonadWriter(..),+    MonadWriter.listens,+    MonadWriter.censor,     -- * The Writer monad     Writer,     runWriter,@@ -32,19 +33,11 @@     runWriterT,     execWriterT,     mapWriterT,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,-    module Data.Monoid,   ) where -import Control.Monad.Writer.Class-+import qualified Control.Monad.Writer.Class as MonadWriter import Control.Monad.Trans import Control.Monad.Trans.Writer.Lazy (         Writer, runWriter, execWriter, mapWriter,         WriterT(WriterT), runWriterT, execWriterT, mapWriterT)--import Control.Monad-import Control.Monad.Fix-import Data.Monoid
Control/Monad/Writer/Strict.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.Writer.Strict@@ -19,9 +20,9 @@  module Control.Monad.Writer.Strict (     -- * MonadWriter class-    MonadWriter(..),-    listens,-    censor,+    MonadWriter.MonadWriter(..),+    MonadWriter.listens,+    MonadWriter.censor,     -- * The Writer monad     Writer,     runWriter,@@ -31,19 +32,11 @@     WriterT(..),     execWriterT,     mapWriterT,-    module Control.Monad,-    module Control.Monad.Fix,     module Control.Monad.Trans,-    module Data.Monoid,   ) where -import Control.Monad.Writer.Class-+import qualified Control.Monad.Writer.Class as MonadWriter import Control.Monad.Trans import Control.Monad.Trans.Writer.Strict (         Writer, runWriter, execWriter, mapWriter,         WriterT(..), execWriterT, mapWriterT)--import Control.Monad-import Control.Monad.Fix-import Data.Monoid
README.markdown view
@@ -1,4 +1,149 @@-The `mtl` Package  [![Hackage](https://img.shields.io/hackage/v/mtl.svg)](https://hackage.haskell.org/package/mtl) [![Build Status](https://travis-ci.org/haskell/mtl.svg)](https://travis-ci.org/haskell/mtl)-=====================+# `mtl` [![Hackage](https://img.shields.io/hackage/v/mtl.svg)](https://hackage.haskell.org/package/mtl) [![Build Status](https://travis-ci.org/haskell/mtl.svg)](https://travis-ci.org/haskell/mtl) -See [`mtl` on Hackage](http://hackage.haskell.org/package/mtl) for more information.+MTL is a collection of monad classes, extending the `transformers`+package, using functional dependencies for generic lifting of monadic+actions.++## Structure++Transformers in MTL are divided into classes and data types. Classes+define the monadic operations of transformers. Data types, generally+from the `transformers` package, implement transformers, and MTL+provides instances for all the transformer type classes.++MTL and `transformers` use a common module, data type, and function+naming scheme. As an example, let's imagine we have a transformer+`Foo`.++In the `Control.Monad.Foo` module, we'd find:++* A type class `MonadFoo` with the transformer operations.+* A data type `FooT` with instances for all monad transformer classes.+* Functions to run the transformed computation, e.g. `runFooT`. For+  the actual transformers, there are usually a number of useful runner+  functions.++### Lifting++When using monad transformers, you often need to "lift" a monadic+action into your transformed monadic action. This is done using the+`lift` function from `MonadTrans` in the `Control.Monad.Trans.Class`+module:++``` haskell+lift :: (Monad m, MonadTrans t) => m a -> t m a+```++The action `m a` is lifted into the transformer action `t m a`.++As an example, here we lift an action of type `IO a` into an action of+type `ExceptT MyError IO a`:++``` haskell+data MyError = EmptyLine++mightFail :: ExceptT MyError IO ()+mightFail = do+  l <- lift getLine+  when (null l) (throwError EmptyLine)+```++### Transformers++The following outlines the available monad classes and transformers in+MTL and `transformers`. For more details, and the corresponding+documentation of the `mtl` version you are using, see [the+documentation on Hackage](https://hackage.haskell.org/package/mtl).++* `Control.Monad.Cont`++    The Continuation monad transformer adds the ability to use+    [continuation-passing style+    (CPS)](https://en.wikipedia.org/wiki/Continuation-passing_style)+    in a monadic computation. Continuations can be used to manipulate+    the control flow of a program, e.g. early exit, error handling, or+    suspending a computation.++    - Class: `Control.Monad.Cont.Class.MonadCont`+    - Transformer: `Control.Monad.Cont.ContT`++* `Control.Monad.Error` (deprecated!)++    The Error monad transformer has been deprecated in favor of+    `Control.Monad.Except`.++* `Control.Monad.Except`++    The Except monad transformer adds the ability to fail with an+    error in a monadic computation.++    - Class: `Control.Monad.Except.Class.MonadError`+    - Transformer: `Control.Monad.Except.ExceptT`++* `Control.Monad.Identity`++    The Identity monad transformer does not add any abilities to a+    monad. It simply applies the bound function to its inner monad+    without any modification.++    - Transformer: `Control.Monad.Trans.Identity.IdentityT` (in the `transformers` package)+    - Identity functor and monad: `Data.Functor.Identity.Identity` (in the `base` package)++* `Control.Monad.List`++    This transformer combines the list monad with another monad. _Note+    that this does not yield a monad unless the inner monad is+    [commutative](https://en.wikipedia.org/wiki/Commutative_property)._++    - Transformer: `Control.Monad.List.ListT`++* `Control.Monad.RWS`++    A convenient transformer that combines the Reader, Writer, and+    State monad transformers.++    - Lazy transformer: `Control.Monad.RWS.Lazy.RWST` (which is the default, exported by `Control.Monad.RWS`)+    - Strict transformer: `Control.Monad.RWS.Strict.RWST`++* `Control.Monad.Reader`++    The Reader monad transformer represents a computation which can+    read values from an environment.++    - Class: `Control.Monad.Reader.Class.MonadReader`+    - Transformer: `Control.Monad.Reader.ReaderT`++* `Control.Monad.State`++    The State monad transformer represents a computation which can+    read and write internal state values. If you only need to _read_+    values, you might want to use+    [Reader](http://hackage.haskell.org/package/mtl/docs/Control-Monad-Reader.html)+    instead.++    - Class: `Control.Monad.State.Class.MonadState`+    - Lazy transformer: `Control.Monad.State.Lazy.StateT` (the default, exported by `Control.Monad.State`)+    - Strict transformer: `Control.Monad.State.Strict.StateT`++* `Control.Monad.Writer`++    The Writer monad transformer represents a computation that can+    produce a stream of data in addition to the computed values. This+    can be used to collect values in some data structure with a+    `Monoid` instance. This can be used for things like logging and+    accumulating values throughout a computation.++    - Class: `Control.Monad.Writer.Class.MonadWriter`+    - Lazy transformers: `Control.Monad.Writer.Lazy.WriterT`+    - Strict transformers: `Control.Monad.Writer.Strict.WriterT`++## Resources++* [`mtl` on Hackage](http://hackage.haskell.org/package/mtl)+* The [Monad Transformers](http://dev.stephendiehl.com/hask/#monad-transformers)+  chapter in "What I Wish I Knew When Learning Haskell".+* References:+    - This package is inspired by the paper _Functional Programming+      with Overloading and Higher-Order Polymorphism_, by Mark P+      Jones, in _Advanced School of Functional Programming_, 1995+      (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).
mtl.cabal view
@@ -1,33 +1,29 @@-name:         mtl-version:      2.2.2-cabal-version: >= 1.10-license:      BSD3-license-file: LICENSE-author:       Andy Gill-maintainer:   Edward Kmett <ekmett@gmail.com>-category:     Control-synopsis:     Monad classes, using functional dependencies-homepage:     http://github.com/haskell/mtl-bug-reports:  http://github.com/haskell/mtl/issues+cabal-version: 3.0+name:          mtl+version:       2.3+license:       BSD-3-Clause+license-file:  LICENSE+author:        Andy Gill+maintainer:    chessai <chessai1996@gmail.com>, +               Emily Pillmore <emilypi@cohomolo.gy>, +               Koz Ross <koz.ross@retro-freedom.nz>+category:      Control+synopsis:      Monad classes for transformers, using functional dependencies+homepage:      http://github.com/haskell/mtl+bug-reports:   http://github.com/haskell/mtl/issues description:-    Monad classes using functional dependencies, with instances-    for various monad transformers, inspired by the paper-    /Functional Programming with Overloading and Higher-Order Polymorphism/,-    by Mark P Jones, in /Advanced School of Functional Programming/, 1995-    (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).+  MTL is a collection of monad classes, extending the 'transformers'+  package, using functional dependencies for generic lifting of+  monadic actions.+ build-type: Simple-extra-source-files: CHANGELOG.markdown, README.markdown-tested-with:-  GHC==7.0.4,-  GHC==7.2.2,-  GHC==7.4.2,-  GHC==7.6.3,-  GHC==7.8.4,-  GHC==7.10.3,-  GHC==8.0.2,-  GHC==8.2.2,-  GHC==8.4.1 +extra-source-files: +  CHANGELOG.markdown+  README.markdown++tested-with: GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.2+ source-repository head   type: git   location: https://github.com/haskell/mtl.git@@ -36,13 +32,12 @@   exposed-modules:     Control.Monad.Cont     Control.Monad.Cont.Class-    Control.Monad.Error     Control.Monad.Error.Class     Control.Monad.Except     Control.Monad.Identity-    Control.Monad.List     Control.Monad.RWS     Control.Monad.RWS.Class+    Control.Monad.RWS.CPS     Control.Monad.RWS.Lazy     Control.Monad.RWS.Strict     Control.Monad.Reader@@ -54,24 +49,20 @@     Control.Monad.Trans     Control.Monad.Writer     Control.Monad.Writer.Class+    Control.Monad.Writer.CPS     Control.Monad.Writer.Lazy     Control.Monad.Writer.Strict-  build-depends: base < 5, transformers >= 0.4 && <0.6--  default-language: Haskell2010-  other-extensions:-    CPP-    MultiParamTypeClasses-    FunctionalDependencies-    FlexibleInstances-    UndecidableInstances+    Control.Monad.Accum+    Control.Monad.Select+  +  build-depends: +    , base >=4.12 && < 5+    , transformers >= 0.5.6 && <0.7 -  -- This is a SafeHaskell safeguard (pun intended) to explicitly declare the API contract of `mtl`-  -- GHC versions before 7.4 were hopelessly broken or incapable of SafeHaskell-  if impl(ghc >= 7.4)-    default-extensions: Safe+  ghc-options: +    -Wall -Wcompat -Wincomplete-record-updates+    -Wincomplete-uni-patterns -Wredundant-constraints+    -Wmissing-export-lists -  ghc-options: -Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations+  default-language: Haskell2010 -  if impl(ghc >= 8.0)-    ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances