transformers 0.6.1.0 → 0.6.1.1
raw patch · 11 files changed
+281/−42 lines, 11 files
Files
- Control/Monad/Trans/Accum.hs +34/−17
- Control/Monad/Trans/Class.hs +9/−6
- Control/Monad/Trans/Reader.hs +10/−4
- Control/Monad/Trans/Writer/CPS.hs +12/−5
- Control/Monad/Trans/Writer/Lazy.hs +12/−4
- Control/Monad/Trans/Writer/Strict.hs +12/−4
- changelog +3/−0
- images/bind-AccumT.svg +66/−0
- images/bind-ReaderT.svg +57/−0
- images/bind-WriterT.svg +60/−0
- transformers.cabal +6/−2
Control/Monad/Trans/Accum.hs view
@@ -18,10 +18,12 @@ -- -- The lazy 'AccumT' monad transformer, which adds accumulation -- capabilities (such as declarations or document patches) to a given monad.+-- Each computation has access to the combination of the input environment+-- and outputs added so far, and returns the outputs added. ----- This monad transformer provides append-only accumulation--- during the computation. For more general access, use--- "Control.Monad.Trans.State" instead.+-- In applications requiring only the ability to accumulate an output and+-- to inspect the output so far, it would be considerably more efficient+-- to use "Control.Monad.Trans.State" instead. ----------------------------------------------------------------------------- module Control.Monad.Trans.Accum (@@ -78,8 +80,16 @@ -- --------------------------------------------------------------------------- -- | An accumulation monad parameterized by the type @w@ of output to accumulate. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.+-- This monad is a more complex extension of both the reader and writer+-- monads. The 'return' function produces the output 'mempty', while @m+-- '>>=' k@ uses the output of @m@ both to extend the initial environment+-- of @k@ and to combine with the output of @k@:+--+-- <<images/bind-AccumT.svg>>+--+-- In applications requiring only the ability to accumulate an output and+-- to inspect the output so far, it would be considerably more efficient+-- to use a state monad. type Accum w = AccumT w Identity -- | Construct an accumulation computation from a (result, output) pair.@@ -124,21 +134,28 @@ -- -- * @m@ - The inner monad. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.------ This monad transformer is similar to both state and writer monad transformers.--- Thus it can be seen as+-- This monad transformer is a more complex extension of both the reader+-- and writer monad transformers. The 'return' function produces the+-- output 'mempty', while @m '>>=' k@ uses the output of @m@ both to+-- extend the initial environment of @k@ and to combine with the output+-- of @k@: ----- * a restricted append-only version of a state monad transformer or+-- <<images/bind-AccumT.svg>> ----- * a writer monad transformer with the extra ability to read all previous output.+-- In applications requiring only the ability to accumulate an output and+-- to inspect the output so far, it would be considerably more efficient+-- to use a state monad transformer. newtype AccumT w m a = AccumT (w -> m (a, w)) #if __GLASGOW_HASKELL__ >= 704 deriving (Generic) #endif --- | Unwrap an accumulation computation.+-- | Unwrap an accumulation computation. For example, in the call+--+-- @ (value, locals) <- runAccumT action globals@+--+-- the action is fed an initial environment @globals@, and @locals@ is+-- the sum of all arguments to calls of 'add' executed by the action. runAccumT :: AccumT w m a -> w -> m (a, w) runAccumT (AccumT f) = f {-# INLINE runAccumT #-}@@ -152,8 +169,8 @@ return w' {-# INLINE execAccumT #-} --- | Evaluate an accumulation computation with the given initial output history--- and return the final value, discarding the final output.+-- | Evaluate an accumulation computation with the given initial output+-- history and return the final value, discarding the final output. -- -- * @'evalAccumT' m w = 'liftM' 'fst' ('runAccumT' m w)@ evalAccumT :: (Monad m, Monoid w) => AccumT w m a -> w -> m a@@ -162,8 +179,8 @@ return a {-# INLINE evalAccumT #-} --- | Map both the return value and output of a computation using--- the given function.+-- | Map both the return value and output of a computation using the+-- given function. -- -- * @'runAccumT' ('mapAccumT' f m) = f . 'runAccumT' m@ mapAccumT :: (m (a, w) -> n (b, w)) -> AccumT w m a -> AccumT w n b
Control/Monad/Trans/Class.hs view
@@ -87,15 +87,18 @@ lift :: (Monad m) => m a -> t m a {- $conventions-Most monad transformer modules include the special case of applying-the transformer to 'Data.Functor.Identity.Identity'. For example,+All monad transformer modules except 'Control.Monad.Trans.Maybe'+include the special case of applying the transformer+to 'Data.Functor.Identity.Identity'. For example, @'Control.Monad.Trans.State.Lazy.State' s@ is an abbreviation for @'Control.Monad.Trans.State.Lazy.StateT' s 'Data.Functor.Identity.Identity'@.+As a consequence, operations defined on the monad transformer can also+be used on this special case. Each monad transformer also comes with an operation @run@/XXX/@T@ to unwrap the transformer, exposing a computation of the inner monad.-(Currently these functions are defined as field labels, but in the next-major release they will be separate functions.)+(Currently these functions are defined as field labels, but in a future+major release they may be separate functions.) All of the monad transformers except 'Control.Monad.Trans.Cont.ContT' and 'Control.Monad.Trans.Cont.SelectT' are functors on the category@@ -134,7 +137,7 @@ >>> undefined >> print 2 *** Exception: Prelude.undefined -However the monads 'Data.Functor.Identity.Identity' and @(->) a@ are not:+However, the monads 'Data.Functor.Identity.Identity' and @(->) a@ are not: >>> undefined >> Identity 2 Identity 2@@ -143,7 +146,7 @@ In a strict monad you know when each action is executed, but the monad is not necessarily strict in the return value, or in other components-of the monad, such as a state. However you can use 'seq' to create+of the monad, such as a state. However, you can use 'seq' to create an action that is strict in the component you want evaluated. -}
Control/Monad/Trans/Reader.hs view
@@ -75,8 +75,11 @@ -- -- Computations are functions of a shared environment. ----- The 'return' function ignores the environment, while @>>=@ passes--- the inherited environment to both subcomputations.+-- The 'return' function ignores the environment, while @m '>>=' k@+-- passes the inherited environment to both subcomputations:+--+-- <<images/bind-ReaderT.svg>>+-- type Reader r = ReaderT r Identity -- | Constructor for computations in the reader monad (equivalent to 'asks').@@ -114,8 +117,11 @@ -- | The reader monad transformer, -- which adds a read-only environment to the given monad. ----- The 'return' function ignores the environment, while @>>=@ passes--- the inherited environment to both subcomputations.+-- The 'return' function ignores the environment, while @m '>>=' k@+-- passes the inherited environment to both subcomputations:+--+-- <<images/bind-ReaderT.svg>>+-- newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a } #if __GLASGOW_HASKELL__ >= 710 deriving (Generic, Generic1)
Control/Monad/Trans/Writer/CPS.hs view
@@ -76,8 +76,12 @@ -- --------------------------------------------------------------------------- -- | A writer monad parameterized by the type @w@ of output to accumulate. ----- The 'return' function produces the output 'mempty', while '>>='--- combines the outputs of the subcomputations using 'mappend'.+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- type Writer w = WriterT w Identity -- | Construct a writer computation from a (result, output) pair.@@ -116,9 +120,12 @@ -- -- * @m@ - The inner monad. ----- The 'return' function produces the output 'mempty', while '>>='--- combines the outputs of the subcomputations using 'mappend'.-+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- newtype WriterT w m a = WriterT { unWriterT :: w -> m (a, w) } #if __GLASGOW_HASKELL__ >= 704 deriving (Generic)
Control/Monad/Trans/Writer/Lazy.hs view
@@ -81,8 +81,12 @@ -- --------------------------------------------------------------------------- -- | A writer monad parameterized by the type @w@ of output to accumulate. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- type Writer w = WriterT w Identity -- | Construct a writer computation from a (result, output) pair.@@ -119,8 +123,12 @@ -- -- * @m@ - The inner monad. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- newtype WriterT w m a = WriterT { runWriterT :: m (a, w) } #if __GLASGOW_HASKELL__ >= 704 deriving (Generic)
Control/Monad/Trans/Writer/Strict.hs view
@@ -84,8 +84,12 @@ -- --------------------------------------------------------------------------- -- | A writer monad parameterized by the type @w@ of output to accumulate. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- type Writer w = WriterT w Identity -- | Construct a writer computation from a (result, output) pair.@@ -122,8 +126,12 @@ -- -- * @m@ - The inner monad. ----- The 'return' function produces the output 'mempty', while @>>=@--- combines the outputs of the subcomputations using 'mappend'.+-- The 'return' function produces the output 'mempty', while @m '>>=' k@+-- combines the outputs of the subcomputations using 'mappend' (also+-- known as @<>@):+--+-- <<images/bind-WriterT.svg>>+-- newtype WriterT w m a = WriterT { runWriterT :: m (a, w) } #if __GLASGOW_HASKELL__ >= 704 deriving (Generic)
changelog view
@@ -1,5 +1,8 @@ -*-change-log-*- +0.6.1.1 Ross Paterson <R.Paterson@city.ac.uk> Aug 2023+ * Additions to documentation, especially of AccumT.+ 0.6.1.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2023 * Add instances of Foldable1 (class added to base-4.18) * Add modifyM to StateT transformers
+ images/bind-AccumT.svg view
@@ -0,0 +1,66 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">+<svg width="390" height="180"+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">++<defs>+ <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <style type="text/css">+ line.arrow {+ fill: none; stroke: black; stroke-width: 4;+ marker-end: url(#arrow);+ }+ circle.action {+ fill: #f8ddbb; stroke: black; stroke-width: 4;+ }+ text.action {+ fill: black; stroke: none;+ font-family: sans-serif; font-size: 35px;+ dominant-baseline: central; text-anchor: middle;+ }+ .extra {+ fill: none; stroke: #44f; stroke-width: 3;+ marker-end: url(#extra-arrow);+ }+ circle.mappend {+ fill: none; stroke: #44f; stroke-width: 3;+ }+ text.mappend {+ fill: #44f; stroke: none;+ font-family: sans-serif; font-size: 26px;+ dominant-baseline: central; text-anchor: middle;+ }+ </style>+</defs>+<g transform="scale(0.6) translate(50,50)">+ <path class="extra" d="M 0,0 L 80,0 A 20 20 0 0 1 100,20 L 100,52"/>+ <path class="extra" d="M 80,0 L 225,0"/>+ <circle class="mappend" cx="250" cy="0" r="20"/>+ <text class="mappend" x="250" y="0"><></text>+ <path class="extra" d="M 270,0 L 380,0 A 20 20 0 0 1 400,20 L 400,52"/>+ <path class="extra" d="M 230,200 A 20 20 0 0 0 250,180 L 250,27"/>+ <path class="extra" d="M 100,140 L 100,180 A 20 20 0 0 0 120,200 L 373,200"/>+ <circle class="mappend" cx="400" cy="200" r="20"/>+ <text class="mappend" x="400" y="200"><></text>+ <path class="extra" d="M 400,140 L 400,173"/>+ <path class="extra" d="M 420,200 L 550,200"/>+ <text class="mappend" x="15" y="-20">w</text>++ <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>+ <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>+ <circle class="action" cx="100" cy="100" r="40"/>+ <text class="action" x="100" y="100">m</text>+ <circle class="action" cx="400" cy="100" r="40"/>+ <text class="action" x="400" y="100">k</text>+</g>+</svg>
+ images/bind-ReaderT.svg view
@@ -0,0 +1,57 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">+<svg width="390" height="150"+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">++<defs>+ <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <style type="text/css">+ line.arrow {+ fill: none; stroke: black; stroke-width: 4;+ marker-end: url(#arrow);+ }+ circle.action {+ fill: #f8ddbb; stroke: black; stroke-width: 4;+ }+ text.action {+ fill: black; stroke: none;+ font-family: sans-serif; font-size: 35px;+ dominant-baseline: central; text-anchor: middle;+ }+ .extra {+ fill: none; stroke: #44f; stroke-width: 3;+ marker-end: url(#extra-arrow);+ }+ circle.mappend {+ fill: none; stroke: #44f; stroke-width: 3;+ }+ text.mappend {+ fill: #44f; stroke: none;+ font-family: sans-serif; font-size: 26px;+ dominant-baseline: central; text-anchor: middle;+ }+ </style>+</defs>+<g transform="scale(0.6) translate(50,50)">+ <path class="extra" d="M 0,0 L 80,0 A 20 20 0 0 1 100,20 L 100,52"/>+ <path class="extra" d="M 80,0 L 380,0 A 20 20 0 0 1 400,20 L 400,52"/>+ <text class="mappend" x="15" y="-20">r</text>++ <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>+ <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>+ <circle class="action" cx="100" cy="100" r="40"/>+ <text class="action" x="100" y="100">m</text>+ <circle class="action" cx="400" cy="100" r="40"/>+ <text class="action" x="400" y="100">k</text>+</g>+</svg>
+ images/bind-WriterT.svg view
@@ -0,0 +1,60 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">+<svg width="360" height="150"+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">++<defs>+ <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"+ markerWidth="5" markerHeight="5"+ orient="auto-start-reverse">+ <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />+ </marker>+ <style type="text/css">+ line.arrow {+ fill: none; stroke: black; stroke-width: 4;+ marker-end: url(#arrow);+ }+ circle.action {+ fill: #f8ddbb; stroke: black; stroke-width: 4;+ }+ text.action {+ fill: black; stroke: none;+ font-family: sans-serif; font-size: 35px;+ dominant-baseline: central; text-anchor: middle;+ }+ .extra {+ fill: none; stroke: #44f; stroke-width: 3;+ marker-end: url(#extra-arrow);+ }+ circle.mappend {+ fill: none; stroke: #44f; stroke-width: 3;+ }+ text.mappend {+ fill: #44f; stroke: none;+ font-family: sans-serif; font-size: 26px;+ dominant-baseline: central; text-anchor: middle;+ }+ </style>+</defs>+<g transform="scale(0.6)">+ <path class="extra" d="M 100,140 L 100,180 A 20 20 0 0 0 120,200 L 373,200"/>+ <circle class="mappend" cx="400" cy="200" r="20"/>+ <text class="mappend" x="400" y="200"><></text>+ <path class="extra" d="M 400,140 L 400,173"/>+ <path class="extra" d="M 420,200 L 550,200"/>+ <text class="mappend" x="520" y="180">w</text>++ <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>+ <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>+ <circle class="action" cx="100" cy="100" r="40"/>+ <text class="action" x="100" y="100">m</text>+ <circle class="action" cx="400" cy="100" r="40"/>+ <text class="action" x="400" y="100">k</text>+</g>+</svg>
transformers.cabal view
@@ -1,5 +1,5 @@ name: transformers-version: 0.6.1.0+version: 0.6.1.1 license: BSD3 license-file: LICENSE author: Andy Gill, Ross Paterson@@ -31,9 +31,13 @@ the @mtl@ or @monads-tf@ packages, which automatically lift operations introduced by monad transformers through other transformers. build-type: Simple+extra-doc-files:+ images/bind-AccumT.svg+ images/bind-ReaderT.svg+ images/bind-WriterT.svg extra-source-files: changelog-cabal-version: >= 1.10+cabal-version: 1.18 source-repository head type: darcs