Haskell HXT拆分XML数据

时间:2018-08-22 10:42:13

标签: haskell arrows hxt

我对箭还很陌生,所以请放轻松...

我正在尝试计算XML文件中特定节点的数量。布置XML文件的位置,以便在根目录下有一个场景列表,在每个场景下都有一个图层列表,每个图层都有一个称为“ recs”的节点。我想计算每个场景中的直肠数量。我不完全了解HXT的工作原理。

我将复制导致问题的代码摘录

process :: IOSArrow XmlTree [XmlTree]
process getScene >>. map func
    where func a = a >>> getLayer >>> getRec

每个get函数的类型均为IOSArrow XmlTree XmlTree

为什么这行不通?以及我该如何解决?

错误消息:

count_dirty.hs:20:16: error:
    • Couldn't match type ‘Data.Tree.NTree.TypeDefs.NTree XNode’
                     with ‘IOSLA (XIOState ()) a0 XmlTree’
      Expected type: [XmlTree] -> [IOSLA (XIOState ()) a0 XmlTree]
        Actual type: [IOSLA (XIOState ()) a0 XmlTree]
                     -> [IOSLA (XIOState ()) a0 XmlTree]
    • In the second argument of ‘(>>.)’, namely ‘map func’
      In the second argument of ‘(>>>)’, namely ‘getScene >>. map func’
      In the expression:
        readDocument [withValidate no] file >>> getScene >>. map func
   |
20 |   getScene >>. map func
   |                ^^^^^^^^

谢谢!

1 个答案:

答案 0 :(得分:1)

您在这里声明func是一个辅助函数,该函数需要一些a,然后计算a >>> getLayer >>> getRec

getRec :: IOSArrow XmlTree XmlTree
(>>>)  :: (Category cat) => cat a b -> cat b c -> cat a c

GHC可以推断出a >>> getRec意味着cat ~ IOSArrow, b ~ XmlTree, c ~ XmlTree,而变量a的类型尚未定IOSArrow a XmlTree,等等。

func :: a -> IOSArrow XmlTree XmlTree

map :: (x -> y) -> [x] -> [y]

map func :: [a] -> [IOSArrow XmlTree XmlTree]

因为

(>>.) :: a b c -> ([c] -> [d]) -> a b d 

getScene >>. :: ([XmlTree] -> [d]) -> IOSArrow XmlTree d

现在GHC非常确定a ~ XmlTree, d ~ IOSArrow XmlTree XmlTree给予了

getScene >>. map func 
  :: IOSArrow 
       XmlTree 
       (IOSArrow XmlTree XmlTree)

问题出在您的map func->>.希望将纯函数作为第二个参数。在您的情况下,func是产生箭头的函数,该箭头不纯。

我想您可能想使用applyA,它可以让您从输入中生成箭头,然后应用该箭头,这正是您在这里所做的。在这种情况下,您要写

process = applyA (getScene >>. map func)
    ...

请注意,您正在使用列表箭头,因此类型签名应该是

process :: IOSArrow XmlTree XmlTree