haskell - learn - ¿Para qué sirve MonadBaseControl?
monad example (2)
Estoy profundizando en las mónadas de Yesod, y me he encontrado con MonadBaseControl
. Eché un vistazo al documento de hackage y me perdí. ¿Podría alguien decirme el problema que está tratando de resolver?
Michael Snoyman en realidad escribió un pequeño tutorial sobre el control de la mónada: http://www.yesodweb.com/book/monad-control
La esencia de ese artículo podría ser la siguiente:
Imagina que tienes este pedazo de código:
withMyFile :: (Handle -> IO a) -> IO a
withMyFile = withFile "test.txt" WriteMode
Puede aplicar withMyFile
a cualquier función del tipo Handle -> IO a
y obtener un buen valor de IO a
. Sin embargo, ¿qué Handle -> ErrorT MyError IO a
si tiene una función del tipo Handle -> ErrorT MyError IO a
y desea obtener un valor de tipo ErrorT MyError IO a
? Bueno, básicamente, tendrá que modificar con withMyFile
para incorporar mucho envoltorio / desenvolvimiento. MonadBaseControl le permite "levantar" algo las funciones, como withMyFile
a ciertos transfromers de mónada que permite desenvolver ("correr"). Por lo tanto, el código resultante se ve así:
useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ /run -> withMyFile $ run . func
Viene del paquete monad-control , y es una de un par de clases de tipo (la otra es MonadTransControl ) que mejora MonadBase (resp. MonadTrans ) al admitir una liftBase
(resp. lift
) para las mónadas que lo implementan. Esta versión mejorada ya no realiza una acción simple en la mónada base absoluta (resp. Mónada base inmediata), sino que toma una función que obtiene el estado completo de la mónada base (transformador de monada resp.) En ese punto como su único parámetro y devuelve el Acción antes mencionada.
Como se indica en la documentación del paquete, esta mejora, junto con el resto del contenido de estas clases de tipos, le permite levantar funciones como catch
, alloca
y forkIO
de la mónada base absoluta (resp. forkIO
base inmediata), lo que no es posible con el esquema más simple presente en MonadBase (resp. MonadTrans ) porque el último par no le permite levantar los argumentos de una función, solo los resultados , mientras que el enfoque adoptado por monad-control permite ambos.
Como resultado, el conjunto de mónadas (resp. Transformadores de mónada) que se pueden usar con MonadBaseControl (resp. MonadTransControl ) es un subconjunto estricto del conjunto de mónadas que se puede usar con MonadBase (resp. MonadTrans ), pero los grupos anteriores Son mucho más poderosos que los últimos por la misma razón.