简体   繁体   English

使用类型约束时类型类推导错误

[英]Typeclass deduction error when using type constraints

I have this function: 我有这个功能:

sTest :: (MonadState s m, MonadError e m) => m ()
sTest = do
  s <- get
  throwError "abc"
  put s

When compiling, I got a typeclass deduction error: 编译时,我得到了一个类型类扣除错误:

• 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) => m ()
    at ...
• In a stmt of a 'do' block: throwError "abc"
  In the expression:
    do { s <- get;
         throwError "abc";
         put s }
  In an equation for ‘sTest’:
      sTest
        = do { s <- get;
               throwError "abc";
               put s }

If I change the throwError to throw an Int instead (and add a Num constraint) then the compilation is success: 如果我更改throwError以改为抛出Int (并添加Num约束),那么编译成功:

sTest :: (Num e, MonadState s m, MonadError e m) => m ()
sTest = do
  s <- get
  throwError 123
  put s

Can anyone explain me about this? 任何人都能解释一下这个吗?

Update #1 更新#1

I create a new type for the errors: 我为错误创建了一个新类型:

data EvalError = VarNotFound
  | PlusParamsMustBeIntVal
  | FirstAppParamMustBeFunVal
  | OtherError String
  deriving (Show)

instance Error EvalError where
  strMsg = OtherError

sTest :: (Error e, MonadState s m, MonadError e m) => m ()
sTest = do
  s <- get
  throwError $ OtherError "abc"
  put s

But the compilation is still not success: 但编译仍然没有成功:

• 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) => m ()
    at ...
• In a stmt of a 'do' block: throwError $ OtherError "abc"
  In the expression:
    do { s <- get;
         throwError $ OtherError "abc";
         put s }
  In an equation for ‘sTest’:
      sTest
        = do { s <- get;
               throwError $ OtherError "abc";
               put s }
throwError :: MonadError e m => e -> m a

这里throwError "abc"使得e等于String ,所以你需要MonadError String m

sTest :: (MonadState s m, MonadError String m) => m ()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM