I am trying to learn Arrows in Haskell, so I am writing a simple application with the arrow based HXT library for XML. The examples in the HXT wikis and tutorials forgo function type signatures. However, I am quite fond of types and am trying to work out how to use them. This is where I have met a stumbling block. Given these functions:
readXml str = runX (readString [withValidate no] str)
atTag tag = deep (isElem >>> hasName tag)
I figure they should be assigned the following signatures:
readXml ∷ String → IO [XmlTree]
atTag ∷ ArrowXml a ⇒ String → a XmlTree XmlTree
I am trying to hook these together using arrow syntax as such:
parseItem = proc str -> do
desc <- text <<< atTag "description" <<< arr readXml -< str
...
However, if my my type-signatures are correct (GHC hasn’t complained), I would need a way in which to combine monad syntax and arrow syntax to get the XmlTree out of and returned to IO.
I am unsure how to proceed. Anyone have any insights?
Using
runXin the definition ofreadXml“converts” an arrow into a function, and usingarrin the definition of parseItem converts that function back into an arrow again. Now, doing it like this would be fine, except thatreadStringreturns anIOStateArrow(a special type alias for theIOSLA– IO State List Arrow), which should be treated not only as anArrow, but more specifically as anIOArrow; meanwhile, you are treating it as a pureArrowby rewrapping it usingarr.You have two options here:
readXml = readString [withValidate no], so thatreadXml :: String -> IOStateArrow s b XmlTree. Then you can just do... <<< readXml strinparseItem.arrIOto lift readXml into an IO arrow, which lets you use it the way you intended.I would use option 1 in this case, since it seems superfluous to do this arrow-wrapping-unwrapping if there’s no special reason for it.