    {-# LANGUAGE CPP #-}
    {-# LANGUAGE Trustworthy #-}

    module Semigroupoids.Internal where

    #if MIN_VERSION_transformers(0,5,6)
    import qualified Control.Monad.Trans.RWS.CPS as CPS
    import qualified Control.Monad.Trans.Writer.CPS as CPS
    import Unsafe.Coerce (unsafeCoerce)
    #endif

    -- This is designed to avoid both https://hub.darcs.net/ross/transformers/issue/67
    -- and also the unnecessary Monoid constraints that the CPS versions of WriterT
    -- and RWST require.

    #if MIN_VERSION_transformers(0,5,6)
    mkWriterT :: (w -> m (a, w)) -> CPS.WriterT w m a
    mkWriterT :: forall w (m :: * -> *) a. (w -> m (a, w)) -> WriterT w m a
    mkWriterT = (w -> m (a, w)) -> WriterT w m a
    forall a b. a -> b
    unsafeCoerce

    unWriterT :: CPS.WriterT w m a -> w -> m (a, w)
    unWriterT :: forall w (m :: * -> *) a. WriterT w m a -> w -> m (a, w)
    unWriterT = WriterT w m a -> w -> m (a, w)
    forall a b. a -> b
    unsafeCoerce

    mkRWST :: (r -> s -> w -> m (a, s, w)) -> CPS.RWST r w s m a
    mkRWST :: forall r s w (m :: * -> *) a.
    (r -> s -> w -> m (a, s, w)) -> RWST r w s m a
    mkRWST = (r -> s -> w -> m (a, s, w)) -> RWST r w s m a
    forall a b. a -> b
    unsafeCoerce

    unRWST :: CPS.RWST r w s m a -> r -> s -> w -> m (a, s, w)
    unRWST :: forall r w s (m :: * -> *) a.
    RWST r w s m a -> r -> s -> w -> m (a, s, w)
    unRWST = RWST r w s m a -> r -> s -> w -> m (a, s, w)
    forall a b. a -> b
    unsafeCoerce
    #endif