5

次のコードを書いていることに気付いたので、モナド変換子の基本的な理解が欠けていると思います。

import Control.Monad.Identity
import Control.Monad.Error

liftError :: Either String Int -> ErrorT String Identity Int
liftError x = do case x of
                    Right val -> return val
                    Left err -> throwError err

gateway :: Bool -> ErrorT String Identity Int
gateway = liftError . inner

inner :: Bool -> Either String Int
inner True = return 5
inner False = throwError "test"

これは機能しますが、もっとエレガントにできると思います。liftError特に、自分で定義する必要はないと思うの代わりを探しています。

gatewayタイプを変更せずに作成してinner連携する最も簡単な方法は何ですか?

4

1 に答える 1

6

タイプを少し変更するだけで、持ち上げる必要はまったくありません。

{-# LANGUAGE FlexibleContexts #-}

gateway :: Bool -> ErrorT String Identity Int
gateway = inner

inner :: MonadError String m => Bool -> m Int
inner True = return 5
inner False = throwError "test"

MonadErrorErrorTにはとの両方のインスタンスがEitherあるため、この方法で両方として使用できますinner

于 2012-04-04T18:10:58.463 に答える