Я рефакторинг некоторого старого кода, который находится в полиморфном, но ограниченном классе типов, монаде:
class ( MonadIO m
, MonadLogger m
, MonadLoggerIO m
, MonadThrow m
, MonadCatch m
, MonadMask m
, MonadBaseControl IO m
, MonadUnliftIO) => HasLogging m where
В старом коде основной монадой приложения была ...
type AppM = ReaderT Env IO
... который теперь изменится на ...
newtype AppM (features :: [FeatureFlag]) a = AppM (ReaderT Env IO a)
deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO)
Учитывая этот контекст, безопасно ли автоматически получать следующее:
- MonadThrow
- MonadCatch
- MonadMask
- MonadBaseControl
- MonadUliftIO
Не вдаваясь во внутренности GHC, как лучше всего развить интуицию о том, что на самом деле происходит, когда компилятор получает вещи автоматически?