{-# OPTIONS --cubical-compatible --safe #-}
module Effect.Monad.Writer.Transformer where
open import Algebra using (RawMonoid)
open import Data.Product.Base using (_Γ_; _,_; projβ; mapβ)
open import Effect.Applicative using (RawApplicative; RawApplicativeZero; RawAlternative)
open import Effect.Choice using (RawChoice)
open import Effect.Empty using (RawEmpty)
open import Effect.Functor using (RawFunctor)
open import Effect.Monad using (RawMonad; RawMonadZero; RawMonadPlus; RawMonadT)
open import Function.Base using (_ββ²_; const; _$_)
open import Level using (Level)
private
variable
w g gβ gβ : Level
A B : Set w
M : Set w β Set g
π : RawMonoid w g
open import Effect.Monad.Writer.Transformer.Base public
using ( RawMonadWriter
; WriterT
; mkWriterT
; runWriterT
)
functor : RawFunctor M β RawFunctor (WriterT π M)
functor M = record
{ _<$>_ = Ξ» f ma β mkWriterT Ξ» w β mapβ f <$> runWriterT ma w
} where open RawFunctor M
empty : RawEmpty M β RawEmpty (WriterT π M)
empty M = record
{ empty = mkWriterT (const (RawEmpty.empty M))
}
choice : RawChoice M β RawChoice (WriterT π M)
choice M = record
{ _<|>_ = Ξ» maβ maβ β mkWriterT Ξ» w β
WriterT.runWriterT maβ w
<|> WriterT.runWriterT maβ w
} where open RawChoice M
module _ {π : RawMonoid w g} where
open RawMonoid π renaming (Carrier to W)
applicative : RawApplicative M β RawApplicative (WriterT π M)
applicative M = record
{ rawFunctor = functor rawFunctor
; pure = Ξ» a β mkWriterT (pure ββ² (_, a))
; _<*>_ = Ξ» mf mx β mkWriterT $ Ξ» w β
(go <$> runWriterT mf w) <*> runWriterT mx Ξ΅
} where
open RawApplicative M
go : W Γ (A β B) β W Γ A β W Γ B
go (wβ , f) (wβ , x) = wβ β wβ , f x
applicativeZero : RawApplicativeZero M β RawApplicativeZero (WriterT π M)
applicativeZero M = record
{ rawApplicative = applicative rawApplicative
; rawEmpty = empty rawEmpty
} where open RawApplicativeZero M using (rawApplicative; rawEmpty)
alternative : RawAlternative M β RawAlternative (WriterT π M)
alternative M = record
{ rawApplicativeZero = applicativeZero rawApplicativeZero
; rawChoice = choice rawChoice
} where open RawAlternative M
monad : RawMonad M β RawMonad (WriterT π M)
monad M = record
{ rawApplicative = applicative rawApplicative
; _>>=_ = Ξ» ma f β mkWriterT Ξ» w β do
wβ , a β runWriterT ma w
runWriterT (f a) wβ
} where open RawMonad M
monadZero : RawMonadZero M β RawMonadZero (WriterT π M)
monadZero M = record
{ rawMonad = monad (RawMonadZero.rawMonad M)
; rawEmpty = empty (RawMonadZero.rawEmpty M)
}
monadPlus : RawMonadPlus M β RawMonadPlus (WriterT π M)
monadPlus M = record
{ rawMonadZero = monadZero rawMonadZero
; rawChoice = choice rawChoice
} where open RawMonadPlus M
monadT : RawMonadT {gβ = gβ} {gβ = _} (WriterT π)
monadT M = record
{ lift = mkWriterT ββ² Ξ» ma w β (w ,_) <$> ma
; rawMonad = monad M
} where open RawMonad M
monadWriter : RawMonad M β RawMonadWriter π (WriterT π M)
monadWriter M = record
{ writer = mkWriterT ββ² Ξ» (w' , a) w β pure (w β w' , a)
; listen = Ξ» ma β mkWriterT Ξ» w β do
w , a β runWriterT ma w
pure (w , w , a)
; pass = Ξ» mx β mkWriterT Ξ» w β do
w , f , a β runWriterT mx w
pure (f w , a)
} where open RawMonad M
module _ {πβ : RawMonoid w gβ} where
open RawMonoid πβ renaming (Carrier to Wβ)
liftWriterT : (πβ : RawMonoid w gβ) β
RawFunctor M β
RawMonadWriter πβ M β
RawMonadWriter πβ (WriterT πβ M)
liftWriterT πβ M MWrite = record
{ writer = Ξ» (w , a) β mkWriterT Ξ» w' β (writer (w , w' , a ))
; listen = Ξ» mx β mkWriterT Ξ» w' β ((Ξ» (wβ , wβ , a) β wβ , wβ , a) <$> listen (runWriterT mx w'))
; pass = Ξ» mx β mkWriterT Ξ» w' β (pass ((Ξ» (w , f , a) β f , w , a) <$> runWriterT mx w'))
} where open RawMonadWriter MWrite
open RawFunctor M
private
variable
Wβ : Set gβ
open import Effect.Monad.Reader.Transformer.Base
liftReaderT : RawFunctor M β
RawMonadWriter πβ M β
RawMonadWriter πβ (ReaderT Wβ M)
liftReaderT M MWrite = record
{ writer = mkReaderT ββ² const ββ² writer
; listen = Ξ» ma β mkReaderT (listen ββ² runReaderT ma)
; pass = Ξ» ma β mkReaderT (pass ββ² runReaderT ma)
} where open RawMonadWriter MWrite
open import Effect.Monad.State.Transformer.Base
liftStateT : RawFunctor M β
RawMonadWriter πβ M β
RawMonadWriter πβ (StateT Wβ M)
liftStateT M MWrite = record
{ writer = Ξ» x β mkStateT Ξ» wβ β (wβ ,_) <$>
writer x
; listen = Ξ» mx β mkStateT Ξ» wβ β (wβ ,_) <$>
listen (projβ <$> runStateT mx wβ)
; pass = Ξ» mx β mkStateT Ξ» wβ β (wβ ,_) <$>
pass ((Ξ» (_ , f , a) β f , a) <$> runStateT mx wβ)
} where open RawMonadWriter MWrite
open RawFunctor M