I am trying to do something that is probably not possible. I have a type that is an instance of MonadIO . If you liftIO a IO action in a context where this type is the base monad of any transformer stack, it will work fine. Thus, I would like this to be done, to accept a value that has already been partially removed (to my type) and raise it βto the endβ in one step.
I can do this in two ways. Firstly, my type can indeed be trivially re-injected into regular IO, so I can do this:
liftMore :: (MonadIO m) => MyType a -> ma liftMore x = liftIO $ embedMyTypeInIO x
And it works. However, it also makes it possible to completely get out of my type if used in a context where IO is simply the base monad, which is undesirable.
I can also do this by creating a new class of type MonadIO that uses my type as the base, but then it should be created for anything that is very undesirable. I tried using the newtype shell to make each monad transformer an instance of this class, but could not get it.
Any ideas on strategies I could try to implement? (I am ready to play with language extensions, but of course, the Haskell98 solution is much preferable).
source share