title: Typeclass deduction error when using type constraints
body: <p>I have this function:</p>
  
  <pre><code>sTest :: (MonadState s m, MonadError e m) =&gt; m ()
  sTest = do
    s &lt;- get
    throwError "abc"
    put s
  </code></pre>
  
  <p>When compiling, I got a typeclass deduction error:</p>
  
  <pre><code>• Could not deduce (MonadError [Char] m)
      arising from a use of ‘throwError’
    from the context: (MonadState s m, MonadError e m)
      bound by the type signature for:
                 sTest :: (MonadState s m, MonadError e m) =&gt; m ()
      at ...
  • In a stmt of a 'do' block: throwError "abc"
    In the expression:
      do { s &lt;- get;
           throwError "abc";
           put s }
    In an equation for ‘sTest’:
        sTest
          = do { s &lt;- get;
                 throwError "abc";
                 put s }
  </code></pre>
  
  <p>If I change the <code>throwError</code> to throw an <code>Int</code> instead (and add a <code>Num</code> constraint) then the compilation is success:</p>
  
  <pre><code>sTest :: (Num e, MonadState s m, MonadError e m) =&gt; m ()
  sTest = do
    s &lt;- get
    throwError 123
    put s
  </code></pre>
  
  <p>Can anyone explain me about this?</p>
  
  <p><strong>Update #1</strong></p>
  
  <p>I create a new type for the errors:</p>
  
  <pre><code>data EvalError = VarNotFound
    | PlusParamsMustBeIntVal
    | FirstAppParamMustBeFunVal
    | OtherError String
    deriving (Show)
  
  instance Error EvalError where
    strMsg = OtherError
  
  sTest :: (Error e, MonadState s m, MonadError e m) =&gt; m ()
  sTest = do
    s &lt;- get
    throwError $ OtherError "abc"
    put s
  </code></pre>
  
  <p>But the compilation is still not success:</p>
  
  <pre><code>• Could not deduce (MonadError EvalError m)
      arising from a use of ‘throwError’
    from the context: (Error e, MonadState s m, MonadError e m)
      bound by the type signature for:
                 sTest :: (Error e, MonadState s m, MonadError e m) =&gt; m ()
      at ...
  • In a stmt of a 'do' block: throwError $ OtherError "abc"
    In the expression:
      do { s &lt;- get;
           throwError $ OtherError "abc";
           put s }
    In an equation for ‘sTest’:
        sTest
          = do { s &lt;- get;
                 throwError $ OtherError "abc";
                 put s }
  </code></pre>