HXT:基于列表向树中添加元素

HXT: Adding elements to a tree based on a list

我正在努力使用 HXT 库中的箭头基于列表(下面带有 mapM 的行)在树中生成元素。

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]] 

程序无法编译,我得到以下信息:

• 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)]]

我试过用 += 的变体替换 mapM,但我对 Arrows 中的映射没有很好的直觉。有什么指点吗?

您的顶级代码清单中有一个逗号,但错误消息中 GHC 打印的代码中没有这个逗号。如果没有逗号,GHC 会尝试将 mapMmkInvestment[(120, 10.0)] 解释为 selem.

的三个参数

我没试过用逗号编译;不知道还有没有其他错误

你的问题实际上不涉及箭头;相反,它与 mapM 在这里是不必要的有关。在元组列表上简单地 fmap 来制作元素箭头,然后将结果与其余元素一起附加到列表中,就足够了。

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)]

至于 (+=),它将子节点添加到节点,因此您不会使用它来代替 mapM/fmap,而是,例如,定义 mkInvestment 以不同的方式:

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.