module Pandora.Paradigm.Primary.Transformer.Jet where

import Pandora.Pattern.Functor.Covariant (Covariant ((<$>)), (<$$>))
import Pandora.Pattern.Functor.Avoidable (Avoidable (empty))
import Pandora.Pattern.Functor.Pointable (Pointable (point))
import Pandora.Pattern.Functor.Extractable (Extractable (extract))
import Pandora.Pattern.Functor.Applicative (Applicative ((<*>)))
import Pandora.Pattern.Functor.Traversable (Traversable ((->>), (->>>)))

data Jet t a = Jet a (Jet t (t a))

instance Covariant t => Covariant (Jet t) where
	a -> b
f <$> :: (a -> b) -> Jet t a -> Jet t b
<$> Jet a
x Jet t (t a)
xs = b -> Jet t (t b) -> Jet t b
forall (t :: * -> *) a. a -> Jet t (t a) -> Jet t a
Jet (a -> b
f a
x) (a -> b
f (a -> b) -> Jet t (t a) -> Jet t (t b)
forall (t :: * -> *) (u :: * -> *) a b.
(Covariant t, Covariant u) =>
(a -> b) -> ((t :. u) := a) -> (t :. u) := b
<$$> Jet t (t a)
xs)

instance Traversable t => Traversable (Jet t) where
	Jet a
x Jet t (t a)
xs ->> :: Jet t a -> (a -> u b) -> (u :. Jet t) := b
->> a -> u b
f = b -> Jet t (t b) -> Jet t b
forall (t :: * -> *) a. a -> Jet t (t a) -> Jet t a
Jet (b -> Jet t (t b) -> Jet t b) -> u b -> u (Jet t (t b) -> Jet t b)
forall (t :: * -> *) a b. Covariant t => (a -> b) -> t a -> t b
<$> a -> u b
f a
x u (Jet t (t b) -> Jet t b) -> u (Jet t (t b)) -> (u :. Jet t) := b
forall (t :: * -> *) a b. Applicative t => t (a -> b) -> t a -> t b
<*> (Jet t (t a)
xs Jet t (t a) -> (a -> u b) -> u (Jet t (t 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 (forall u . Avoidable u) => Pointable (Jet t) where
	point :: a |-> Jet t
point a
x = a -> Jet t (t a) -> Jet t a
forall (t :: * -> *) a. a -> Jet t (t a) -> Jet t a
Jet a
x Jet t (t a)
forall (t :: * -> *) a. Avoidable t => t a
empty

instance Covariant t => Extractable (Jet t) where
	extract :: a <-| Jet t
extract (Jet a
x Jet t (t a)
_) = a
x