是否将箭头分解为箭头表示有效的转换? [英] Is factoring an arrow out of arrow do notation a valid transformation?

查看:202
本文介绍了是否将箭头分解为箭头表示有效的转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图绕过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>
< /留言簿>


解决方案

getGuest'<您有

  ...(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屋!

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