[Haskell-cafe] MonadPeelIO instance for monad transformers on top of "forall"

Anders Kaseorg andersk at MIT.EDU
Sat Feb 5 05:19:49 CET 2011

On Fri, 4 Feb 2011, Anders Kaseorg wrote:
> but isn’t M isomorphic to ReaderT () IO (via unM :: M a -> ReaderT () IO 
> a, M . mapReaderT liftIO :: IO a -> M a)?

Er, M . mapReaderT liftIO :: ReaderT () IO a -> M a.  Of course that 
doesn’t actually type check until you eta-expand it: (\x -> M (mapReaderT 
liftIO x)) :: ReaderT () IO a -> M a.

Just to demonstrate that I didn’t use the triviality of ReaderT (), here’s 
a less trivial example with ReaderT and StateT:

  data M a = M { unM :: forall m. MonadPeelIO m => ReaderT Int (StateT Char m) a }
  instance Monad M
    return x = M (return x)
    M mx >>= fxmy = M (mx >>= unM . fxmy)
  instance MonadIO M where
    liftIO io = M (liftIO io)

  -- M ≅ ReaderT Int (StateT Char IO)
  fromM :: M a -> ReaderT Int (StateT Char IO) a
  fromM = unM
  toM :: ReaderT Int (StateT Char IO) a -> M a
  toM mx = M (mapReaderT (mapStateT liftIO) mx)

  instance MonadPeelIO M where
    peelIO = toM (liftM (\k (M mx) -> liftM toM (k mx)) peelIO)


More information about the Haskell-Cafe mailing list