のは、私はこの(間違いなく誤解を)持っているとしましょう転がっコードの一部:リフトのいずれかを自動的に
import System.Environment (getArgs)
import Control.Monad.Except
parseArgs :: ExceptT String IO User
parseArgs =
do
args <- lift getArgs
case safeHead args of
Just admin -> parseUser admin
Nothing -> throwError "No admin specified"
parseUser :: String -> Either String User
-- implementation elided
safeHead :: [a] -> Maybe a
-- implementation elided
main =
do
r <- runExceptT parseArgs
case r of
Left err -> putStrLn $ "ERROR: " ++ err
Right res -> print res
ghc
は私に次のエラーを与える:ほとんどの標準的な方法は何
Couldn't match expected type ‘ExceptT String IO User’
with actual type ‘Either String User’
In the expression: parseUser admin
In a case alternative: Just admin -> parseUser admin
Either
をExceptT
に持ち上げますか? Either String
はMonadError
のインスタンスなので、何らかの方法が必要であると私は感じています。
私は自分の昇降機能を書いた:
liftEither :: (Monad m, MonadError a (Either a)) => Either a b -> ExceptT a m b
liftEither = either throwError return
しかし、私には、私はすでに ExceptT
モナド変換子の内部で働いているので、これはまだ間違って感じています。
私はここで間違っていますか?自分のコードを違う構造にする必要がありますか?
「例外」についてはどうですか。戻る? 'ExceptT = ExceptT = m(Either)')、 'return'は' IO(いずれかの文字列ユーザ) 'と 'ExceptT'(コンストラクタ/関数として)を' ExceptT String IO User'にします。 – ibotty