2013-07-30 29 views
2

我一直在嘗試編寫使用箭頭的一些Haskell代碼的更緊湊版本。haskell箭頭混淆試圖使用proc和表示法

我想將xml轉換爲元組列表。

運行tx2產生: [(「Item 1」,「Item One」,[「p1_1」,「p1_2」,「p1_3」]),(「Item 2」,「Item Two」,[「p2_1 「,」p2_2「])]

我有工作的代碼,但我忍不住想我不應該使用盡可能多的runLA調用。我爲getDesc,getDispgetPlist中的每一個呼叫runLA。

我想我可能能夠使用PROC符號簡化

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

謝謝。

+0

你在使用'-XArrows'嗎? –

+0

@AndrewJaffe:代碼示例頂部有一個附註。 – Vitus

回答

2

你幾乎不需要在HXT 箭頭上多次調用run功能來獲得你想要的結果。在你的情況下,listA可以用來代替 map runLA從箭頭中獲得結果列表。您還可以通過使用/>運算符來擺脫 許多getChildren調用。

proctoTuple -version看起來好像沒什麼問題,但我已經重寫的 你的示例代碼,其餘爲

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 (,,) 
+0

非常感謝,這正是我想要的,現在明白它在做什麼。再次感謝 – Chime