module Control.Invertible.BiArrow
( BiArrow(..)
, BiArrow'
, biarr
, involve
, (^^>>)
, (>>^^)
, (<<^^)
, (^^<<)
) where
import Prelude hiding ((.))
import Control.Arrow
import Control.Category
import Data.Invertible.Bijection
#ifdef VERSION_semigroupoids
import Data.Semigroupoid (Semigroupoid(..))
import Data.Groupoid (Groupoid(..))
import qualified Data.Isomorphism as Semigroupoid
#define SemigroupoidArrowA (Semigroupoid a, Arrow a)
#else
#define SemigroupoidArrowA Arrow a
#endif
#ifdef VERSION_TypeCompose
import qualified Data.Bijection as TypeCompose
#endif
#ifdef VERSION_partial_isomorphisms
import qualified Control.Isomorphism.Partial as Partial
import qualified Control.Isomorphism.Partial.Unsafe as Partial
#endif
#ifdef VERSION_arrows
import qualified Control.Arrow.Transformer.All as T
#endif
infix 2 <->
class (
#ifdef VERSION_semigroupoids
Groupoid a,
#endif
Category a) => BiArrow a where
(<->) :: (b -> c) -> (c -> b) -> a b c
invert :: a b c -> a c b
#ifdef VERSION_semigroupoids
invert = inv
#endif
class (BiArrow a, Arrow a) => BiArrow' a
biarr :: BiArrow a => (b <-> c) -> a b c
biarr (f :<->: g) = f <-> g
involve :: BiArrow a => (b -> b) -> a b b
involve f = f <-> f
infixr 1 ^^>>, >>^^
infixr 1 ^^<<, <<^^
(^^>>) :: BiArrow a => (b <-> c) -> a c d -> a b d
f ^^>> a = biarr f >>> a
(>>^^) :: BiArrow a => a b c -> (c <-> d) -> a b d
a >>^^ f = a >>> biarr f
(<<^^) :: BiArrow a => a c d -> (b <-> c) -> a b d
a <<^^ f = a <<< biarr f
(^^<<) :: BiArrow a => (c <-> d) -> a b c -> a b d
f ^^<< a = biarr f <<< a
instance SemigroupoidArrowA => BiArrow (Bijection a) where
f <-> g = arr f :<->: arr g
invert (f :<->: g) = g :<->: f
instance SemigroupoidArrowA => BiArrow' (Bijection a)
#ifdef VERSION_semigroupoids
instance (Semigroupoid a, Arrow a) => BiArrow (Semigroupoid.Iso a) where
f <-> g = Semigroupoid.Iso (arr f) (arr g)
#endif
#ifdef VERSION_TypeCompose
#ifdef VERSION_semigroupoids
instance Semigroupoid a => Semigroupoid (TypeCompose.Bijection a) where
TypeCompose.Bi f1 g1 `o` TypeCompose.Bi f2 g2 = TypeCompose.Bi (o f1 f2) (o g2 g1)
instance Semigroupoid a => Groupoid (TypeCompose.Bijection a) where
inv = TypeCompose.inverse
#endif
instance SemigroupoidArrowA => BiArrow (TypeCompose.Bijection a) where
f <-> g = TypeCompose.Bi (arr f) (arr g)
invert = TypeCompose.inverse
instance SemigroupoidArrowA => BiArrow' (TypeCompose.Bijection a)
#endif
#ifdef VERSION_partial_isomorphisms
#ifdef VERSION_semigroupoids
instance Semigroupoid Partial.Iso where
o = (.)
instance Groupoid Partial.Iso where
inv = Partial.inverse
#endif
instance BiArrow Partial.Iso where
f <-> g = Partial.Iso (Just . f) (Just . g)
invert = Partial.inverse
#endif
#ifdef VERSION_arrows
#ifdef VERSION_semigroupoids
instance Semigroupoid a => Semigroupoid (T.StateArrow s a) where
T.StateArrow f `o` T.StateArrow g = T.StateArrow (f `o` g)
instance Groupoid a => Groupoid (T.StateArrow s a) where
inv (T.StateArrow f) = T.StateArrow (inv f)
instance Semigroupoid a => Semigroupoid (T.CoStateArrow s a) where
T.CoStateArrow f `o` T.CoStateArrow g = T.CoStateArrow (f `o` g)
instance Groupoid a => Groupoid (T.CoStateArrow s a) where
inv (T.CoStateArrow f) = T.CoStateArrow (inv f)
instance Semigroupoid a => Semigroupoid (T.StreamArrow a) where
T.StreamArrow f `o` T.StreamArrow g = T.StreamArrow (f `o` g)
instance Groupoid a => Groupoid (T.StreamArrow a) where
inv (T.StreamArrow f) = T.StreamArrow (inv f)
#endif
instance (Arrow a, BiArrow a) => BiArrow (T.StateArrow s a) where
f <-> g = T.StateArrow (first $ f <-> g)
invert (T.StateArrow f) = T.StateArrow (invert f)
instance BiArrow' a => BiArrow' (T.StateArrow s a)
instance BiArrow a => BiArrow (T.CoStateArrow s a) where
f <-> g = T.CoStateArrow ((f .) <-> (g .))
invert (T.CoStateArrow f) = T.CoStateArrow (invert f)
instance BiArrow' a => BiArrow' (T.CoStateArrow s a)
instance BiArrow a => BiArrow (T.StreamArrow a) where
f <-> g = T.StreamArrow (fmap f <-> fmap g)
invert (T.StreamArrow f) = T.StreamArrow (invert f)
instance BiArrow' a => BiArrow' (T.StreamArrow a)
#endif