HXT:输入是否可以用箭头语法改变? [英] HXT: Can an input change with the arrow syntax?

查看:181
本文介绍了HXT:输入是否可以用箭头语法改变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码:

  { - #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



相关问题:从箭头中分解出一个箭头来表示一个有效的转换?



我原来的问题



我有以下代码:

  { - #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 



您可以使用

  { - #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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆