|  | 
|  | 1 | +------------------------------------------------------------------------ | 
|  | 2 | +-- The Agda standard library | 
|  | 3 | +-- | 
|  | 4 | +-- The indexed writer monad | 
|  | 5 | +------------------------------------------------------------------------ | 
|  | 6 | + | 
|  | 7 | +{-# OPTIONS --without-K --safe #-} | 
|  | 8 | + | 
|  | 9 | +open import Level | 
|  | 10 | + | 
|  | 11 | +module Effect.Monad.Writer.Indexed (a : Level) where | 
|  | 12 | + | 
|  | 13 | +open import Algebra using (RawMonoid) | 
|  | 14 | +open import Data.Product using (_×_; _,_; map₁) | 
|  | 15 | +open import Data.Unit.Polymorphic | 
|  | 16 | +open import Effect.Applicative.Indexed | 
|  | 17 | +open import Effect.Monad | 
|  | 18 | +open import Effect.Monad.Indexed | 
|  | 19 | +open import Function | 
|  | 20 | +open import Function.Identity.Effectful as Id using (Identity) | 
|  | 21 | + | 
|  | 22 | +private | 
|  | 23 | +  variable | 
|  | 24 | +    w ℓ : Level | 
|  | 25 | +    A B I : Set ℓ | 
|  | 26 | + | 
|  | 27 | +------------------------------------------------------------------------ | 
|  | 28 | +-- Indexed writer | 
|  | 29 | + | 
|  | 30 | +IWriterT : Set w → IFun I (w ⊔ a) → IFun I (w ⊔ a) | 
|  | 31 | +IWriterT W M i j A = M i j (W × A) | 
|  | 32 | + | 
|  | 33 | +module _ {M : IFun I (w ⊔ a)} {MW' : RawMonoid w ℓ} where | 
|  | 34 | + | 
|  | 35 | +  open RawMonoid MW' renaming (Carrier to W') | 
|  | 36 | + | 
|  | 37 | +  ------------------------------------------------------------------------ | 
|  | 38 | +  -- Indexed writer applicative | 
|  | 39 | + | 
|  | 40 | +  WriterTIApplicative : RawIApplicative M → RawIApplicative (IWriterT W' M) | 
|  | 41 | +  WriterTIApplicative App = record | 
|  | 42 | +    { pure = λ x → pure (ε , x) | 
|  | 43 | +    ; _⊛_ = λ m n → go <$> m ⊛ n | 
|  | 44 | +    } where | 
|  | 45 | +        open RawIApplicative App | 
|  | 46 | +        go : W' × (A → B) → W' × A → W' × B | 
|  | 47 | +        go (w₁ , f) (w₂ , x) = w₁ ∙ w₂ , f x | 
|  | 48 | + | 
|  | 49 | +  WriterTIApplicativeZero : RawIApplicativeZero M → | 
|  | 50 | +                            RawIApplicativeZero (IWriterT W' M) | 
|  | 51 | +  WriterTIApplicativeZero App = record | 
|  | 52 | +    { applicative = WriterTIApplicative applicative | 
|  | 53 | +    ; ∅ = ∅ | 
|  | 54 | +    } where open RawIApplicativeZero App | 
|  | 55 | + | 
|  | 56 | +  WriterTIAlternative : RawIAlternative M → RawIAlternative (IWriterT W' M) | 
|  | 57 | +  WriterTIAlternative Alt = record | 
|  | 58 | +    { applicativeZero = WriterTIApplicativeZero applicativeZero | 
|  | 59 | +    ; _∣_ = _∣_ | 
|  | 60 | +    } where open RawIAlternative Alt | 
|  | 61 | + | 
|  | 62 | +  ------------------------------------------------------------------------ | 
|  | 63 | +  -- Indexed writer monad | 
|  | 64 | + | 
|  | 65 | +  WriterTIMonad : RawIMonad M → RawIMonad (IWriterT W' M) | 
|  | 66 | +  WriterTIMonad Mon = record | 
|  | 67 | +    { return = λ x → return (ε , x) | 
|  | 68 | +    ; _>>=_ = λ m f → do | 
|  | 69 | +        w₁ , x  ← m | 
|  | 70 | +        w₂ , fx ← f x | 
|  | 71 | +        return (w₁ ∙ w₂ , fx) | 
|  | 72 | +    } where open RawIMonad Mon | 
|  | 73 | + | 
|  | 74 | +  WriterTIMonadZero : RawIMonadZero M → RawIMonadZero (IWriterT W' M) | 
|  | 75 | +  WriterTIMonadZero Mon = record | 
|  | 76 | +    { monad = WriterTIMonad monad | 
|  | 77 | +    ; applicativeZero = WriterTIApplicativeZero applicativeZero | 
|  | 78 | +    } where open RawIMonadZero Mon | 
|  | 79 | + | 
|  | 80 | +  WriterTIMonadPlus : RawIMonadPlus M → RawIMonadPlus (IWriterT W' M) | 
|  | 81 | +  WriterTIMonadPlus Mon = record | 
|  | 82 | +    { monad = WriterTIMonad monad | 
|  | 83 | +    ; alternative = WriterTIAlternative alternative | 
|  | 84 | +    } where open RawIMonadPlus Mon | 
|  | 85 | + | 
|  | 86 | +------------------------------------------------------------------------ | 
|  | 87 | +-- Writer monad operations | 
|  | 88 | + | 
|  | 89 | +record RawIMonadWriter {I : Set ℓ} (W : Set w) (M : IFun I (w ⊔ a)) | 
|  | 90 | +                       : Set (ℓ ⊔ suc (w ⊔ a)) where | 
|  | 91 | +  field | 
|  | 92 | +    monad  : RawIMonad M | 
|  | 93 | +    writer : ∀ {i} → (W × A) → M i i A | 
|  | 94 | +    listen : ∀ {i j} → M i j A → M i j (W × A) | 
|  | 95 | +    pass   : ∀ {i j} → M i j ((W → W) × A) → M i j A | 
|  | 96 | + | 
|  | 97 | +  open RawIMonad monad public | 
|  | 98 | + | 
|  | 99 | +  tell : ∀ {i} → W → M i i ⊤ | 
|  | 100 | +  tell = writer ∘′ (_, tt) | 
|  | 101 | + | 
|  | 102 | +  listens : ∀ {i j} {Z : Set w} → (W → Z) → M i j A → M i j (Z × A) | 
|  | 103 | +  listens f m = listen m >>= return ∘′ map₁ f | 
|  | 104 | + | 
|  | 105 | +  censor : ∀ {i j} → (W → W) → M i j A → M i j A | 
|  | 106 | +  censor f m = pass (m >>= return ∘′ (f ,_)) | 
|  | 107 | + | 
|  | 108 | +module _ {MW' : RawMonoid w ℓ} where | 
|  | 109 | + | 
|  | 110 | +  open RawMonoid MW' renaming (Carrier to W') | 
|  | 111 | + | 
|  | 112 | +  WriterTIMonadWriter : {I : Set ℓ} {M : IFun I (w ⊔ a)} → | 
|  | 113 | +                        RawIMonad M → RawIMonadWriter W' (IWriterT W' M) | 
|  | 114 | +  WriterTIMonadWriter Mon = record | 
|  | 115 | +    { monad = WriterTIMonad {MW' = MW'} Mon | 
|  | 116 | +    ; writer = return | 
|  | 117 | +    ; listen = λ m → do | 
|  | 118 | +        w , a ← m | 
|  | 119 | +        return (w , w , a) | 
|  | 120 | +    ; pass = λ m → do | 
|  | 121 | +        w , f , a ← m | 
|  | 122 | +        return (f w , a) | 
|  | 123 | +    } where open RawIMonad Mon | 
0 commit comments