#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706 && MIN_VERSION_base(4,7,0)
# define LANGUAGE_PolyKinds
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
# define LANGUAGE_DeriveDataTypeable
#else
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
# if defined(LANGUAGE_DeriveDataTypeable)
# else
# endif
#endif
module Control.Natural ((:~>)(..)) where
#if defined(LANGUAGE_PolyKinds)
import qualified Control.Category as C (Category(..))
#endif
#if !(MIN_VERSION_base(4,8,0))
import Data.Monoid (Monoid(..))
#endif
import Data.Typeable
infixr 0 :~>, $$
newtype f :~> g = Nat { ($$) :: forall x. f x -> g x }
#if defined(LANGUAGE_DeriveDataTypeable)
deriving Typeable
#else
instance (Typeable1 f, Typeable1 g) => Typeable (f :~> g) where
typeOf _ = mkTyConApp natTyCon [typeOf1 (undefined :: f a), typeOf1 (undefined :: g a)]
natTyCon :: TyCon
# if MIN_VERSION_base(4,4,0)
natTyCon = mkTyCon3 "natural-transformation" "Control.Natural" ":~>"
# else
natTyCon = mkTyCon ":~>"
# endif
#endif
#if defined(LANGUAGE_PolyKinds)
instance C.Category (:~>) where
id = Nat id
Nat f . Nat g = Nat (f . g)
#endif
instance f ~ g => Monoid (f :~> g) where
mempty = Nat id
mappend (Nat f) (Nat g) = Nat (f . g)