{-# LANGUAGE StaticPointers #-}

module Data.Profunctor.Strong.Static where

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

class StaticProfunctor p => StaticStrong p where
  staticFirst'
    :: (Typeable a, Typeable b, Typeable c)
    => p a b -> p (a, c) (b, c)
  staticSecond'
    :: (Typeable a, Typeable b, Typeable c)
    => p a b -> p (c, a) (c, b)

instance StaticStrong WrappedArrowClosure where
  staticFirst' :: forall a b c.
(Typeable a, Typeable b, Typeable c) =>
WrappedArrowClosure a b -> WrappedArrowClosure (a, c) (b, c)
staticFirst' (WrapArrowClosure Closure (a -> b)
sf) =
    forall a b. Closure (a -> b) -> WrappedArrowClosure a b
WrapArrowClosure forall a b. (a -> b) -> a -> b
$ static (\a -> b
f (a
x, c
y) -> (a -> b
f a
x, c
y)) forall a b.
Typeable a =>
Closure (a -> b) -> Closure a -> Closure b
`cap` Closure (a -> b)
sf
  staticSecond' :: forall a b c.
(Typeable a, Typeable b, Typeable c) =>
WrappedArrowClosure a b -> WrappedArrowClosure (c, a) (c, b)
staticSecond' (WrapArrowClosure Closure (a -> b)
sf) =
    forall a b. Closure (a -> b) -> WrappedArrowClosure a b
WrapArrowClosure forall a b. (a -> b) -> a -> b
$ static (\a -> b
f (c
x, a
y) -> (c
x, a -> b
f a
y)) forall a b.
Typeable a =>
Closure (a -> b) -> Closure a -> Closure b
`cap` Closure (a -> b)
sf