Earlier quoted context omitted.
I think the point is that there is no good effect-union type; this has to be pieced together with monad transformers where you might have that types "Atransformer (Btransformer C)" is not equal to "Btransformer (Atransformer C)". This is, for example, why Haskell has one monolithic "IO" monad instead of one for hitting the filesystem, one for HTTP requests, one for IORefs, etc. Haskell does not, for example, represen…
I'm kind of interested in knowing why you don't think that there isn't an isomorphism along the ordering of the monad transformers. Wouldn't it just be a question of rebuilding combinators so that they're targetting the right depth? Or am I missing something
Consider MaybeT and WriterT (and the basic Identity monad for the bottom of our stack)
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
newtype Identity a = Identity { runIdentity :: a }
I'm going to claim that MaybeT (WriterT w Identity) is not isomorphic to WriterT w (MaybeT Identity). If we expand the first MaybeT (WriterT w Identity) a
==
WriterT w Identity (Maybe a)
==
Identity (Maybe a, w)
==
(Maybe a, w)
And if we expand the second WriterT w (MaybeT Identity) a
==
MaybeT Identity (a, w)
==
Identity (Maybe (a, w))
==
Maybe (a, w)
So we can see that the Maybe is wrapped around something different in each stack. So now to the claim that there's no isomorphism should be obvious---any witnesses to the isomorphism f and g would have to have that for all w, f (g (Nothing, w)) = (Nothing, w), but since g :: (Maybe a, w) -> Maybe (a, w) cannot fabricate an `a`, it must be such that g (Nothing, w) = Nothing which means that f :: Maybe (a, w) -> (Maybe a, w) cannot determine the right `w` to return.