我对箭头很陌生,所以对我放轻松...
我正在尝试计算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
| ^^^^^^^^
谢谢!
你在这里声明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