2012-03-08 11 views
11

Si tengo una pila de mónadas, dicen IO, State y Error, y una función que sólo utiliza IO y Error. ¿Cómo se podría "quitar" la mónada State del medio de la pila para poder usar mi función? Si la orden era IO, Error, State, podría usar lift para que coincida con los tipos, pero quiero poder usar mi función si la pila de mónada contiene IO y Error y posiblemente otras mónadas en cualquier orden. Por ejemplo:mónada

fun :: ErrorT String IO() 
fun = throwError "error" 

someCode :: ErrorT String (StateT Int IO)() 
someCode = do 
    -- I want to use fun here 

Respuesta

15

Sólo cambia la firma tipo de fun a fun :: (MonadError String m, MonadIO m) => m(). Entonces se podrá utilizar para cualquier pila de mónada que tenga un error String y pueda realizar IO (como ErrorT String (StateT Int IO)).

Ej:

fun :: (MonadError String m, MonadIO m) => m() 
fun = do 
    liftIO $ putStrLn "in fun" 
    throwError "error" 

someCode :: ErrorT String (StateT Int IO)() 
someCode = do 
    fun 
    -- whatever you want 
+0

Esto es impresionante, gracias! –