Partial lift with elevator

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).

+4
source share

Source: https://habr.com/ru/post/1440581/


All Articles