HXT:输入是否可以用箭头语法改变? [英] HXT: Can an input change with the arrow syntax?
问题描述
使用以下代码:
{ - #LANGUAGE箭头# - }
{ - #LANGUAGE NoMonomorphismRestriction# - }
import Text.XML.HXT.Core
parseXml :: IOSArrow XmlTree XmlTree
parseXml = getChildren>>> getChildren>>>
proc x - > do
y< -x> - hasNameitem
returnA - < x
main :: IO()
main = do
person< - runX(readString [withValidate no]
< xml>< item> John< / item>< item2> Smith< / item2>< / xml>
>>> parseXml)
putStrLn $ show person
return()
我得到输出
<$ creec(NTTree)(XTagitem[])[NTree(XTextJohn)[]]]
因此,似乎 hasNameitem
被应用于 x
这是我没有想到的。使用 arrowp 我得到 parseXml
:
parseXml
= getChildren> ;>> getChildren>>>
(first(hasNameitem)>>>>>< \(y, x) - > x)))
所以我有箭头图
y
/ - hasNameitem---
x /
- getChildren - getChildren - -x->(x,x)\(y,x) - > x ---最终结果
\ /
\ --------- ------------ /
为什么 hasNameitem
也适用于元组的第二位?我认为haskell中没有状态,并且 hasNameitemx
返回一个新对象,而不是改变 x $ c $的内部状态c>。
我原来的问题
我有以下代码:
{ - #LANGUAGE Arrows# - }
import Text.XML.HXT.Core
data Person = Person {forname :: String,surname :: String}派生(显示)
parseXml :: IOSArrow XmlTree Person
parseXml = proc x - >做
forname< - x> - this />这个/> hasNamefn/> getText
surname< - x> - this />这个/> hasNamesn/> getText
returnA - <人名
$ b $ 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
以避免这个
语句
parseXml :: IOSArrow XmlTree Person
parseXml =(getChildren>>> getChildren)>>> proc x - > do
forname< -x> - hasNamefn/> getText
姓氏< -x> - hasNamesn/> getText
returnA - <人名
无人可以解析(输出为 []
)。用
parseXml :: IOSArrow XmlTree Person
parseXml =(getChildren>>> getChildren)调查问题>>>
proc x - > do
forname< -x> - withTraceLevel 5 traceTree>>> hasNamefn/> getText
姓氏< -x> - hasNamesn/> getText
returnA - <人名姓
我得到了输出
内容:
============
--- XTagfn
|
+ --- XTextJohn
的内容:
============
--- XTagsn
|
+ --- XTextSmith
[]
所以一切似乎都很好,但是使用代码
parseXml :: IOSArrow XmlTree Person
parseXml = (getChildren>>> getChildren)>>>
proc x - > do
forname< -x> - hasNamefn/> getText
姓氏< -x> - withTraceLevel 5 traceTree>>> hasNamesn/> getText
returnA - <人名姓
我得到了
内容:
============
--- XTagfn
|
+ --- XTextJohn
[]
因此,在我看来,输入 x
的值在两个语句之间变化。它看起来像 hasNamefn
在被附加到之前被应用于
箭头。但是 x
姓氏 x
在两行之间不会保持一致吗?
你在行中编程的内容
proc x - > do
y< -x> - hasNameitem
returnA - < x
只是一个删除所有未命名为项目
。
他相当于箭头
hasNameitem`guards` this
$ c
您可以使用
{ - #LANGUAGE箭头# - }
{ - #LANGUAGE NoMonomorphismRestriction# - }
模块Main其中
import Text.XML.HXT.Core
parseXml0 :: IOSArrow XmlTree XmlTree
parseXml0 = getChildren>>> getChildren>>>
proc x - > do
_< - hasNameitem - < x
returnA - < x
parseXml1 :: IOSArrow XmlTree XmlTree
parseXml1 = getChildren>>> getChildren>>>
(hasNameitem`guards` this)
main1 ::显示c => IOSArrow XmlTree c - > IO()
main1 parseXml = do
person< - runX(readString [withValidate no]
< xml>< item> John< / item>< item2> Smith< / item2>< / xml>
>>>> parseXml)
putStrLn $ show person
return()
$ b main :: IO()
main = main1 parseXml0>> main1 parseXml1
With the following code
{-# 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 ()
I get the output
[NTree (XTag "item" []) [NTree (XText "John") []]]
So it seems that hasName "item"
was applied to x
which I did not expect. Using arrowp I get for parseXml
:
parseXml
= getChildren >>> getChildren >>>
(arr (\ x -> (x, x)) >>>
(first (hasName "item") >>> arr (\ (y, x) -> x)))
So I have the arrow diagram
y
/-- hasName "item" ---
x /
-- getChildren -- getChildren ---\x->(x,x) \(y,x)->x --- final result
\ /
\---------------------/
Why is hasName "item"
also applied to second place of the tuple? I thought there is no state in haskell and hasName "item" x
returns a new object instead of changing the internal state of x
.
Related question: Is factoring an arrow out of arrow do notation a valid transformation?
My original problem
I have the following code:
{-# 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 ()
If I run it everything works fine and I get the output
[Person {forname = "John", surname = "Smith"}]
But if I change the parseXml
to avoid the this
statements
parseXml :: IOSArrow XmlTree Person
parseXml = (getChildren >>> getChildren) >>> proc x -> do
forname <- x >- hasName "fn" /> getText
surname <- x >- hasName "sn" /> getText
returnA -< Person forname surname
no person can be parsed anymore (output is []
). Investigating the problem with
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
I got the output
content of:
============
---XTag "fn"
|
+---XText "John"
content of:
============
---XTag "sn"
|
+---XText "Smith"
[]
So everything seems fine, but with the code
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
I got
content of:
============
---XTag "fn"
|
+---XText "John"
[]
So it seems to me, that the value of the input x
changes between the two statements. It looks like the hasName "fn"
was applied to x
before it was attached to the surname
arrow. But shall x
not remain the same between the two lines?
解决方案 No, the input can't change and it doesn't.
What you've programmed in the lines
proc x -> do
y <- x >- hasName "item"
returnA -< x
is just a filter removing all nodes not named item
.
His is equivalent to the arrow
hasName "item" `guards` this
You can test this with
{-# LANGUAGE Arrows #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module Main where
import Text.XML.HXT.Core
parseXml0 :: IOSArrow XmlTree XmlTree
parseXml0 = getChildren >>> getChildren >>>
proc x -> do
_ <- hasName "item" -< x
returnA -< x
parseXml1 :: IOSArrow XmlTree XmlTree
parseXml1 = getChildren >>> getChildren >>>
(hasName "item" `guards` this)
main1 :: Show c => IOSArrow XmlTree c -> IO ()
main1 parseXml = do
person <- runX (readString [withValidate no]
"<xml><item>John</item><item2>Smith</item2></xml>"
>>> parseXml)
putStrLn $ show person
return ()
main :: IO ()
main = main1 parseXml0 >> main1 parseXml1
这篇关于HXT:输入是否可以用箭头语法改变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!