on master help sign in
Add LazyWriterT
e715c92Vladislav Zavialov
src/Ether/State.hs+4−4
@@ -85,8 +85,8 @@ import Data.Kind
85import Data.Proxy
85import Data.Proxy
86import Data.Reflection
86import Data.Reflection
87
87
88−import Ether.TaggedTrans
89import Ether.Internal
88import Ether.Internal
89+import Ether.TaggedTrans
90
90
91class Monad m => MonadState tag s m | m tag -> s where
91class Monad m => MonadState tag s m | m tag -> s where
92
92
@@ -151,9 +151,6 @@ instance {-# OVERLAPPABLE #-}
151 (state @tag)
151 (state @tag)
152 {-# INLINE state #-}
152 {-# INLINE state #-}
153
153
154−-- | Encode type-level information for 'StateT'.
155−data STATE
156−
157-- | Modifies the state inside a state monad.
154-- | Modifies the state inside a state monad.
158modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
155modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
159modify f = state @tag (\s -> ((), f s))
156modify f = state @tag (\s -> ((), f s))
@@ -164,6 +161,9 @@ gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
164gets f = fmap f (get @tag)
161gets f = fmap f (get @tag)
165{-# INLINABLE gets #-}
162{-# INLINABLE gets #-}
166
163
164+-- | Encode type-level information for 'StateT'.
165+data STATE
166+
167type instance HandleSuper STATE s trans = ()
167type instance HandleSuper STATE s trans = ()
168type instance HandleConstraint STATE s trans m =
168type instance HandleConstraint STATE s trans m =
169 T.MonadState s (trans m)
169 T.MonadState s (trans m)
src/Ether/Writer.hs+137−31
@@ -17,6 +17,15 @@ module Ether.Writer
17 , writerT
17 , writerT
18 , runWriterT
18 , runWriterT
19 , execWriterT
19 , 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
20 -- * MonadWriter class (implicit)
29 -- * MonadWriter class (implicit)
21 , MonadWriter'
30 , MonadWriter'
22 , writer'
31 , writer'
@@ -34,6 +43,15 @@ module Ether.Writer
34 , writerT'
43 , writerT'
35 , runWriterT'
44 , runWriterT'
36 , execWriterT'
45 , 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'
37 -- * Internal labels
55 -- * Internal labels
38 , TAGGED
56 , TAGGED
39 , WRITER
57 , WRITER
@@ -44,11 +62,12 @@ import qualified Control.Monad.Trans.Lift.Listen as Lift
44import qualified Control.Monad.Trans.Lift.Pass as Lift
62import qualified Control.Monad.Trans.Lift.Pass as Lift
45import qualified Control.Monad.Writer.Class as T
63import qualified Control.Monad.Writer.Class as T
46import qualified Control.Monad.Writer.CPS as T.CPS
64import qualified Control.Monad.Writer.CPS as T.CPS
65+import qualified Control.Monad.Writer.Lazy as T.Lazy
47import Data.Coerce
66import Data.Coerce
48import Data.Functor.Identity
67import Data.Functor.Identity
49
68
50−import Ether.TaggedTrans
51import Ether.Internal
69import Ether.Internal
70+import Ether.TaggedTrans
52
71
53class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
72class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
54
73
@@ -106,6 +125,47 @@ censor f m = pass @tag $ do
106-- | Encode type-level information for 'WriterT'.
125-- | Encode type-level information for 'WriterT'.
107data WRITER
126data WRITER
108
127
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+
109-- | The parametrizable writer monad.
169-- | The parametrizable writer monad.
110--
170--
111-- Computations can accumulate a monoid value.
171-- Computations can accumulate a monoid value.
@@ -123,99 +183,145 @@ type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
123-- | Constructor for computations in the writer monad transformer.
183-- | Constructor for computations in the writer monad transformer.
124writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
184writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
125writerT = coerce (T.CPS.writerT @m @w @a)
185writerT = coerce (T.CPS.writerT @m @w @a)
186+{-# INLINE writerT #-}
126
187
127-- | Runs a 'WriterT' and returns both the normal value
188-- | Runs a 'WriterT' and returns both the normal value
128-- and the final accumulator.
189-- and the final accumulator.
129runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
190runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
130runWriterT = coerce (T.CPS.runWriterT @w @m @a)
191runWriterT = coerce (T.CPS.runWriterT @w @m @a)
192+{-# INLINE runWriterT #-}
131
193
132-- | Runs a 'Writer' and returns both the normal value
194-- | Runs a 'Writer' and returns both the normal value
133-- and the final accumulator.
195-- and the final accumulator.
134runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
196runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
135runWriter = coerce (T.CPS.runWriter @w @a)
197runWriter = coerce (T.CPS.runWriter @w @a)
198+{-# INLINE runWriter #-}
136
199
137-- | Runs a 'WriterT' and returns the final accumulator,
200-- | Runs a 'WriterT' and returns the final accumulator,
138-- discarding the normal value.
201-- discarding the normal value.
139execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
202execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
140execWriterT = coerce (T.CPS.execWriterT @m @w @a)
203execWriterT = coerce (T.CPS.execWriterT @m @w @a)
204+{-# INLINE execWriterT #-}
141
205
142-- | Runs a 'Writer' and returns the final accumulator,
206-- | Runs a 'Writer' and returns the final accumulator,
143-- discarding the normal value.
207-- discarding the normal value.
144execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
208execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
145execWriter = coerce (T.CPS.execWriter @w @a)
209execWriter = coerce (T.CPS.execWriter @w @a)
210+{-# INLINE execWriter #-}
146
211
147−type instance HandleSuper WRITER w trans = Monoid w
212+-- | The parametrizable writer monad.
148−type instance HandleConstraint WRITER w trans m =
213+--
149− T.MonadWriter w (trans m)
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
150
219
151−instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
220+-- | The writer monad transformer.
152− handling r = r
221+--
153− {-# INLINE handling #-}
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)
154
225
155−instance
226+-- | Constructor for computations in the writer monad transformer.
156− ( Handle WRITER w trans
227+lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
157− , Monad m, Monad (trans m)
228+lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
158− ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
229+{-# INLINE lazyWriterT #-}
159− where
160
230
161− writer =
231+-- | Runs a 'WriterT' and returns both the normal value
162− handling @WRITER @w @trans @m $
232+-- and the final accumulator.
163− coerce (T.writer @w @(trans m) @a) ::
233+runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
164− forall eff a . (a, w) -> TaggedTrans eff trans m a
234+runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
165− {-# INLINE writer #-}
235+{-# INLINE runLazyWriterT #-}
166
236
167− tell =
237+-- | Runs a 'Writer' and returns both the normal value
168− handling @WRITER @w @trans @m $
238+-- and the final accumulator.
169− coerce (T.tell @w @(trans m))
239+runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
240+runLazyWriter = coerce (T.Lazy.runWriter @w @a)
170− {-# INLINE tell #-}
241+{-# INLINE runLazyWriter #-}
171
242
172− listen =
243+-- | Runs a 'WriterT' and returns the final accumulator,
173− handling @WRITER @w @trans @m $
244+-- discarding the normal value.
174− coerce (T.listen @w @(trans m) @a) ::
245+execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
175− forall eff a . Listen w (TaggedTrans eff trans m) a
246+execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
176− {-# INLINE listen #-}
247+{-# INLINE execLazyWriterT #-}
177
248
178− pass =
249+-- | Runs a 'Writer' and returns the final accumulator,
179− handling @WRITER @w @trans @m $
250+-- discarding the normal value.
180− coerce (T.pass @w @(trans m) @a) ::
251+execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
181− forall eff a . Pass w (TaggedTrans eff trans m) a
252+execLazyWriter = coerce (T.Lazy.execWriter @w @a)
182− {-# INLINE pass #-}
253+{-# INLINE execLazyWriter #-}
183
254
184type Writer' w = Writer w w
255type Writer' w = Writer w w
185
256
186runWriter' :: Monoid w => Writer' w a -> (a, w)
257runWriter' :: Monoid w => Writer' w a -> (a, w)
187runWriter' = runWriter
258runWriter' = runWriter
259+{-# INLINE runWriter' #-}
188
260
189execWriter' :: Monoid w => Writer' w a -> w
261execWriter' :: Monoid w => Writer' w a -> w
190execWriter' = execWriter
262execWriter' = execWriter
263+{-# INLINE execWriter' #-}
191
264
192type WriterT' w = WriterT w w
265type WriterT' w = WriterT w w
193
266
194writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
267writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
195writerT' = writerT
268writerT' = writerT
269+{-# INLINE writerT' #-}
196
270
197runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
271runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
198runWriterT' = runWriterT
272runWriterT' = runWriterT
273+{-# INLINE runWriterT' #-}
199
274
200execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
275execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
201execWriterT' = execWriterT
276execWriterT' = 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' #-}
202
302
203type MonadWriter' w = MonadWriter w w
303type MonadWriter' w = MonadWriter w w
204
304
205writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
305writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
206writer' = writer @w
306writer' = writer @w
307+{-# INLINE writer' #-}
207
308
208tell' :: forall w m . MonadWriter' w m => w -> m ()
309tell' :: forall w m . MonadWriter' w m => w -> m ()
209tell' = tell @w
310tell' = tell @w
311+{-# INLINE tell' #-}
210
312
211listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
313listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
212listen' = listen @w
314listen' = listen @w
315+{-# INLINE listen' #-}
213
316
214pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
317pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
215pass' = pass @w
318pass' = pass @w
319+{-# INLINE pass' #-}
216
320
217listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
321listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
218listens' = listens @w
322listens' = listens @w
323+{-# INLINE listens' #-}
219
324
220censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
325censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
221censor' = censor @w
326censor' = censor @w
327+{-# INLINE censor' #-}