Ok, I boilded it down to this
:set -XQuantifiedConstraints -XUndecidableInstances -XTypeFamilies -XAllowAmbiguousTypes
:{
type BaseResult m a = BaseMonad m (StM m a)
class RunBase m where
type BaseMonad m :: * -> *
type StM m a :: *
runBase :: m a -> BaseResult m a
:}
:{
instance RunBase IO where
type BaseMonad IO = IO
type StM IO a = a
runBase = id
:}
newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)} deriving Functor
instance Applicative m => Applicative (MaybeT m) where pure = MaybeT . pure . Just; MaybeT x <*> MaybeT y = MaybeT $ fmap (<*>) x <*> y
:{
instance RunBase m => RunBase (MaybeT m) where
type BaseMonad (MaybeT m) = BaseMonad m
type StM (MaybeT m) a = StM m (Maybe a)
runBase = runBase . runMaybeT
:}
class Show (StM m a) => ShowWorks m a
instance Show (StM m a) => ShowWorks m a
:{
works :: forall m.
( forall a. Show a => ShowWorks m a
, RunBase m
, BaseMonad m ~ IO
, Applicative m
) => IO ()
works = do
print =<< runBase @m (pure ())
print =<< runBase @m (pure 'a')
:}
works @(MaybeT IO)
class (Show a, Show (StM m a)) => ShowFails m a
instance (Show a, Show (StM m a)) => ShowFails m a
:{
fails :: forall m.
( forall a. ShowFails m a
, RunBase m
, BaseMonad m ~ IO
, Applicative m
) => IO ()
fails = do
print =<< runBase @m (pure ())
print =<< runBase @m (pure 'a')
:}
fails @(MaybeT IO)
For me it produces:
<interactive>:47:4: error:
Could not deduce (Show (StM m ())) arising from a use of âprintâ
from the context: (forall a. ShowFails m a, RunBase m,
BaseMonad m ~ IO, Applicative m)
bound by the type signature for:
fails :: forall (m :: * -> *).
(forall a. ShowFails m a, RunBase m, BaseMonad m ~ IO,
Applicative m) =>
IO ()
at <interactive>:(40,1)-(45,12)
In the first argument of â(=<<)â, namely âprintâ
In a stmt of a 'do' block: print =<< runBase @m (pure ())
In the expression:
do print =<< runBase @m (pure ())
print =<< runBase @m (pure 'a')
<interactive>:48:4: error:
Could not deduce (Show (StM m Char))
arising from a use of âprintâ
from the context: (forall a. ShowFails m a, RunBase m,
BaseMonad m ~ IO, Applicative m)
bound by the type signature for:
fails :: forall (m :: * -> *).
(forall a. ShowFails m a, RunBase m, BaseMonad m ~ IO,
Applicative m) =>
IO ()
at <interactive>:(40,1)-(45,12)
In the first argument of â(=<<)â, namely âprintâ
In a stmt of a 'do' block: print =<< runBase @m (pure 'a')
In the expression:
do print =<< runBase @m (pure ())
print =<< runBase @m (pure 'a')