можно еще больше ограничить скоуп возможностей
class Monad m => MonadFS m where
readF :: FilePath -> m ByteString
writeF :: FilePath -> ByteString -> m ()
myAction :: MonadFS m => m ()
myAction = do
a <- readF "a"
writeF "b" a
instance MonadFS IO where
readF = BS.readFile
writeF = BS.writeFile
main = myAction -- но мы точно знаем, что в myAction не может быть ничего из эффектов кроме работы с файлами