2016-05-11 64 views
-3
newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) } 

instance (Monad m, Error e) => Monad (ErrorT e m) where 
m >>= k = ErrorT $ do 
    a <- runErrorT m 
    case a of 
     Left l -> return (Left l) 
     Right r -> runErrorT (k r) 

ErrorT僅僅是一個值的構造函數(類型構造也一樣),並獲得該類型的實例(獲得ErrorT值),我們要調用一個構造函數參數 - 一個函數(析構函數),它獲取ErrorT並返回內部monad,在我們的例子中它是任何m(可以是ea)。所以,在綁定函數中它被定義爲:m >>= k = ErrorT $ ...。但是,在其定義中,它稱爲runErrorT,這只是定義。所以像遞歸調用。但是,我想這裏沒有遞歸。這意味着我誤解了monad/monad變形金剛。請幫忙:)ErrorT綁定功能

+0

你的實際問題是什麼? – epsilonhalbe

回答

3

我覺得你很困惑newtype包裝。被定義的ErrorT結果在兩個函數的NEWTYPE定義:

ErrorT :: m (Either e a) -> ErrorT e m a 
runErrorT :: ErrorT e m a -> m (Either e a) 

所以在(>>=)定義,ErrorT $ do ...指構造爲ErrorT NEWTYPE而

a <- runErrorT m 
runErrorT (k r) 

參閱「展開」功能提取底層的m (Either e a)