{-# LANGUAGE FunctionalDependencies #-}
module Data.Profunctor.Writer.Class where

import Data.Profunctor
import qualified Control.Category as C
import Data.Bifunctor (second)

class (Monoid w, C.Category p, Profunctor p) => ProfunctorWriter w p | p -> w where
  {-# MINIMAL listen, pass #-}
  tell :: p (a, w) a
  tell = ((a, w) -> (a, w -> w)) -> p (a, w -> w) a -> p (a, w) a
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap ((w -> w -> w) -> (a, w) -> (a, w -> w)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (\w :: w
w -> (w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w))) p (a, w -> w) a
forall w (p :: * -> * -> *) a.
ProfunctorWriter w p =>
p (a, w -> w) a
pass
  listen :: p a (a, w)
  pass :: p (a, w -> w) a

class (Monoid w, Profunctor p) => ProfunctorWriter' w p | p -> w where
  {-# MINIMAL listen', pass' #-}
  tell' :: p a (b, w) -> p a b
  tell' p :: p a (b, w)
p = p a (b, w -> w) -> p a b
forall w (p :: * -> * -> *) a b.
ProfunctorWriter' w p =>
p a (b, w -> w) -> p a b
pass' (((b, w) -> (b, w -> w)) -> p a (b, w) -> p a (b, w -> w)
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap (\(b :: b
b, w :: w
w) -> (b
b, (w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w))) p a (b, w)
p)
  listen' :: p a b -> p a (b, w)
  pass' :: p a (b, w -> w) -> p a b