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

import Data.Profunctor
import Control.Category ((>>>))
import qualified Control.Category as C

class (C.Category p, Profunctor p) => ProfunctorState s p | p -> s where
  {-# MINIMAL state | (get, put) #-}
  get :: p a (a, s)
  get = p (a, s) ((a, s), s) -> p a (a, s)
forall s (p :: * -> * -> *) a b.
ProfunctorState s p =>
p (a, s) (b, s) -> p a b
state (((a, s) -> ((a, s), s)) -> p (a, s) (a, s) -> p (a, s) ((a, s), s)
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap (\(a :: a
a, s :: s
s) -> ((a
a, s
s), s
s)) p (a, s) (a, s)
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
C.id)
  put :: p (a, s) a
  put = p ((a, s), s) (a, s) -> p (a, s) a
forall s (p :: * -> * -> *) a b.
ProfunctorState s p =>
p (a, s) (b, s) -> p a b
state ((((a, s), s) -> (a, s)) -> p (a, s) (a, s) -> p ((a, s), s) (a, s)
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap (\((a :: a
a, s :: s
s), _) -> (a
a, s
s)) p (a, s) (a, s)
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
C.id)
  state :: p (a, s) (b, s) -> p a b
  state p :: p (a, s) (b, s)
p = (p a (a, s)
forall s (p :: * -> * -> *) a. ProfunctorState s p => p a (a, s)
get p a (a, s) -> p (a, s) b -> p a b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> p (a, s) (b, s)
p p (a, s) (b, s) -> p (b, s) b -> p (a, s) b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> p (b, s) b
forall s (p :: * -> * -> *) a. ProfunctorState s p => p (a, s) a
put)


class (Profunctor p) => ProfunctorState' s p | p -> s where
  {-# MINIMAL (get', put') #-}
  get' :: p (a, s) b -> p a b
  put' :: p a (b, s) -> p a b