6

タイプが別のタイプのサブタイプであるかどうかをチェックする関数があります。

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))

エラーハンドリングをしたい。私は次の定義を持っています:

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

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 ()

今、私は 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

チェックを入力しませんが、次のエラーが表示されます。

 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))

st の結果をどちらかとして扱うと、'st' の外側では機能するが、内側では機能しないのはなぜですか? 内部でも動作するようにコードを変更するにはどうすればよいですか?

4

1 に答える 1

5

show msg問題は、使用すべき場所で呼び出すことだと思いますmsg。その結果、コンパイラはあなたが意図したことを推測できませんEither String。それが知っているのはEither t、制約Show tが満たされる場所があるということだけです。に置き換えるshow msgmsg修正されます。

于 2009-06-03T01:55:31.193 に答える