使用任一monad在Haskell中进行错误处理

时间:2022-08-18 17:03:34

I have a function that checks whether a type is a subtype of another type:

我有一个函数,检查类型是否是另一种类型的子类型:

st :: Monad m => Map String Type  -- ^type environment
   -> Set (Type, Type) -- ^assumed subtypes
   -> (Type, Type) -- ^we are checking if lhs <: rhs      
   -> m (Set (Type, Type))

I want to do error handling. I have the following definition:

我想做错误处理。我有以下定义:

instance Monad (Either String) where
  return v = Right v
  fail s = Left s
  (Left s) >>= _ = Left s
  (Right v) >>= f = f v

Sometimes I can do error handling by treating the result of st as Either. For example, the following function works, and gets me the messages that result from invoking "fail" inside st:

有时我可以通过将st的结果视为Either来进行错误处理。例如,以下函数有效,并获取在st中调用“fail”导致的消息:

isSubType env cs t1 t2 = result where
  result = case st env (S.empty) (t1, t2) of
    Left msg -> Left msg
    Right rel -> Right ()

Now, I'm inside st and I want to recursively call it. For some reason, the following code, nested deep in st:

现在,我在里面,我想以递归方式调用它。出于某种原因,下面的代码深入嵌入st:

  let do_t1 rel t1 = case st env rel (t1, t2) of
        Left msg -> fail $ printf "type %s in the union is not a subtype\
                           \ of the rhs, %s, because: %s" (renderType t1)
                           (renderType t2) (show msg)
        Right rel -> return rel

Does not type check, but gives me the following error:

不键入检查,但给我以下错误:

 No instance for (Monad (Either t))
      arising from a use of `st'
                   at src/TypedJavaScript/Types.hs:386:24-42
    Possible fix: add an instance declaration for (Monad (Either t))

Why does treating the result of st as Either work outside of 'st' but not inside? How can I change my code such that it works inside, too?

为什么将st的结果视为'st'之外的工作而不是在'st'之外?如何更改我的代码以使其在内部工作?

1 个解决方案

#1


I think the problem is that you call show msg where you should just use msg. As a result, the compiler can't deduce that you meant Either String; all it knows is that you have Either t where the constraint Show t is satisfied. Replacing show msg with msg should fix it.

我认为问题是你调用show msg你应该只使用msg。因此,编译器无法推断出您的意思是字符串;所有它知道的是你有一个约束显示t满足的地方。用msg替换show msg应该修复它。

#1


I think the problem is that you call show msg where you should just use msg. As a result, the compiler can't deduce that you meant Either String; all it knows is that you have Either t where the constraint Show t is satisfied. Replacing show msg with msg should fix it.

我认为问题是你调用show msg你应该只使用msg。因此,编译器无法推断出您的意思是字符串;所有它知道的是你有一个约束显示t满足的地方。用msg替换show msg应该修复它。