有些事情似乎令人难以置信:
foo :: a -> StateT Env (ReaderT Env (ErrorT String IO)) String
可以替换为
foo :: a -> ErrorT String IO String
怎么可能?毕竟,它们是完全不同的类型......
答案 0 :(得分:7)
显然,在所有情况下无法相互替换这些内容。例如,如果您明确使用ErrorT . return $ Left "Muahar"
,则此必须为ErrorT String m a
。
但是,这两种类型都是a -> M String
形式,带有(变换器堆栈)monad M
,它是MonadIO
和MonadError String
的实例。因此,如果仅使用liftIO ioaction
形式的动作定义此函数,并且可能throwError
和catchError
,则它将作为任何这些monad工作。一般类型是
foo :: (MonadIO m, MonadError String m) => a -> m String