content: {-# LANGUAGE TypeApplications, ImpredicativeTypes, ScopedTypeVariables,
               QuantifiedConstraints, StandaloneDeriving, GeneralizedNewtypeDeriving #-}
  
  module T15290a where
  
  import Prelude hiding ( Monad(..) )
  import Data.Coerce ( Coercible, coerce )
  
  class Monad m where
    join  :: m (m a) -> m a
  
  newtype StateT s m a = StateT { runStateT :: s -> m (s, a) }
  
  newtype IntStateT m a = IntStateT { runIntStateT :: StateT Int m a }
  
  instance Monad m => Monad (StateT s m) where
    join = error "urk"
  
  instance (Monad m, forall p q. Coercible p q => Coercible (m p) (m q))
        => Monad (IntStateT m) where
  
  --   Fails with the impredicative instantiation of coerce, succeeds without
  
  -- Impredicative version (fails)
      join = coerce
            @(forall a. StateT Int m (StateT Int m a) -> StateT Int m a)
            @(forall a. IntStateT m (IntStateT m a)   -> IntStateT m a)
            join
  
  
  -- Predicative version (succeeds)
  --    join = (coerce
  --           @(StateT Int m (StateT Int m a) -> StateT Int m a)
  --           @(IntStateT m (IntStateT m a)   -> IntStateT m a)
  --           join) :: forall a. IntStateT m (IntStateT m a)   -> IntStateT m a
  