Lassen Sie uns sagen, ich habe diese (wohl verleiten) Stück Code rumliegen:Lift Entweder zu Exceptt automatisch
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
gibt mir die folgende Fehlermeldung:
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
Was ist der normale Weg der Heben Sie eine Either
in eine ExceptT
? Ich fühle, dass es einen Weg geben muss, da Either String
eine Instanz von MonadError
ist.
Ich schrieb meine eigene Hebefunktion:
liftEither :: (Monad m, MonadError a (Either a)) => Either a b -> ExceptT a m b
liftEither = either throwError return
Aber mir das fühlt sich immer noch falsch, da ich bereits in der ExceptT
Monade Transformator arbeiten.
Was mache ich hier falsch? Soll ich meinen Code anders strukturieren?
Was ist mit 'AusgenommenT. zurückkommen? 'ExceptT = ExceptT (m (Entweder e a))', so bringt 'return' Sie zu' IO (Entweder String User) 'und' ExceptT' (als Konstruktor/Funktion) zu 'ExceptT String IO User'. – ibotty