Si desea utilizar la mónada subyacente en un transformador mónada, puede utilizar lift
:
lift :: (MonadTrans t, Monad m) => m a -> t m a
En este caso, es t
StateT MyState
y m
es MyMonad
. Así, por ejemplo: transformadores
foo :: StateT MyState MyMonad MyType
foo = do
modify $ \s -> s+1
lift $ doSomethingInMyMonad 42
Monad no están "en capas sobre" en el sentido de que le devuelve un valor de tipo MyMonad MyType
desde el interior; es una transformación más literal : convierten una mónada en una nueva que tiene la capacidad de ejecutar acciones en la mónada transformada. Por lo tanto, puede pensar en StateT s m
como la mónada normal State s
, excepto que también puede usar lift
para ejecutar acciones de giro en m
en acciones en StateT s m
.
Si está utilizando los Monad Transformer Library transformadores (MTL) como estándar StateT
, ReaderT
, etc., que no realmente tiene que usar lift
; cosas como modify
y ask
funcionan en cualquiera mónada con el transformador correcto en algún lugar de la pila. (Una pila es sólo una torre de mónadas transformadas, como StateT s (ReaderT r IO)
.)
Además, si usted tiene una gran pila con IO
en la parte inferior, hay una función de conveniencia para el levantamiento de una acción IO
cualquier número de capas:
liftIO :: (MonadIO m) => IO a -> m a
así liftIO (putStrLn "Hello, world!")
obras en IO
, StateT Int IO
, ContT r (WriterT [String] IO)
, y así sucesivamente.
(Como nota adicional, foo
aquí no es realmente una función, un término más preciso es acción o cálculo .)
En caso de que usted no sabe acerca de Hoogle: http: // www.haskell.org/hoogle – jberryman