我一直在尝试编写一些使用箭头的 Haskell 代码的更紧凑版本。
我正在尝试将 xml 转换为元组列表。
运行 tx2 会产生: [("项目 1","项目一",["p1_1","p1_2","p1_3"]),("项目 2","项目二",["p2_1","p2_2"])]
我的代码可以工作,但我不禁想到我不应该像我一样使用那么多的 runLA 调用。我为 getDesc、getDisp 和 getPlist 中的每一个调用 runLA。
我想我也许可以使用 proc 和 do 表示法来简化
{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
module Test1 where
import Text.XML.HXT.Arrow.ReadDocument
import Text.XML.HXT.Core
xml = "<top>\
\<list>\
\<item>\
\<desc>Item 1</desc>\
\<plist>\
\<p>p1_1</p>\
\<p>p1_2</p>\
\<p>p1_3</p>\
\</plist>\
\<display>Item One</display>\
\</item>\
\<item>\
\<desc>Item 2</desc>\
\<plist>\
\<p>p2_1</p>\
\<p>p2_2</p>\
\</plist>\
\<display>Item Two</display>\
\</item>\
\</list>\
\</top>"
tx1 = runLA (xread >>> getChildren >>> hasName "list" >>> getChildren >>> hasName "item") xml
tx2 = map toTuple tx1
toTuple i = let
desc = getDesc i
display = getDisp i
plist = getPlist i
in (desc, display, plist)
aDesc = getChildren >>> hasName "desc" >>> getChildren >>> getText >>> unlistA
aDisp = getChildren >>> hasName "display" >>> getChildren >>> getText >>> unlistA
aPlist = getChildren >>> hasName "plist" >>> getChildren >>> deep getText
getDesc i = runLA aDesc i
getDisp i = runLA aDisp i
getPlist i = runLA aPlist i
但是当我尝试按如下方式重写 tx2 时:
aToTuple = proc tree -> do
desc <- aDesc -< tree
display <- aDisp -< tree
plist <- aPlist -< tree
returnA -< (desc, display, plist)
tx3 = map (\i -> runLA aToTuple i) tx1
一切都落入一大堆。
转换为 proc/do 表示法时我缺少什么?
谢谢。
最佳答案
您几乎不需要在 HXT 上多次调用 run
函数
箭头以获得您想要的结果。在你的情况下,listA
可以用来代替
map runLA
以从箭头获取结果列表。你也可以摆脱
许多 getChildren
调用都使用 />
运算符。
你的proc
版本的toTuple
对我来说看起来不错,但我会重写其余的
您的示例代码为
tx1 = runLA (xread /> hasName "list" /> hasName "item" >>> toTuple) xml
toTuple = proc tree -> do
desc <- aDesc -< tree
disp <- aDisp -< tree
plist <- aPlist -< tree
returnA -< (desc, disp, plist)
aDesc = getChildren >>> hasName "desc" /> getText
aDisp = getChildren >>> hasName "display" /> getText
aPlist = getChildren >>> hasName "plist" >>> listA (getChildren /> getText)
并且不使用箭头表示法,toTuple
可以简单地写为
toTuple = aDesc &&& aDisp &&& aPlist >>> arr3 (,,)
关于尝试使用 proc 和 do 表示法时,haskell 箭头出现混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17951915/