我花了半天时间试图弄清楚如何使用 EitherT 来处理我的代码中的错误。
我已经定义了一个这样的变压器堆栈。
-- Stuff Monad
data StuffConfig = StuffConfig {
  appId     :: T.Text,
  appSecret :: T.Text
}
data StuffState = StuffState {
  stateToken :: Maybe Token,
  stateTime  :: POSIXTime
}
newtype Stuff a = Stuff {
  runStuff :: (ReaderT StuffConfig (StateT StuffState (EitherT T.Text IO))) a
} deriving (Monad, Functor, Applicative, 
            MonadIO, 
            MonadReader StuffConfig,
            MonadState StuffState
            )
askStuff :: StuffConfig -> Stuff a -> IO (Either T.Text a)
askStuff config a = do
  t <- getPOSIXTime 
  runEitherT (evalStateT (runReaderT (runStuff a) config) (StuffState Nothing t))
只要我只使用ReaderTandStateT函数,它就可以很好地工作。我的印象是现在我应该能够写出这样的东西:
faultyFunction :: String -> Stuff String
faultyFunction s = do
  when s == "left" $ left "breaking out"
  "right"
更重要的是从包中捕获Either应该可能的返回值:hoistEithererrors
faultyLookup :: Map -> String -> Stuff String
faultyLookup m k = do
  hoistEither $ lookup k m
我阅读了关于 monad 转换器的真实世界的 haskell章节并摆弄了lift. 但是我无法进行任何类型检查。