2012-03-08 5 views
11

Se ho una pila di monadi, dicono IO, State e Error, e una funzione che utilizza solo IO e Error. Come si fa a "rimuovere" la monade centrale State dallo stack in modo da poter usare la mia funzione? Se l'ordine fosse IO, Error, State, potrei usare lift per abbinare i tipi, ma voglio essere in grado di usare la mia funzione se lo stack monad contiene IO e Error e possibilmente altre monadi in qualsiasi ordine. Per esempio:Manipolare lo stack monade

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

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

risposta

15

basta cambiare la firma tipo di fun a fun :: (MonadError String m, MonadIO m) => m(). Sarà quindi utilizzabile per qualsiasi stack monad che abbia un errore String e possa eseguire un IO (ad esempio ErrorT String (StateT Int IO)).

Esempio:

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

Questo è impressionante, grazie! –