タイプが別のタイプのサブタイプであるかどうかをチェックする関数があります。
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' の外側では機能するが、内側では機能しないのはなぜですか? 内部でも動作するようにコードを変更するにはどうすればよいですか?