使用以下代码
{-# LANGUAGE Arrows #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
import Text.XML.HXT.Core
parseXml :: IOSArrow XmlTree XmlTree
parseXml = getChildren >>> getChildren >>>
proc x -> do
y <- x >- hasName "item"
returnA -< x
main :: IO ()
main = do
person <- runX (readString [withValidate no]
"<xml><item>John</item><item2>Smith</item2></xml>"
>>> parseXml)
putStrLn $ show person
return ()
我得到输出
[NTree (XTag "item" []) [NTree (XText "John") []]]
所以它似乎hasName "item"
适用于x
我没想到的。使用箭头我得到parseXml
:
parseXml
= getChildren >>> getChildren >>>
(arr (\ x -> (x, x)) >>>
(first (hasName "item") >>> arr (\ (y, x) -> x)))
所以我有箭头图
y
/-- hasName "item" ---
x /
-- getChildren -- getChildren ---\x->(x,x) \(y,x)->x --- final result
\ /
\---------------------/
为什么hasName "item"
也适用于元组的第二位?我认为 haskell 中没有状态并hasName "item" x
返回一个新对象而不是更改x
.
相关问题:从箭头符号中分解箭头是否是有效的转换?
我原来的问题
我有以下代码:
{-# LANGUAGE Arrows #-}
import Text.XML.HXT.Core
data Person = Person { forname :: String, surname :: String } deriving (Show)
parseXml :: IOSArrow XmlTree Person
parseXml = proc x -> do
forname <- x >- this /> this /> hasName "fn" /> getText
surname <- x >- this /> this /> hasName "sn" /> getText
returnA -< Person forname surname
main :: IO ()
main = do
person <- runX (readString [withValidate no]
"<p><fn>John</fn><sn>Smith</sn></p>"
>>> parseXml)
putStrLn $ show person
return ()
如果我运行它一切正常,我得到输出
[Person {forname = "John", surname = "Smith"}]
但是如果我改变parseXml
以避免this
陈述
parseXml :: IOSArrow XmlTree Person
parseXml = (getChildren >>> getChildren) >>> proc x -> do
forname <- x >- hasName "fn" /> getText
surname <- x >- hasName "sn" /> getText
returnA -< Person forname surname
再也无法解析任何人(输出为[]
)。调查问题
parseXml :: IOSArrow XmlTree Person
parseXml = (getChildren >>> getChildren) >>>
proc x -> do
forname <- x >- withTraceLevel 5 traceTree >>> hasName "fn" /> getText
surname <- x >- hasName "sn" /> getText
returnA -< Person forname surname
我得到了输出
content of:
============
---XTag "fn"
|
+---XText "John"
content of:
============
---XTag "sn"
|
+---XText "Smith"
[]
所以一切看起来都很好,但是有代码
parseXml :: IOSArrow XmlTree Person
parseXml = (getChildren >>> getChildren) >>>
proc x -> do
forname <- x >- hasName "fn" /> getText
surname <- x >- withTraceLevel 5 traceTree >>> hasName "sn" /> getText
returnA -< Person forname surname
我有
content of:
============
---XTag "fn"
|
+---XText "John"
[]
所以在我看来,输入的值x
在两个语句之间发生了变化。看起来是在附加到箭头之前hasName "fn"
应用的。但是两条线之间不应该保持不变吗?x
surname
x