module Pandora.Pattern.Functor.Distributive (Distributive (..)) where
import Pandora.Core.Functor (type (:.:), type (><))
import Pandora.Core.Morphism (identity, (.), (?))
import Pandora.Pattern.Functor.Covariant (Covariant ((<$>)))
infixl 5 >>-, >>>-, >>>>-, >>>>>-
class Covariant u => Distributive u where
{-# MINIMAL (>>-) #-}
(>>-) :: Covariant t => t a -> (a -> u b) -> u :.: t >< b
collect :: Covariant t => (a -> u b) -> t a -> u :.: t >< b
collect f t = t >>- f
distribute :: Covariant t => t :.: u >< a -> u :.: t >< a
distribute t = t >>- identity
(>>>-) :: (Covariant t, Covariant v)
=> t :.: v >< a -> (a -> u b) -> u :.: t :.: v >< b
x >>>- f = (collect . collect) f x
(>>>>-) :: (Covariant t, Covariant v, Covariant w)
=> t :.: v :.: w >< a -> (a -> u b) -> u :.: t :.: v :.: w >< b
x >>>>- f = (collect . collect . collect) f x
(>>>>>-) :: (Covariant t, Covariant v, Covariant w, Covariant j)
=> t :.: v :.: w :.: j >< a -> (a -> u b) -> u :.: t :.: v :.: w :.: j >< b
x >>>>>- f = (collect . collect . collect . collect) f x
instance Distributive ((->) e) where
g >>- f = \e -> (f ? e) <$> g