2012-03-08 46 views
11

如果我有單子一堆,說IOStateError,並且只使用IOError功能。如何從堆棧中刪除中間的State monad以便我可以使用我的函數?如果訂單是IOErrorState,我可以用lift相匹配的類型,但我希望能夠用我的功能,如果單子堆棧包含IOError並有可能在任何秩序的其他單子。例如:操縱單子堆棧

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

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

回答

15

fun類型簽名就變成fun :: (MonadError String m, MonadIO m) => m()。它隨後可用於任何具有String錯誤的monad堆棧,並且可以執行IO(例如ErrorT String (StateT Int IO))。

如:

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

這是真棒,謝謝! – 2012-03-08 01:46:39