@@ -17,6 +17,15 @@ module Ether.Writer
1717 , writerT
1818 , runWriterT
1919 , execWriterT
20+ -- * The Writer monad (lazy)
21+ , LazyWriter
22+ , runLazyWriter
23+ , execLazyWriter
24+ -- * The WriterT monad transformer (lazy)
25+ , LazyWriterT
26+ , lazyWriterT
27+ , runLazyWriterT
28+ , execLazyWriterT
2029 -- * MonadWriter class (implicit)
2130 , MonadWriter'
2231 , writer'
@@ -34,6 +43,15 @@ module Ether.Writer
3443 , writerT'
3544 , runWriterT'
3645 , execWriterT'
46+ -- * The Writer monad (lazy, implicit)
47+ , LazyWriter'
48+ , runLazyWriter'
49+ , execLazyWriter'
50+ -- * The WriterT monad transformer (lazy, implicit)
51+ , LazyWriterT'
52+ , lazyWriterT'
53+ , runLazyWriterT'
54+ , execLazyWriterT'
3755 -- * Internal labels
3856 , TAGGED
3957 , WRITER
@@ -44,11 +62,12 @@ import qualified Control.Monad.Trans.Lift.Listen as Lift
4462import qualified Control.Monad.Trans.Lift.Pass as Lift
4563import qualified Control.Monad.Writer.Class as T
4664import qualified Control.Monad.Writer.CPS as T.CPS
65+import qualified Control.Monad.Writer.Lazy as T.Lazy
4766import Data.Coerce
4867import Data.Functor.Identity
4968
50−import Ether.TaggedTrans
5169import Ether.Internal
70+import Ether.TaggedTrans
5271
5372class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
5473
@@ -106,6 +125,47 @@ censor f m = pass @tag $ do
106125-- | Encode type-level information for 'WriterT'.
107126data WRITER
108127
128+type instance HandleSuper WRITER w trans = Monoid w
129+type instance HandleConstraint WRITER w trans m =
130+ T.MonadWriter w (trans m)
131+
132+instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
133+ handling r = r
134+ {-# INLINE handling #-}
135+
136+instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
137+ handling r = r
138+ {-# INLINE handling #-}
139+
140+instance
141+ ( Handle WRITER w trans
142+ , Monad m, Monad (trans m)
143+ ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
144+ where
145+
146+ writer =
147+ handling @WRITER @w @trans @m $
148+ coerce (T.writer @w @(trans m) @a) ::
149+ forall eff a . (a, w) -> TaggedTrans eff trans m a
150+ {-# INLINE writer #-}
151+
152+ tell =
153+ handling @WRITER @w @trans @m $
154+ coerce (T.tell @w @(trans m))
155+ {-# INLINE tell #-}
156+
157+ listen =
158+ handling @WRITER @w @trans @m $
159+ coerce (T.listen @w @(trans m) @a) ::
160+ forall eff a . Listen w (TaggedTrans eff trans m) a
161+ {-# INLINE listen #-}
162+
163+ pass =
164+ handling @WRITER @w @trans @m $
165+ coerce (T.pass @w @(trans m) @a) ::
166+ forall eff a . Pass w (TaggedTrans eff trans m) a
167+ {-# INLINE pass #-}
168+
109169-- | The parametrizable writer monad.
110170--
111171-- Computations can accumulate a monoid value.
@@ -123,99 +183,145 @@ type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
123183-- | Constructor for computations in the writer monad transformer.
124184writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
125185writerT = coerce (T.CPS.writerT @m @w @a)
186+{-# INLINE writerT #-}
126187
127188-- | Runs a 'WriterT' and returns both the normal value
128189-- and the final accumulator.
129190runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
130191runWriterT = coerce (T.CPS.runWriterT @w @m @a)
192+{-# INLINE runWriterT #-}
131193
132194-- | Runs a 'Writer' and returns both the normal value
133195-- and the final accumulator.
134196runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
135197runWriter = coerce (T.CPS.runWriter @w @a)
198+{-# INLINE runWriter #-}
136199
137200-- | Runs a 'WriterT' and returns the final accumulator,
138201-- discarding the normal value.
139202execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
140203execWriterT = coerce (T.CPS.execWriterT @m @w @a)
204+{-# INLINE execWriterT #-}
141205
142206-- | Runs a 'Writer' and returns the final accumulator,
143207-- discarding the normal value.
144208execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
145209execWriter = coerce (T.CPS.execWriter @w @a)
210+{-# INLINE execWriter #-}
146211
147−type instance HandleSuper WRITER w trans = Monoid w
148−type instance HandleConstraint WRITER w trans m =
149− T.MonadWriter w (trans m)
212+-- | The parametrizable writer monad.
213+--
214+-- Computations can accumulate a monoid value.
215+--
216+-- The 'return' function produces the output 'mempty', while '>>=' combines
217+-- the outputs of the subcomputations using 'mappend'.
218+type LazyWriter tag w = LazyWriterT tag w Identity
150219
151−instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
152− handling r = r
153− {-# INLINE handling #-}
220+-- | The writer monad transformer.
221+--
222+-- The 'return' function produces the output 'mempty', while '>>=' combines
223+-- the outputs of the subcomputations using 'mappend'.
224+type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
154225
155−instance
156− ( Handle WRITER w trans
157− , Monad m, Monad (trans m)
158− ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
159− where
226+-- | Constructor for computations in the writer monad transformer.
227+lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
228+lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
229+{-# INLINE lazyWriterT #-}
160230
161− writer =
162− handling @WRITER @w @trans @m $
163− coerce (T.writer @w @(trans m) @a) ::
164− forall eff a . (a, w) -> TaggedTrans eff trans m a
165− {-# INLINE writer #-}
231+-- | Runs a 'WriterT' and returns both the normal value
232+-- and the final accumulator.
233+runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
234+runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
235+{-# INLINE runLazyWriterT #-}
166236
167− tell =
168− handling @WRITER @w @trans @m $
169− coerce (T.tell @w @(trans m))
170− {-# INLINE tell #-}
237+-- | Runs a 'Writer' and returns both the normal value
238+-- and the final accumulator.
239+runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
240+runLazyWriter = coerce (T.Lazy.runWriter @w @a)
241+{-# INLINE runLazyWriter #-}
171242
172− listen =
173− handling @WRITER @w @trans @m $
174− coerce (T.listen @w @(trans m) @a) ::
175− forall eff a . Listen w (TaggedTrans eff trans m) a
176− {-# INLINE listen #-}
243+-- | Runs a 'WriterT' and returns the final accumulator,
244+-- discarding the normal value.
245+execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
246+execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
247+{-# INLINE execLazyWriterT #-}
177248
178− pass =
179− handling @WRITER @w @trans @m $
180− coerce (T.pass @w @(trans m) @a) ::
181− forall eff a . Pass w (TaggedTrans eff trans m) a
182− {-# INLINE pass #-}
249+-- | Runs a 'Writer' and returns the final accumulator,
250+-- discarding the normal value.
251+execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
252+execLazyWriter = coerce (T.Lazy.execWriter @w @a)
253+{-# INLINE execLazyWriter #-}
183254
184255type Writer' w = Writer w w
185256
186257runWriter' :: Monoid w => Writer' w a -> (a, w)
187258runWriter' = runWriter
259+{-# INLINE runWriter' #-}
188260
189261execWriter' :: Monoid w => Writer' w a -> w
190262execWriter' = execWriter
263+{-# INLINE execWriter' #-}
191264
192265type WriterT' w = WriterT w w
193266
194267writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
195268writerT' = writerT
269+{-# INLINE writerT' #-}
196270
197271runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
198272runWriterT' = runWriterT
273+{-# INLINE runWriterT' #-}
199274
200275execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
201276execWriterT' = execWriterT
277+{-# INLINE execWriterT' #-}
278+
279+type LazyWriter' w = LazyWriter w w
280+
281+runLazyWriter' :: LazyWriter' w a -> (a, w)
282+runLazyWriter' = runLazyWriter
283+{-# INLINE runLazyWriter' #-}
284+
285+execLazyWriter' :: LazyWriter' w a -> w
286+execLazyWriter' = execLazyWriter
287+{-# INLINE execLazyWriter' #-}
288+
289+type LazyWriterT' w = LazyWriterT w w
290+
291+lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
292+lazyWriterT' = lazyWriterT
293+{-# INLINE lazyWriterT' #-}
294+
295+runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
296+runLazyWriterT' = runLazyWriterT
297+{-# INLINE runLazyWriterT' #-}
298+
299+execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
300+execLazyWriterT' = execLazyWriterT
301+{-# INLINE execLazyWriterT' #-}
202302
203303type MonadWriter' w = MonadWriter w w
204304
205305writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
206306writer' = writer @w
307+{-# INLINE writer' #-}
207308
208309tell' :: forall w m . MonadWriter' w m => w -> m ()
209310tell' = tell @w
311+{-# INLINE tell' #-}
210312
211313listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
212314listen' = listen @w
315+{-# INLINE listen' #-}
213316
214317pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
215318pass' = pass @w
319+{-# INLINE pass' #-}
216320
217321listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
218322listens' = listens @w
323+{-# INLINE listens' #-}
219324
220325censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
221326censor' = censor @w
327+{-# INLINE censor' #-}