我正在尝试使用异常来跳过部分代码。不会被catcheE
抓住并恢复正常行为,而是会跳过mapM_
链中的所有后续操作。
我查看了this question,看来catchE
〜main
和checkMaybe
〜intercept
。
我还检查了mapM_
的实现,以确保它符合我的要求,但我不明白Left值如何逃脱dlAsset
以影响mapM_
的行为。
我从一个版本重构了这个版本,我只是使用一个空字符串作为失败查找的异常标记。在该版本中,checkMaybe
只是立即返回Right
值并且有效(在""
上匹配'捕获')
import Data.HashMap.Strict as HM hiding (map)
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Char8 as BSC8
import qualified JSONParser as P -- my module
retrieveAssets :: (Text -> Text) -> ExceptT Text IO ()
retrieveAssets withName = withManager $ (lift ((HM.keys . P.assets)
<$> P.raw) ) >>= mapM_ f
where
f = \x -> dlAsset x "0.1246" (withName x)
dlAsset :: Text -> Text -> Text -> ReaderT Manager (ExceptT Text IO) ()
dlAsset name size dest = do
req <- lift $ (P.assetLookup name size <$> P.raw) >>= checkMaybe
name >>= parseUrl . unpack -- lookup of a url
res <- httpLbs req
lift $ (liftIO $ BS.writeFile (unpack dest) $ responseBody res)
`catchE` (\_ -> return ()) -- always a Right value?
where
checkMaybe name a = case a of
Nothing -> ExceptT $ fmap Left $ do
BSC8.appendFile "./resources/images/missingFiles.txt" $
BSC8.pack $ (unpack name) ++ "\n"
putStrLn $ "lookup of " ++ (unpack name) ++ " failed"
return name
Just x -> lift $ pure x
(必须重新格式化,以便在这里变得有些可读)
编辑:我想了解这里实际发生了什么,这可能对我有所帮助,而不仅仅是知道哪部分代码是错误的。
答案 0 :(得分:1)
问题是,您对catchE
的来电仅涵盖dlAsset
的最后一行。它需要移动到do-notation缩进级别的左侧以覆盖所有的符号。