title: How does EitherT work?
body: <p>I spend half of my day trying to figure out how to use EitherT as a way to deal with errors in my code.</p>
  
  <p>I have defined a transformer stack like this.</p>
  
  <pre><code>-- 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 -&gt; Stuff a -&gt; IO (Either T.Text a)
  askStuff config a = do
    t &lt;- getPOSIXTime 
    runEitherT (evalStateT (runReaderT (runStuff a) config) (StuffState Nothing t))
  </code></pre>
  
  <p>This works quite well as long as i only use the <code>ReaderT</code> and <code>StateT</code> functions. I am under the impression that now i should be able to write something like this:</p>
  
  <pre><code>faultyFunction :: String -&gt; Stuff String
  faultyFunction s = do
    when s == "left" $ left "breaking out"
    "right"
  </code></pre>
  
  <p>More important is capturing <code>Either</code> return values which should be possible with <code>hoistEither</code> from the <code>errors</code> package:</p>
  
  <pre><code>faultyLookup :: Map -&gt; String -&gt; Stuff String
  faultyLookup m k = do
    hoistEither $ lookup k m
  </code></pre>
  
  <p>I read the <em>real world haskell</em> chapter on monad transformers and fiddled around with <code>lift</code>. But I can't get anything to typecheck. </p>