我编写了以下代码来替换我从readFile
获得的错误消息:
module Main where
import Control.Error
import qualified Data.ByteString.Lazy as BSL
replaceLeftT :: Monad m => String -> EitherT String m a -> EitherT String m a
replaceLeftT message e = EitherT $ do
unwrapped <- runEitherT e
let x = case unwrapped of
Left _ -> Left message
y -> y
return x
main :: IO ()
main = runScript $ do
contents <- replaceLeftT "Could not read file" $
scriptIO $ BSL.readFile "somefile"
scriptIO $ putStrLn "Won't get here"
我觉得很笨,就像我错过了一个基本概念。可能是因为我主要通过反复试验推导出这个功能......
对于使用现有Control.Error
原语或一般monad原语的方法有任何建议吗?
答案 0 :(得分:4)
有不同的方法可以实现这一目标:
您可以首先将其丢弃(hushT
),然后添加新的错误消息(noteT
)来覆盖错误消息。
replaceLeftT :: Monad m => String -> EitherT String m a -> EitherT String m a
replaceLeftT message = noteT message . hushT
-- Same as: replaceLeftT message e = noteT message $ hushT e
使用fmapLT
另一种可能性是使用fmapLT
修改Left
中的邮件。为了实现replaceLeftT
,我们总是返回相同的新值,忽略旧的值:
replaceLeftT :: Monad m => String -> EitherT String m a -> EitherT String m a
replaceLeftT = fmapLT . const
-- Same as: replaceLeftT message e = fmapLT (const message) e