{- |
Module      :  Control.Monad.Trans.Indexed.Writer
Copyright   :  (C) 2024 Eitan Chatav
License     :  BSD 3-Clause License (see the file LICENSE)
Maintainer  :  Eitan Chatav <eitan.chatav@gmail.com>

The writer indexed monad transformer.
-}

module Control.Monad.Trans.Indexed.Writer
  ( WriterIx (..)
  , evalWriterIx
  , execWriterIx
  , mapWriterIx
  , tellIx
  , listenIx
  , listensIx
  , passIx
  , censorIx
  ) where

import Prelude hiding (id, (.))
import Control.Category
import Control.Monad.Trans
import Control.Monad.Trans.Indexed

newtype WriterIx w i j m x = WriterIx {forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
WriterIx w i j m x -> m (x, w i j)
runWriterIx :: m (x, w i j)}
  deriving (forall a b. (a -> b) -> WriterIx w i j m a -> WriterIx w i j m b)
-> (forall a b. a -> WriterIx w i j m b -> WriterIx w i j m a)
-> Functor (WriterIx w i j m)
forall a b. a -> WriterIx w i j m b -> WriterIx w i j m a
forall a b. (a -> b) -> WriterIx w i j m a -> WriterIx w i j m b
forall k k (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *) a b.
Functor m =>
a -> WriterIx w i j m b -> WriterIx w i j m a
forall k k (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *) a b.
Functor m =>
(a -> b) -> WriterIx w i j m a -> WriterIx w i j m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall k k (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *) a b.
Functor m =>
(a -> b) -> WriterIx w i j m a -> WriterIx w i j m b
fmap :: forall a b. (a -> b) -> WriterIx w i j m a -> WriterIx w i j m b
$c<$ :: forall k k (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *) a b.
Functor m =>
a -> WriterIx w i j m b -> WriterIx w i j m a
<$ :: forall a b. a -> WriterIx w i j m b -> WriterIx w i j m a
Functor

instance Category w => IxMonadTrans (WriterIx w) where
  joinIx :: forall (m :: * -> *) (i :: k) (j :: k) (k1 :: k) y.
Monad m =>
WriterIx w i j m (WriterIx w j k1 m y) -> WriterIx w i k1 m y
joinIx (WriterIx m (WriterIx w j k1 m y, w i j)
mm) = m (y, w i k1) -> WriterIx w i k1 m y
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m (y, w i k1) -> WriterIx w i k1 m y)
-> m (y, w i k1) -> WriterIx w i k1 m y
forall a b. (a -> b) -> a -> b
$ do
    (WriterIx m (y, w j k1)
m, w i j
ij) <- m (WriterIx w j k1 m y, w i j)
mm
    (y
x, w j k1
jk) <- m (y, w j k1)
m
    (y, w i k1) -> m (y, w i k1)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (y
x, w i j
ij w i j -> w j k1 -> w i k1
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> w j k1
jk)
instance (i ~ j, Applicative m, Category w) => Applicative (WriterIx w i j m) where
  pure :: forall a. a -> WriterIx w i j m a
pure a
x = m (a, w i j) -> WriterIx w i j m a
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx ((a, w i j) -> m (a, w i j)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
x, w i i
w i j
forall (a :: k). w a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id))
  WriterIx m (a -> b, w i j)
mf <*> :: forall a b.
WriterIx w i j m (a -> b)
-> WriterIx w i j m a -> WriterIx w i j m b
<*> WriterIx m (a, w i j)
mx =
    let
      apply :: (t -> a, cat a b) -> (t, cat b c) -> (a, cat a c)
apply (t -> a
f, cat a b
ij) (t
x, cat b c
jk) = (t -> a
f t
x, cat a b
ij cat a b -> cat b c -> cat a c
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> cat b c
jk)
    in
      m (b, w i j) -> WriterIx w i j m b
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m (b, w i j) -> WriterIx w i j m b)
-> m (b, w i j) -> WriterIx w i j m b
forall a b. (a -> b) -> a -> b
$ (a -> b, w i j) -> (a, w j j) -> (b, w i j)
forall {k} {cat :: k -> k -> *} {t} {a} {a :: k} {b :: k} {c :: k}.
Category cat =>
(t -> a, cat a b) -> (t, cat b c) -> (a, cat a c)
apply ((a -> b, w i j) -> (a, w j j) -> (b, w i j))
-> m (a -> b, w i j) -> m ((a, w j j) -> (b, w i j))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (a -> b, w i j)
mf m ((a, w j j) -> (b, w i j)) -> m (a, w j j) -> m (b, w i j)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (a, w i j)
m (a, w j j)
mx
instance (i ~ j, Monad m, Category w) => Monad (WriterIx w i j m) where
  return :: forall a. a -> WriterIx w i j m a
return = a -> WriterIx w i j m a
forall a. a -> WriterIx w i j m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  >>= :: forall a b.
WriterIx w i j m a
-> (a -> WriterIx w i j m b) -> WriterIx w i j m b
(>>=) = ((a -> WriterIx w i j m b)
 -> WriterIx w i j m a -> WriterIx w i j m b)
-> WriterIx w i j m a
-> (a -> WriterIx w i j m b)
-> WriterIx w i j m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> WriterIx w i j m b)
-> WriterIx w i i m a -> WriterIx w i j m b
(a -> WriterIx w i j m b)
-> WriterIx w i j m a -> WriterIx w i j m b
forall k (t :: k -> k -> (* -> *) -> * -> *) (m :: * -> *) x
       (j :: k) (k1 :: k) y (i :: k).
(IxMonadTrans t, Monad m) =>
(x -> t j k1 m y) -> t i j m x -> t i k1 m y
forall (m :: * -> *) x (j :: k) (k1 :: k) y (i :: k).
Monad m =>
(x -> WriterIx w j k1 m y)
-> WriterIx w i j m x -> WriterIx w i k1 m y
bindIx
instance (i ~ j, Category w) => MonadTrans (WriterIx w i j) where
  lift :: forall (m :: * -> *) a. Monad m => m a -> WriterIx w i j m a
lift m a
m = m (a, w i j) -> WriterIx w i j m a
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m (a, w i j) -> WriterIx w i j m a)
-> m (a, w i j) -> WriterIx w i j m a
forall a b. (a -> b) -> a -> b
$ do
    a
x <- m a
m
    (a, w i j) -> m (a, w i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
x, w i i
w i j
forall (a :: k). w a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)

evalWriterIx :: Monad m => WriterIx w i j m x -> m x
evalWriterIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k)
       x.
Monad m =>
WriterIx w i j m x -> m x
evalWriterIx (WriterIx m (x, w i j)
m) = (x, w i j) -> x
forall a b. (a, b) -> a
fst ((x, w i j) -> x) -> m (x, w i j) -> m x
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (x, w i j)
m

execWriterIx :: Monad m => WriterIx w i j m x -> m (w i j)
execWriterIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k)
       x.
Monad m =>
WriterIx w i j m x -> m (w i j)
execWriterIx (WriterIx m (x, w i j)
m) = (x, w i j) -> w i j
forall a b. (a, b) -> b
snd ((x, w i j) -> w i j) -> m (x, w i j) -> m (w i j)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (x, w i j)
m

mapWriterIx
  :: (m (x, w i j) -> n (y, q i j))
  -> WriterIx w i j m x
  -> WriterIx q i j n y
mapWriterIx :: forall {k} {k} (m :: * -> *) x (w :: k -> k -> *) (i :: k) (j :: k)
       (n :: * -> *) y (q :: k -> k -> *).
(m (x, w i j) -> n (y, q i j))
-> WriterIx w i j m x -> WriterIx q i j n y
mapWriterIx m (x, w i j) -> n (y, q i j)
f WriterIx w i j m x
m = n (y, q i j) -> WriterIx q i j n y
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (n (y, q i j) -> WriterIx q i j n y)
-> n (y, q i j) -> WriterIx q i j n y
forall a b. (a -> b) -> a -> b
$ m (x, w i j) -> n (y, q i j)
f (WriterIx w i j m x -> m (x, w i j)
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
WriterIx w i j m x -> m (x, w i j)
runWriterIx WriterIx w i j m x
m)

tellIx :: Monad m => w i j -> WriterIx w i j m ()
tellIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k).
Monad m =>
w i j -> WriterIx w i j m ()
tellIx w i j
w = m ((), w i j) -> WriterIx w i j m ()
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (((), w i j) -> m ((), w i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((), w i j
w))

listenIx :: Monad m => WriterIx w i j m x -> WriterIx w i j m (x, w i j)
listenIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k)
       x.
Monad m =>
WriterIx w i j m x -> WriterIx w i j m (x, w i j)
listenIx (WriterIx m (x, w i j)
m) = m ((x, w i j), w i j) -> WriterIx w i j m (x, w i j)
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m ((x, w i j), w i j) -> WriterIx w i j m (x, w i j))
-> m ((x, w i j), w i j) -> WriterIx w i j m (x, w i j)
forall a b. (a -> b) -> a -> b
$ do
  (x
x, w i j
w) <- m (x, w i j)
m
  ((x, w i j), w i j) -> m ((x, w i j), w i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((x
x, w i j
w),w i j
w)

listensIx
  :: Monad m
  => (w i j -> y)
  -> WriterIx w i j m x
  -> WriterIx w i j m (x, y)
listensIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k) y
       x.
Monad m =>
(w i j -> y) -> WriterIx w i j m x -> WriterIx w i j m (x, y)
listensIx w i j -> y
f (WriterIx m (x, w i j)
m) = m ((x, y), w i j) -> WriterIx w i j m (x, y)
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m ((x, y), w i j) -> WriterIx w i j m (x, y))
-> m ((x, y), w i j) -> WriterIx w i j m (x, y)
forall a b. (a -> b) -> a -> b
$ do
  (x
x, w i j
w) <- m (x, w i j)
m
  ((x, y), w i j) -> m ((x, y), w i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((x
x, w i j -> y
f w i j
w), w i j
w)

passIx
  :: Monad m
  => WriterIx w i j m (x, w i j -> q i j)
  -> WriterIx q i j m x
passIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k) x
       (q :: k -> k -> *).
Monad m =>
WriterIx w i j m (x, w i j -> q i j) -> WriterIx q i j m x
passIx (WriterIx m ((x, w i j -> q i j), w i j)
m) = m (x, q i j) -> WriterIx q i j m x
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m (x, q i j) -> WriterIx q i j m x)
-> m (x, q i j) -> WriterIx q i j m x
forall a b. (a -> b) -> a -> b
$ do
  ((x
x, w i j -> q i j
f), w i j
w) <- m ((x, w i j -> q i j), w i j)
m
  (x, q i j) -> m (x, q i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (x
x, w i j -> q i j
f w i j
w)

censorIx :: Monad m => (w i j -> w i j) -> WriterIx w i j m x -> WriterIx w i j m x
censorIx :: forall {k} {k} (m :: * -> *) (w :: k -> k -> *) (i :: k) (j :: k)
       x.
Monad m =>
(w i j -> w i j) -> WriterIx w i j m x -> WriterIx w i j m x
censorIx w i j -> w i j
f (WriterIx m (x, w i j)
m) = m (x, w i j) -> WriterIx w i j m x
forall {k} {k} (w :: k -> k -> *) (i :: k) (j :: k) (m :: * -> *)
       x.
m (x, w i j) -> WriterIx w i j m x
WriterIx (m (x, w i j) -> WriterIx w i j m x)
-> m (x, w i j) -> WriterIx w i j m x
forall a b. (a -> b) -> a -> b
$ do
  (x
x, w i j
w) <- m (x, w i j)
m
  (x, w i j) -> m (x, w i j)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (x
x, w i j -> w i j
f w i j
w)