{-# LANGUAGE UndecidableInstances #-}

module Pandora.Paradigm.Primary.Transformer.Jet where

import Pandora.Pattern.Functor.Covariant (Covariant ((-<$>-)), (-<$$>-))
import Pandora.Pattern.Functor.Extractable (Extractable (extract))
import Pandora.Pattern.Functor.Traversable (Traversable ((<<-)), (-<<-<<-))
import Pandora.Paradigm.Primary.Algebraic ((-<*>-))

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 :: * -> *) (category :: * -> * -> *) a b.
(Covariant u category category, Covariant t category category) =>
category a b -> category (t (u a)) (t (u b))
-<$$>- Jet t (t a)
xs)

instance Traversable t (->) (->) => Traversable (Jet t) (->) (->) where
	a -> u b
f <<- :: (a -> u b) -> Jet t a -> u (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 (b -> Jet t (t b) -> Jet t b) -> u b -> u (Jet t (t b) -> Jet t b)
forall (t :: * -> *) (source :: * -> * -> *)
       (target :: * -> * -> *) a b.
Covariant t source target =>
source a b -> target (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
-<*>- a -> u b
f (a -> u b) -> Jet t (t a) -> u (Jet t (t b))
forall (t :: * -> *) (u :: * -> *) (v :: * -> *)
       (category :: * -> * -> *) a b.
(Traversable t category category, Covariant u category category,
 Pointable u category, Semimonoidal u category (:*:) (:*:),
 Traversable v category category) =>
category a (u b) -> category (v (t a)) (u (v (t b)))
-<<-<<- Jet t (t a)
xs

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