2016-05-11 66 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)