1
- {-# LANGUAGE Safe #-}
1
+ {-# LANGUAGE Trustworthy #-}
2
2
{-# LANGUAGE FlexibleInstances #-}
3
3
{-# LANGUAGE FunctionalDependencies #-}
4
4
{-# LANGUAGE MultiParamTypeClasses #-}
5
5
{-# LANGUAGE UndecidableInstances #-}
6
+ {-# LANGUAGE StandaloneKindSignatures #-}
7
+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
8
+ {-# LANGUAGE TupleSections #-}
9
+ {-# LANGUAGE ViewPatterns #-}
10
+ {-# OPTIONS_GHC -Wno-name-shadowing #-}
6
11
-- Search for UndecidableInstances to see why this is needed
7
12
8
13
-----------------------------------------------------------------------------
@@ -28,6 +33,7 @@ module Control.Monad.Writer.Class (
28
33
MonadWriter (.. ),
29
34
listens ,
30
35
censor ,
36
+ LiftingWriter (.. ),
31
37
) where
32
38
33
39
import Control.Monad.Trans.Except (ExceptT )
@@ -47,7 +53,8 @@ import Control.Monad.Trans.Accum (AccumT)
47
53
import qualified Control.Monad.Trans.Accum as Accum
48
54
import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
49
55
import qualified Control.Monad.Trans.Writer.CPS as CPS
50
- import Control.Monad.Trans.Class (lift )
56
+ import Control.Monad.Trans.Class (MonadTrans (lift ))
57
+ import Data.Kind (Type )
51
58
52
59
-- ---------------------------------------------------------------------------
53
60
-- MonadWriter class
@@ -205,3 +212,80 @@ instance
205
212
tell = lift . tell
206
213
listen = Accum. liftListen listen
207
214
pass = Accum. liftPass pass
215
+
216
+
217
+ -- | A helper type to decrease boilerplate when defining new transformer
218
+ -- instances of 'MonadWriter'.
219
+ --
220
+ -- @since ????
221
+ type LiftingWriter :: ((Type -> Type ) -> Type -> Type ) -> (Type -> Type ) -> Type -> Type
222
+ newtype LiftingWriter t m a = LiftingWriter { runLiftingWriter :: t m a }
223
+ deriving (Functor , Applicative , Monad , MonadTrans )
224
+
225
+
226
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (LazyRWS. RWST r w' s ) m ) where
227
+ writer = lift . writer
228
+ tell = lift . tell
229
+ listen (LiftingWriter (LazyRWS. RWST x)) = LiftingWriter $ LazyRWS. RWST $ \ r s -> do
230
+ ((a, s, w'), w) <- listen $ x r s
231
+ pure ((a, w), s, w')
232
+ pass (LiftingWriter (LazyRWS. RWST x)) = LiftingWriter $ LazyRWS. RWST $ \ r s -> do
233
+ (y, s, w') <- x r s
234
+ a <- pass $ pure y
235
+ pure (a, s, w')
236
+
237
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (StrictRWS. RWST r w' s ) m ) where
238
+ writer = lift . writer
239
+ tell = lift . tell
240
+ listen (LiftingWriter (StrictRWS. RWST x)) = LiftingWriter $ StrictRWS. RWST $ \ r s -> do
241
+ ((a, s, w'), w) <- listen $ x r s
242
+ pure ((a, w), s, w')
243
+ pass (LiftingWriter (StrictRWS. RWST x)) = LiftingWriter $ StrictRWS. RWST $ \ r s -> do
244
+ (y, s, w') <- x r s
245
+ a <- pass $ pure y
246
+ pure (a, s, w')
247
+
248
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (CPSRWS. RWST r w' s ) m ) where
249
+ writer = lift . writer
250
+ tell = lift . tell
251
+ listen (LiftingWriter (CPSRWS. runRWST -> x)) = LiftingWriter $ CPSRWS. rwsT $ \ r s -> do
252
+ ((a, s, w'), w) <- listen $ x r s
253
+ pure ((a, w), s, w')
254
+ pass (LiftingWriter (CPSRWS. runRWST -> x)) = LiftingWriter $ CPSRWS. rwsT $ \ r s -> do
255
+ (y, s, w') <- x r s
256
+ a <- pass $ pure y
257
+ pure (a, s, w')
258
+
259
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (Lazy. WriterT w' ) m ) where
260
+ writer = lift . writer
261
+ tell = lift . tell
262
+ listen (LiftingWriter (Lazy. WriterT x)) = LiftingWriter $ Lazy. WriterT $ do
263
+ ((a, w'), w) <- listen x
264
+ pure ((a, w), w')
265
+ pass (LiftingWriter (Lazy. WriterT x)) = LiftingWriter $ Lazy. WriterT $ do
266
+ (y, w') <- x
267
+ a <- pass $ pure y
268
+ pure (a, w')
269
+
270
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (Strict. WriterT w' ) m ) where
271
+ writer = lift . writer
272
+ tell = lift . tell
273
+ listen (LiftingWriter (Strict. WriterT x)) = LiftingWriter $ Strict. WriterT $ do
274
+ ((a, w'), w) <- listen x
275
+ pure ((a, w), w')
276
+ pass (LiftingWriter (Strict. WriterT x)) = LiftingWriter $ Strict. WriterT $ do
277
+ (y, w') <- x
278
+ a <- pass $ pure y
279
+ pure (a, w')
280
+
281
+ instance (Monoid w' , MonadWriter w m ) => MonadWriter w (LiftingWriter (CPS. WriterT w' ) m ) where
282
+ writer = lift . writer
283
+ tell = lift . tell
284
+ listen (LiftingWriter (CPS. runWriterT -> x)) = LiftingWriter $ CPS. writerT $ do
285
+ ((a, w'), w) <- listen x
286
+ pure ((a, w), w')
287
+ pass (LiftingWriter (CPS. runWriterT -> x)) = LiftingWriter $ CPS. writerT $ do
288
+ (y, w') <- x
289
+ a <- pass $ pure y
290
+ pure (a, w')
291
+
0 commit comments