2012-03-08 20 views
11

Nếu tôi có một chồng monads, hãy nói IO, StateError và chức năng chỉ sử dụng IOError. Làm thế nào sẽ đi về "loại bỏ" giữa State monad từ ngăn xếp để tôi có thể sử dụng chức năng của tôi? Nếu đơn hàng là IO, Error, State, tôi có thể sử dụng lift để khớp với các loại, nhưng tôi muốn có thể sử dụng chức năng của mình nếu ngăn đơn nguyên chứa IOError và có thể là các đơn vị khác theo thứ tự bất kỳ. Ví dụ:Thao tác ngăn xếp đơn nguyên

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

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

Trả lời

15

Chỉ cần thay đổi kiểu chữ ký của fun để fun :: (MonadError String m, MonadIO m) => m(). Sau đó, nó sẽ có thể sử dụng được cho bất kỳ ngăn xếp đơn lẻ nào có lỗi String và có thể thực hiện IO (chẳng hạn như ErrorT String (StateT Int IO)).

Ví dụ:

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

Đây là tuyệt vời, cảm ơn! –