{-# LANGUAGE StaticPointers #-}

module Data.Profunctor.Choice.Static where

import Control.Distributed.Closure
import Data.Bifunctor (bimap)
import Data.Profunctor.Static
import Data.Typeable (Typeable)

class StaticProfunctor p => StaticChoice p where
  staticLeft'
    :: (Typeable a, Typeable b, Typeable c)
    => p a b -> p (Either a c) (Either b c)
  staticRight'
    :: (Typeable a, Typeable b, Typeable c)
    => p a b -> p (Either c a) (Either c b)

instance StaticChoice WrappedArrowClosure where
  staticLeft' :: forall a b c.
(Typeable a, Typeable b, Typeable c) =>
WrappedArrowClosure a b
-> WrappedArrowClosure (Either a c) (Either b c)
staticLeft' (WrapArrowClosure Closure (a -> b)
sf) =
    Closure (Either a c -> Either b c)
-> WrappedArrowClosure (Either a c) (Either b c)
forall a b. Closure (a -> b) -> WrappedArrowClosure a b
WrapArrowClosure (Closure (Either a c -> Either b c)
 -> WrappedArrowClosure (Either a c) (Either b c))
-> Closure (Either a c -> Either b c)
-> WrappedArrowClosure (Either a c) (Either b c)
forall a b. (a -> b) -> a -> b
$ static (\a -> b
f -> (a -> b) -> (c -> c) -> Either a c -> Either b c
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f c -> c
forall a. a -> a
id) Closure ((a -> b) -> Either a c -> Either b c)
-> Closure (a -> b) -> Closure (Either a c -> Either b c)
forall a b.
Typeable a =>
Closure (a -> b) -> Closure a -> Closure b
`cap` Closure (a -> b)
sf
  staticRight' :: forall a b c.
(Typeable a, Typeable b, Typeable c) =>
WrappedArrowClosure a b
-> WrappedArrowClosure (Either c a) (Either c b)
staticRight' (WrapArrowClosure Closure (a -> b)
sg) =
    Closure (Either c a -> Either c b)
-> WrappedArrowClosure (Either c a) (Either c b)
forall a b. Closure (a -> b) -> WrappedArrowClosure a b
WrapArrowClosure (Closure (Either c a -> Either c b)
 -> WrappedArrowClosure (Either c a) (Either c b))
-> Closure (Either c a -> Either c b)
-> WrappedArrowClosure (Either c a) (Either c b)
forall a b. (a -> b) -> a -> b
$ static (\a -> b
g -> (c -> c) -> (a -> b) -> Either c a -> Either c b
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap c -> c
forall a. a -> a
id a -> b
g) Closure ((a -> b) -> Either c a -> Either c b)
-> Closure (a -> b) -> Closure (Either c a -> Either c b)
forall a b.
Typeable a =>
Closure (a -> b) -> Closure a -> Closure b
`cap` Closure (a -> b)
sg