私はHaskellでエラーを処理するために次のモナドトランスフォーマーを持っています。Haskellモナドと文字列を必要としないフェイル
instance (Monad m, Error e) => Monad (EitherT e m) where
return = EitherT . return . return
m >>= k = EitherT $ do
a <- runEitherT m
case a of
Left l -> return (Left l)
Right r -> runEitherT (k r)
fail = EitherT . return . Left . strMsg
私はカスタムクラスでError
をインスタンス化し、エラーを処理することにより、かなり柔軟な手段を持つことができるように、それは、かなりうまく動作します。
fail
は、タイプがString -> EitherT e m
であり、String
という制限がエラーを作成する厄介な方法になる可能性があるため、少しばかです。私は何をしたいのですが、私は(Error e)
制限を解除することができるようfail
のように、それはタイプa -> e
であり、新しい関数を作成することです
instance Error BazError where
strMsg "foo" = FooError -- oh look we have no error context
strMsg "bar" = BarError -- isn't that nice
:私はの全体の多くで終わります。 fail
はモナドスタックがより制限の少ないタイプでfail
と同じ動作を持つ関数を作成する方法はあります私は
EitherT BazError (StateT [BazWarning] IO) Foo
で終わるときのように、大きくなる場合には特に便利なのですか?または深いhaskell暗い魔法を使用してfail
が実装されていますか?
失敗した 'do'-blockパターンマッチの振る舞いをカスタマイズしない限り、単に' fail'を完全に避けるべきでしょう。 – ehird