{-# LANGUAGE DataKinds #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Distributive.Square
-- License     :  BSD-style (see the file LICENSE)
-- Maintainer  :  sjoerd@w3future.com
--
-----------------------------------------------------------------------------
module Data.Distributive.Square where

import Data.Square
import Data.Profunctor
import qualified Data.Distributive as D

-- |
-- > +--t--+
-- > |  v  |
-- > f<-@-<f
-- > |  v  |
-- > +--t--+
--
-- @cotraverse = (funId ||| fromRight) === distribute === (toLeft ||| funId)@
cotraverse :: (D.Distributive t, Functor f) => Square '[Costar f] '[Costar f] '[t] '[t]
cotraverse :: forall (t :: * -> *) (f :: * -> *).
(Distributive t, Functor f) =>
Square '[Costar f] '[Costar f] '[t] '[t]
cotraverse = forall (ps :: [* -> * -> *]) (qs :: [* -> * -> *]) (fs :: [* -> *])
       (gs :: [* -> *]).
(IsPList ps, IsPList qs, IsFList fs, IsFList gs,
 Profunctor (PList qs)) =>
(forall a b.
 PlainP ps a b -> PlainP qs (PlainF fs a) (PlainF gs b))
-> Square ps qs fs gs
mkSquare (forall {k} (f :: k -> *) (d :: k) c. (f d -> c) -> Costar f d c
Costar forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (g :: * -> *) (f :: * -> *) a b.
(Distributive g, Functor f) =>
(f a -> b) -> f (g a) -> g b
D.cotraverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (d :: k) c. Costar f d c -> f d -> c
runCostar)

-- |
-- > +---t-f-+
-- > |   v v |
-- > | /-@-/ |
-- > | v v   |
-- > +-f-t---+
--
-- @distribute = fromRight ||| cotraverse ||| toLeft@
distribute :: (D.Distributive t, Functor f) => Square '[] '[] '[t, f] '[f, t]
distribute :: forall (t :: * -> *) (f :: * -> *).
(Distributive t, Functor f) =>
Square '[] '[] '[t, f] '[f, t]
distribute = forall (f :: * -> *). Functor f => Square '[] '[Costar f] '[] '[f]
fromRight forall (rs :: [* -> * -> *]) (fs :: [* -> *]) (gs :: [* -> *])
       (hs :: [* -> *]) (is :: [* -> *]) (ps :: [* -> * -> *])
       (qs :: [* -> * -> *]).
(Profunctor (PList rs), IsFList fs, IsFList gs, Functor (FList hs),
 Functor (FList is)) =>
Square ps qs fs gs
-> Square qs rs hs is -> Square ps rs (fs ++ hs) (gs ++ is)
||| forall (t :: * -> *) (f :: * -> *).
(Distributive t, Functor f) =>
Square '[Costar f] '[Costar f] '[t] '[t]
cotraverse forall (rs :: [* -> * -> *]) (fs :: [* -> *]) (gs :: [* -> *])
       (hs :: [* -> *]) (is :: [* -> *]) (ps :: [* -> * -> *])
       (qs :: [* -> * -> *]).
(Profunctor (PList rs), IsFList fs, IsFList gs, Functor (FList hs),
 Functor (FList is)) =>
Square ps qs fs gs
-> Square qs rs hs is -> Square ps rs (fs ++ hs) (gs ++ is)
||| forall (f :: * -> *). Square '[Costar f] '[] '[f] '[]
toLeft