2012-03-08 10 views
11

Jeśli mam stos monad, powiedzmy IO, State i Error i funkcję, która korzysta tylko IO i Error. Jak zabrałbyś się za "usunięcie" środkowej monady State ze stosu, aby móc korzystać z mojej funkcji? Jeśli zamówienie było IO, Error, State, mogę użyć lift, aby dopasować typy, ale chcę móc korzystać z mojej funkcji, jeśli stos monad zawiera IO i Error i ewentualnie inne monady w dowolnej kolejności. Na przykład:Manipulowanie monada stos

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

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

Odpowiedz

15

Wystarczy zmienić podpis typu z fun do fun :: (MonadError String m, MonadIO m) => m(). Będzie wtedy można użyć dowolnego stosu monad, który ma błąd String i może wykonać IO (na przykład ErrorT String (StateT Int IO)).

Np

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

To jest niesamowite, dzięki! –