是否将箭头分解为箭头表示有效的转换? [英] Is factoring an arrow out of arrow do notation a valid transformation?
问题描述
我正试图绕过HXT,一个用于解析使用箭头的XML的Haskell库。对于我的具体使用情况,我宁愿不使用 deep
,因为存在< outer_tag>< payload_tag>值< / payload_tag><< ; / outer_tag>
不同于< outer_tag>< inner_tag>< payload_tag>值< / payload_tag>< / inner_tag>< / outer_tag>
但我碰到了一些奇怪的东西,觉得它应该可以工作,但没有。
我设法提出了一个基于< 这个例子来自文档:
{ - #LANGUAGE箭头,NoMonomorphismRestriction# - }
模块Main其中
导入Text.XML。 HXT.Core
data Guest = Guest {firstName,lastName :: String}
deriving(Show,Eq)
getGuest = deep(isElem >> hasNameguest)>>>
proc x - >做
fname< - getText<<<< getChildren<<<深(hasNamefname) - < x
lname< - getText<<<< getChildren<<<深(hasNamelname) - < x
returnA - < {firstName = fname,lastName = lname}
getGuest'= deep(isElem>>> hasNameguest)>>>
proc x - >做
fname< - getText<<<< getChildren<<< (hasNamefname)<<< getChildren - < x
lname< - getText<<<< getChildren<<< (hasNamelname)<<< getChildren - < x
returnA - <访客{firstName = fname,lastName = lname}
getGuest''=深(isElem>>> hasNameguest)>>> getChildren>>>
proc x - >做
fname< - getText<<<< getChildren<<< (hasNamefname) - < x
lname< - getText<<<< getChildren<<< (hasNamelname) - < x
returnA - <来宾{firstName = fname,lastName = lname}
驱动程序finalArrow = runX(readDocument [withValidate no]guestbook.xml>>>> finalArrow)
main = do
guests < - driver getGuest
printgetGuest
print guests
guests'< - driver getGuest'
打印getGuest
打印客人
客人''< - driver getGuest''
打印getGuest'
打印客人''
在 getGuest
和 getGuest之间'
我将深
展开为正确数量的 getChildren
。由此产生的功能仍然有效。然后我将 getChildren
放在 do
块之外,但这会导致函数失败。输出是:
pre $ getGuest
[Guest {firstName =John,lastName =Steinbeck}} ,客人{firstName =Henry,lastName =Ford},客人{firstName =Andrew,lastName =Carnegie},客人{firstName =Anton,lastName =Chekhov}, George,lastName =Washington},Guest {firstName =William,lastName =Shakespeare},Guest {firstName =Nathaniel,lastName =Hawthorne}]
getGuest'
[Guest {firstName =John,lastName =Steinbeck},Guest {firstName =Henry,lastName =Ford},Guest {firstName =Andrew,lastName =Carnegie}, {firstName =Anton,lastName =Chekhov},Guest {firstName =George,lastName =Washington},Guest {firstName =William,lastName =Shakespeare},Guest {firstName =Nathaniel ,lastName =Hawthorne}]
getGuest'
[]
我觉得这应该是一个有效的转变,但我对箭的理解有点不稳定。难道我做错了什么?这是我应该报告的错误吗?
我使用HXT版本9.3.1.3(写作时是最新版本)。 ghc --version打印The Glorious Glasgow Haskell Compilation System,version 7.4.1。我也用ghc 7.6.3在一个盒子上进行了测试,得到了相同的结果。
XML文件具有以下重复结构(完整文件可以在< a href =http://www.haskell.org/haskellwiki/HXT/Practical/Simple1 =nofollowtitle =简单1例子>在这里)
<留言簿>
< guest>
< fname> John< / fname>
< lname> Steinbeck< / lname>
< / guest>
< guest>
< fname>亨利< / fname>
< lname>福特< / lname>
< / guest>
< guest>
< fname> Andrew< / fname>
< lname>卡内基< / lname>
< / guest>
< /留言簿>
...(hasNamefname) - < x
...(hasNamelname) - < x
也就是说,您仅限于 x
fname
和 x
是 lname
,这不被任何 x
!
满足
I'm trying to get my head around HXT, a Haskell library for parsing XML that uses arrows. For my specific use case I'd rather not use deep
as there are cases where <outer_tag><payload_tag>value</payload_tag></outer_tag>
is distinct from <outer_tag><inner_tag><payload_tag>value</payload_tag></inner_tag></outer_tag>
but I ran into some weirdness that felt like it should work but doesn't.
I've managed to come up with a test case based on this example from the docs:
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
module Main where
import Text.XML.HXT.Core
data Guest = Guest { firstName, lastName :: String }
deriving (Show, Eq)
getGuest = deep (isElem >>> hasName "guest") >>>
proc x -> do
fname <- getText <<< getChildren <<< deep (hasName "fname") -< x
lname <- getText <<< getChildren <<< deep (hasName "lname") -< x
returnA -< Guest { firstName = fname, lastName = lname }
getGuest' = deep (isElem >>> hasName "guest") >>>
proc x -> do
fname <- getText <<< getChildren <<< (hasName "fname") <<< getChildren -< x
lname <- getText <<< getChildren <<< (hasName "lname") <<< getChildren -< x
returnA -< Guest { firstName = fname, lastName = lname }
getGuest'' = deep (isElem >>> hasName "guest") >>> getChildren >>>
proc x -> do
fname <- getText <<< getChildren <<< (hasName "fname") -< x
lname <- getText <<< getChildren <<< (hasName "lname") -< x
returnA -< Guest { firstName = fname, lastName = lname }
driver finalArrow = runX (readDocument [withValidate no] "guestbook.xml" >>> finalArrow)
main = do
guests <- driver getGuest
print "getGuest"
print guests
guests' <- driver getGuest'
print "getGuest'"
print guests'
guests'' <- driver getGuest''
print "getGuest''"
print guests''
Between getGuest
and getGuest'
I expand deep
into the correct number of getChildren
. The resulting function still works. I then factor the getChildren
outside of the do
block but this causes the resulting function to fail. The output is:
"getGuest"
[Guest {firstName = "John", lastName = "Steinbeck"},Guest {firstName = "Henry", lastName = "Ford"},Guest {firstName = "Andrew", lastName = "Carnegie"},Guest {firstName = "Anton", lastName = "Chekhov"},Guest {firstName = "George", lastName = "Washington"},Guest {firstName = "William", lastName = "Shakespeare"},Guest {firstName = "Nathaniel", lastName = "Hawthorne"}]
"getGuest'"
[Guest {firstName = "John", lastName = "Steinbeck"},Guest {firstName = "Henry", lastName = "Ford"},Guest {firstName = "Andrew", lastName = "Carnegie"},Guest {firstName = "Anton", lastName = "Chekhov"},Guest {firstName = "George", lastName = "Washington"},Guest {firstName = "William", lastName = "Shakespeare"},Guest {firstName = "Nathaniel", lastName = "Hawthorne"}]
"getGuest''"
[]
I feel like this should be a valid transformation to perform, but my understanding of arrows is a little shaky. Am I doing something wrong? Is this a bug that I should report?
I'm using HXT version 9.3.1.3 (the latest at the time of writing). ghc --version prints "The Glorious Glasgow Haskell Compilation System, version 7.4.1". I've also tested on a box with ghc 7.6.3 and got the same result.
The XML file had the following repetitive structure (the full file can be found here)
<guestbook>
<guest>
<fname>John</fname>
<lname>Steinbeck</lname>
</guest>
<guest>
<fname>Henry</fname>
<lname>Ford</lname>
</guest>
<guest>
<fname>Andrew</fname>
<lname>Carnegie</lname>
</guest>
</guestbook>
In getGuest''
you have
... (hasName "fname") -< x
... (hasName "lname") -< x
That is, you are restricting to the case where x
is "fname"
and x
is "lname"
, which isn't satisfied by any x
!
这篇关于是否将箭头分解为箭头表示有效的转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!