Search code examples
xmlhaskellhxt

HXT: reuse "preparsed" data


I am trying to 'preparse' XML with HXT into [XmlTree] once and then reuse this data several times.

Below is my code:

{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
import Text.XML.HXT.Core

parseXML = readDocument [ withValidate no
                        , withRemoveWS yes  -- throw away formating WS
                        ] 

atTag tag = deep (isElem >>> hasName tag)


data UiWindow = UiWindow {
    wndName :: String,
    wndNameLib :: String,
    wndChildren :: [UiWindow]
    } deriving (Show)

initUiWindow = UiWindow {
    wndName = "empty",
    wndNameLib = "",
    wndChildren = []
    }


parseDoc docName = runX $ parseXML fileName >>> getWindow
  where
    fileName = docName ++ ".xml"


getWindow = atTag "Window" >>> proc x -> do
    libraryItemName <- getAttrValue "libraryItemName" -< x
    name <- getAttrValue "name" -< x
    children <- arrIO parseDoc -< libraryItemName
    returnA -< initUiWindow { wndName = name, wndNameLib = libraryItemName, wndChildren = children}


documentName = "DOMDocument.xml"        

parseRoot = parseXML documentName

--runX (parseRoot >>> getWindow )

If I parse beforehand:

λ: x <- runX parseRoot

λ: :t x
x :: [XmlTree]
λ: :t getWindow
getWindow :: IOSLA (XIOState ()) XmlTree UiWindow

How do I run something like this:

runX $ XYZ(x) >>> getWindow

or this:

runX $ XYZ(x) >>> getSomethingElse

Allowing me to reuse data in 'x'.


Solution

  • After reading more about arrows I found this:

    λ: :t constA
    constA :: ArrowList a => c -> a b c
    

    Now using constA on an element of type XmlTree we get an arrow that we can reuse:

    main = do
      x <- runX parseRoot
      windows <- runX $ constA (head x) >>> getWindow
      doors <- runX $ constA (head x) >>> getDoor
    

    I have to use head x as x will be of type [XmlTree] but the second arrow expects XmlTree.