Related to MonadTransControl instance for a custom monad where, unfortunately (but understandably) the author gave up on monad-control
. However, that is not an option for me, because I need to use Control.Concurrent.Async.Lifted
within my custom monad:
{-# LANGUAGE DataKinds, GADTs, ScopedTypeVariables #-}
data FeatureFlag = Feature1 | Feature2
newtype AppM (features :: [FeatureFlag]) a = AppM (ReaderT Env IO a)
deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO)
I've tried reading https://www.stackage.org/haddock/lts-12.1/monad-control-1.0.2.3/Control-Monad-Trans-Control.html but nothing seems to be making sense to me. Conceptually I understand why MonadBaseControl
and friends are required, thanks to the walk-through at https://www.yesodweb.com/book/monad-control , but I can't figure out how to implement this.
The official docs have an implementation guide at the very top, but it assumes monad-transformers:
Define instances MonadTransControl T for all transformers T, using the defaultLiftWith and defaultRestoreT functions on the constructor and deconstructor of T.
[...]
Define instances MonadBaseControl B m => MonadBaseControl B (T m) for all transformers:
How do I write a sensible instance for MonadBaseControl IO (AppM fs)
where the fs
part is preserved when the monad is unwrapped and wrapped again? Also, I'm assuming that I don't really have to implement MonadTransControl
, because AppM fs
is not a transformer.
PS: Also related - Is it safe to derive MonadThrow, MonadCatch, MonadBaseControl, MonadUnliftIO, etc?
ReaderT
's instance? – Daniel Wagner