您可以使用catchA
箭头来处理管道内的异常。在这种情况下parseThing
,需要具有更具体的 IO 感知类型,例如IOSArrow
.
要跳过异常,catchA
给定none
箭头作为异常处理程序。
这是一个完整的示例(为了更好的可读性,我从中提取)parseThing_aux
:parseThing
{-# LANGUAGE Arrows #-}
import Control.Arrow.ArrowExc (catchA)
import Text.XML.HXT.Core
data Thing = Thing String [(String,String)] deriving Show
main :: IO ()
main = do
xml <- getContents
res <- runX $ readString [] xml >>> parseThing
mapM_ print res
parseThing :: IOSArrow XmlTree Thing
parseThing
= deep (hasName "table") &&& deep (hasName "h3")
>>> catchA parseThing_aux none
parseThing_aux :: IOSArrow (XmlTree, XmlTree) Thing
parseThing_aux = proc (table, h3) -> do
name <- getText <<< getChildren -< h3
info <- listA parseTable -< table
returnA -< mkThing name info
parseTable :: ArrowXml a => a XmlTree (String, String)
parseTable = error "Not implemented"
mkThing :: String -> [(String,String)] -> Thing
mkThing n i = Thing n i
旁注1
如果您想压缩表格和标题而不是制作它们的交叉产品,您可以更改parseThing
为
parseThing
= (listA $ deep $ hasName "table") &&& (listA $ deep $ hasName "h3")
>>> arr2 zip >>> unlistA
>>> catchA parseThing_aux none
旁注2
parseThing_aux
用无点风格写会更简洁一点
parseThing_aux
= (getChildren >>> getText) *** listA parseTable
>>^ uncurry mkThing
(你可以uncurry
通过改变mkThing
采取一对消除。)