I'm struggling using arrows in the HXT library to generate elements in a tree based on a list (the line with mapM below).
mkqelem (mkQName vns "depositInstruction" pacNS) []
[selem "key"
[selem "accountId" [txt $ pacuAccountId pacUpdate],
selem "instructionId" [txt $ pacuInstructionId pacUpdate]
],
selem "totalAmount" [txt $ pacuTotalAmount pacUpdate],
mapM mkInvestment [(120, 10.0)]
]
mkInvestment :: ArrowXml a => (Fund, Amount) -> a n XmlTree
mkInvestment x = selem "investments" [selem "investmentId" [txt $ show $ fst x],selem "amount" [txt $ show $ snd x]]
The program won't compile, I get the following:
• Couldn't match type ‘[]’ with ‘XN.NTree’
Expected type: a n XmlTree
Actual type: a n [XmlTree]
• In the expression: mapM mkInvestment [(120, 10.0)]
In the third argument of ‘mkqelem’, namely
‘[mkelem
"key" [] [selem "accountId" [...], selem "instructionId" [...]],
selem "totalAmount" [txt $ pacuTotalAmount pacUpdate],
mapM mkInvestment [(120, 10.0)]]’
In the expression:
mkqelem
(mkQName vns "depositInstruction" pacNS)
[]
[mkelem
"key" [] [selem "accountId" [...], selem "instructionId" [...]],
selem "totalAmount" [txt $ pacuTotalAmount pacUpdate],
mapM mkInvestment [(120, 10.0)]]
I've tried replacing mapM with variations of +=, but I don't have a good intuition on mapping in Arrows. Any pointers?
Your issue doesn't actually involve arrows; rather, it has to do with mapM
being unnecessary here. A plain fmap
over the list of tuples to make the element arrows, following by appending the result to the list with the rest of your elements, should be enough.
mkqelem (mkQName vns "depositInstruction" pacNS) [] $
[selem "key"
[selem "accountId" [txt $ pacuAccountId pacUpdate],
selem "instructionId" [txt $ pacuInstructionId pacUpdate]
],
selem "totalAmount" [txt $ pacuTotalAmount pacUpdate]
]
++ fmap mkInvestment [(120, 10.0), (121, 15.0)]
As for (+=)
, it adds children to a node, so you wouldn't use it instead of mapM
/fmap
, but rather, for instance, to define mkInvestment
in a different manner:
mkInvestment :: ArrowXml a => (Fund, Amount) -> a n XmlTree
mkInvestment x = eelem "investments"
+= (eelem "investmentId" += (txt $ show $ fst x))
+= (eelem "amount" += (txt $ show $ snd x))
-- Minor style suggestion: you might prefer to use pattern matching here
-- instead of fst and snd.