Подтвердить что ты не робот

Для чего нужен MonadBaseControl?

Я углубляюсь в монады Есода, и столкнулся с MonadBaseControl. Я взглянул на документ о взломе и потерялся. Может ли кто-нибудь сказать мне проблему, которую он пытается решить?

4b9b3361

Ответ 1

Он поставляется из пакета monad-control и является одним из двух классов типов (другой MonadTransControl), которые улучшают MonadBase (соответственно MonadTrans), поддерживая альтернативу liftBase (соответственно lift) для монодаров, которые ее реализуют. Эта расширенная версия больше не принимает простых действий в абсолютной базовой монаде (соответственно немедленной базовой монаде), но вместо этого принимает функцию, которая получает полное состояние базовой монады (соответственно монада-трансформатора) в этой точке в качестве единственного параметра и возвращает вышеупомянутое действие.

Как указывается в документации к пакету, это усовершенствование, наряду с остальной частью содержимого этих классов типов, позволяет вам снимать функции, такие как catch, alloca и forkIO из абсолютной базовой монады (соответственно. немедленная базовая монада), что невозможно в более простой схеме, представленной в MonadBase (соответственно MonadTrans), потому что последняя пара не позволяет вам поднять аргументы функции, просто результаты, в то время как подход, используемый monad-control, позволяет обоим.

В результате набор монадов (соответственно монад-трансформаторов), которые можно использовать с MonadBaseControl (соответственно MonadTransControl) является строгим подмножеством множества монад, которые можно использовать с MonadBase (соответственно MonadTrans), но первые группы намного сильнее, чем последние по той же причине.

Ответ 2

Майкл Сноян на самом деле написал небольшой учебник по монад-контролю: http://www.yesodweb.com/book/monad-control

Суть этой статьи может быть следующей:

Представьте, что у вас есть этот фрагмент кода:

withMyFile :: (Handle -> IO a) -> IO a
withMyFile = withFile "test.txt" WriteMode

Вы можете применить withMyFile к любой функции типа Handle -> IO a и получить хорошее значение IO a. Однако, что, если у вас есть функция типа Handle -> ErrorT MyError IO a и вы хотите получить значение типа ErrorT MyError IO a? Ну, в основном, вам придется изменить withMyFile, чтобы включить много обертывания/разворачивания. MonadBaseControl позволяет несколько "поднять" функции, такие как withMyFile, к определенным трансформаторам монады, которые позволяют разворачивать ( "работает" ). Таким образом, полученный код выглядит следующим образом:

useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ \run -> withMyFile $ run . func