为什么可以替换这些类型?

时间:2016-04-20 10:28:17

标签: haskell monads monad-transformers

有些事情似乎令人难以置信:

foo :: a -> StateT Env (ReaderT Env (ErrorT String IO)) String

可以替换为
foo :: a -> ErrorT String IO String

怎么可能?毕竟,它们是完全不同的类型......

1 个答案:

答案 0 :(得分:7)

显然,在所有情况下无法相互替换这些内容。例如,如果您明确使用ErrorT . return $ Left "Muahar",则此必须ErrorT String m a

但是,这两种类型都是a -> M String形式,带有(变换器堆栈)monad M,它是MonadIOMonadError String的实例。因此,如果仅使用liftIO ioaction形式的动作定义此函数,并且可能throwErrorcatchError,则它将作为任何这些monad工作。一般类型是

foo :: (MonadIO m, MonadError String m) => a -> m String