我正在尝试在Haskell中学习Arrows,所以我正在使用基于箭头的HXT库编写一个简单的应用程序。 HXT wiki和教程中的示例放弃了函数类型签名。但是,我非常喜欢类型,并试图找出如何使用它们。这是我遇到绊脚石的地方。鉴于这些功能:
readXml str = runX (readString [withValidate no] str)
atTag tag = deep (isElem >>> hasName tag)
我认为他们应该被分配以下签名:
readXml ∷ String → IO [XmlTree]
atTag ∷ ArrowXml a ⇒ String → a XmlTree XmlTree
我正在尝试使用箭头语法将它们连接在一起:
parseItem = proc str -> do
desc <- text <<< atTag "description" <<< arr readXml -< str
...
但是,如果我的类型签名是正确的(GHC没有抱怨),我需要一种方法来结合monad语法和箭头语法来获取XmlTree
并返回{{ 1}}。
我不确定如何继续。有人有任何见解吗?
答案 0 :(得分:3)
在runX
的定义中使用readXml
将“箭头转换为函数,并在parseItem的定义中使用arr
将该函数再次转换为箭头。现在,这样做会很好,除了readString
返回IOStateArrow
(IOSLA
- IO状态列表箭头的特殊类型别名),这不应该被视为一个Arrow
,但更具体地说是IOArrow
;同时,您通过使用Arrow
重新封装它将其视为纯arr
。
这里有两个选项:
readXml = readString [withValidate no]
,以便readXml :: String -> IOStateArrow s b XmlTree
。然后,您可以... <<< readXml str
中的parseItem
。arrIO
将readXml提升为IO箭头,让您按照预期的方式使用它。在这种情况下,我会使用选项1,因为如果没有特殊原因,执行此箭头包装 - 解包似乎是多余的。