{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds #-}
#endif
#if __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
-----------------------------------------------------------------------------
-- |
-- Copyright   :  (C) 2007-2015 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  portable
--
-- A semigroupoid satisfies all of the requirements to be a Category except
-- for the existence of identity arrows.
----------------------------------------------------------------------------
module Data.Semigroupoid.Dual (Dual(..)) where

import Data.Semigroupoid
import Control.Category
import Prelude ()

newtype Dual k a b = Dual { Dual k a b -> k b a
getDual :: k b a }

instance Semigroupoid k => Semigroupoid (Dual k) where
  Dual k k j
f o :: Dual k j k -> Dual k i j -> Dual k i k
`o` Dual k j i
g = k k i -> Dual k i k
forall k k (k :: k -> k -> *) (a :: k) (b :: k).
k b a -> Dual k a b
Dual (k j i
g k j i -> k k j -> k k i
forall k (c :: k -> k -> *) (j :: k) (k :: k) (i :: k).
Semigroupoid c =>
c j k -> c i j -> c i k
`o` k k j
f)

instance Category k => Category (Dual k) where
  id :: Dual k a a
id = k a a -> Dual k a a
forall k k (k :: k -> k -> *) (a :: k) (b :: k).
k b a -> Dual k a b
Dual k a a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  Dual k c b
f . :: Dual k b c -> Dual k a b -> Dual k a c
. Dual k b a
g = k c a -> Dual k a c
forall k k (k :: k -> k -> *) (a :: k) (b :: k).
k b a -> Dual k a b
Dual (k b a
g k b a -> k c b -> k c a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. k c b
f)