{-# LANGUAGE UndecidableInstances #-}

module Pandora.Paradigm.Structure.Modification.Prefixed where

import Pandora.Core.Functor (type (:.), type (:=))
import Pandora.Pattern.Category ((.), ($))
import Pandora.Pattern.Functor.Covariant (Covariant ((<$>), (<$$>)))
import Pandora.Pattern.Functor.Pointable (Pointable (point))
import Pandora.Pattern.Functor.Traversable (Traversable ((->>), (->>>)))
import Pandora.Pattern.Object.Monoid (Monoid (zero))
import Pandora.Paradigm.Primary.Functor.Product (Product ((:*:)))
import Pandora.Paradigm.Controlflow.Effect.Interpreted (Interpreted (Primary, run, unite))

newtype Prefixed t k a = Prefixed (t :. Product k := a)

instance Interpreted (Prefixed t k) where
	type Primary (Prefixed t k) a = t :. Product k := a
	run :: Prefixed t k a -> Primary (Prefixed t k) a
run ~(Prefixed (t :. Product k) := a
x) = (t :. Product k) := a
Primary (Prefixed t k) a
x
	unite :: Primary (Prefixed t k) a -> Prefixed t k a
unite = Primary (Prefixed t k) a -> Prefixed t k a
forall (t :: * -> *) k a. ((t :. Product k) := a) -> Prefixed t k a
Prefixed

instance Covariant t => Covariant (Prefixed t k) where
	a -> b
f <$> :: (a -> b) -> Prefixed t k a -> Prefixed t k b
<$> Prefixed (t :. Product k) := a
x = ((t :. Product k) := b) -> Prefixed t k b
forall (t :: * -> *) k a. ((t :. Product k) := a) -> Prefixed t k a
Prefixed (((t :. Product k) := b) -> Prefixed t k b)
-> ((t :. Product k) := b) -> Prefixed t k b
forall (m :: * -> * -> *). Category m => m ~~> m
$ a -> b
f (a -> b) -> ((t :. Product k) := a) -> (t :. Product k) := b
forall (t :: * -> *) (u :: * -> *) a b.
(Covariant t, Covariant u) =>
(a -> b) -> ((t :. u) := a) -> (t :. u) := b
<$$> (t :. Product k) := a
x

instance Traversable t => Traversable (Prefixed t k) where
	Prefixed (t :. Product k) := a
x ->> :: Prefixed t k a -> (a -> u b) -> (u :. Prefixed t k) := b
->> a -> u b
f = ((t :. Product k) := b) -> Prefixed t k b
forall (t :: * -> *) k a. ((t :. Product k) := a) -> Prefixed t k a
Prefixed (((t :. Product k) := b) -> Prefixed t k b)
-> u ((t :. Product k) := b) -> (u :. Prefixed t k) := b
forall (t :: * -> *) a b. Covariant t => (a -> b) -> t a -> t b
<$> (t :. Product k) := a
x ((t :. Product k) := a) -> (a -> u b) -> u ((t :. Product k) := b)
forall (t :: * -> *) (u :: * -> *) (v :: * -> *) a b.
(Traversable t, Pointable u, Applicative u, Traversable v) =>
((v :. t) := a) -> (a -> u b) -> (u :. (v :. t)) := b
->>> a -> u b
f

instance (Monoid k, Pointable t) => Pointable (Prefixed t k) where
	point :: a :=> Prefixed t k
point = ((t :. Product k) := a) -> Prefixed t k a
forall (t :: * -> *) k a. ((t :. Product k) := a) -> Prefixed t k a
Prefixed (((t :. Product k) := a) -> Prefixed t k a)
-> (a -> (t :. Product k) := a) -> a :=> Prefixed t k
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. Product k a :=> t
forall (t :: * -> *) a. Pointable t => a :=> t
point (Product k a :=> t)
-> (a -> Product k a) -> a -> (t :. Product k) := a
forall (m :: * -> * -> *) b c a.
Category m =>
m b c -> m a b -> m a c
. k -> a -> Product k a
forall s a. s -> a -> Product s a
(:*:) k
forall a. Monoid a => a
zero