4 | module Control.Monad.Writer.CPS
6 | import Control.Monad.Identity
7 | import Control.Monad.Trans
20 | record WriterT (w : Type) (m : Type -> Type) (a : Type) where
21 | constructor MkWriterT
22 | unWriterT : w -> m (a, w)
26 | public export %inline
27 | writerT : Semigroup w => Functor m => m (a, w) -> WriterT w m a
28 | writerT f = MkWriterT $
\w => (\(a,w') => (a,w <+> w')) <$> f
32 | public export %inline
33 | runWriterT : Monoid w => WriterT w m a -> m (a,w)
34 | runWriterT m = unWriterT m neutral
37 | public export %inline
38 | execWriterT : Monoid w => Functor m => WriterT w m a -> m w
39 | execWriterT = map snd . runWriterT
43 | public export %inline
44 | mapWriterT : (Functor n, Monoid w, Semigroup w')
45 | => (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b
46 | mapWriterT f m = MkWriterT $
\w =>
47 | (\(a,w') => (a,w <+> w')) <$> f (runWriterT m)
56 | Writer : Type -> Type -> Type
57 | Writer w = WriterT w Identity
60 | public export %inline
61 | runWriter : Monoid w => Writer w a -> (a, w)
62 | runWriter = runIdentity . runWriterT
65 | public export %inline
66 | execWriter : Monoid w => Writer w a -> w
67 | execWriter = runIdentity . execWriterT
71 | public export %inline
72 | mapWriter : (Monoid w, Semigroup w')
73 | => ((a, w) -> (b, w')) -> Writer w a -> Writer w' b
74 | mapWriter f = mapWriterT $
\(Id p) => Id (f p)
80 | public export %inline
81 | Functor m => Functor (WriterT w m) where
82 | map f m = MkWriterT $
\w => (\(a,w') => (f a,w')) <$> unWriterT m w
84 | public export %inline
85 | Monad m => Applicative (WriterT w m) where
86 | pure a = MkWriterT $
\w => pure (a,w)
87 | MkWriterT mf <*> MkWriterT mx =
88 | MkWriterT $
\w => do (f,w1) <- mf w
92 | public export %inline
93 | (Monad m, Alternative m) => Alternative (WriterT w m) where
94 | empty = MkWriterT $
\_ => empty
95 | MkWriterT m <|> mn = MkWriterT $
\w => m w <|> unWriterT mn w
97 | public export %inline
98 | Monad m => Monad (WriterT w m) where
99 | m >>= k = MkWriterT $
\w => do (a,w1) <- unWriterT m w
102 | public export %inline
103 | MonadTrans (WriterT w) where
104 | lift m = MkWriterT $
\w => map (\a => (a,w)) m
106 | public export %inline
107 | HasIO m => HasIO (WriterT w m) where
108 | liftIO = lift . liftIO