不久前,我写了一系列帖子,回顾了我自己对Either
&EitherT
类型的了解。你可以在这里阅读:http ://watchchrislearn.com/blog/2013/12/01/working-entirely-in-eithert/
我使用该errors
包来获得一堆使用 EitherT 的好帮手(left
以及right
例如返回 and 的提升版本的函数Left
)Right
。
通过将潜在的失败条件提取到它们自己的助手中,您可以使代码的主线完全按顺序读取,而无需使用 case 语句检查结果。
从那篇文章中,您可以看到该runEitherT
部分是如何连续工作的,它恰好具有EitherT
. 显然,这段代码是相当人为地展示了MaybeT
内部的播放方式EitherT
。在真正的代码中,它只是你想要讲述的故事,最后有一个Left
/ Right
。
import Control.Error
import Control.Monad.Trans
-- A type for my example functions to pass or fail on.
data Flag = Pass | Error
main :: IO ()
main = do
putStrLn "Starting to do work:"
result <- runEitherT $ do
lift $ putStrLn "Give me the first input please:"
initialText <- lift getLine
x <- eitherFailure Error initialText
lift $ putStrLn "Give me the second input please:"
secondText <- lift getLine
y <- eitherFailure Pass (secondText ++ x)
noteT ("Failed the Maybe: " ++ y) $ maybeFailure Pass y
case result of
Left val -> putStrLn $ "Work Result: Failed\n " ++ val
Right val -> putStrLn $ "Work Result: Passed\n " ++ val
putStrLn "Ok, finished. Have a nice day"
eitherFailure :: Monad m => Flag -> String -> EitherT String m String
eitherFailure Pass val = right $ "-> Passed " ++ val
eitherFailure Error val = left $ "-> Failed " ++ val
maybeFailure :: Monad m => Flag -> String -> MaybeT m String
maybeFailure Pass val = just $ "-> Passed maybe " ++ val
maybeFailure Error _ = nothing