很难给这个问题一个好的标题……我又被 HXT 困住了。我明白我想要做什么,但我不知道如何让它与箭头很好地配合。在这里,我对问题进行了简单的描述。
函数foo
接受一个Int
并返回一个箭头:
foo :: ArrowXml a => Int -> a XmlTree XmlTree
函数bar
提取某些属性的值:
bar :: ArrowXml a => a XmlTree String
现在,我需要编写一个从s 到sbaz
的映射并返回一个箭头:String
Int
import qualified Data.Map.Lazy as M
baz :: ArrowXml a => M.Map String Int -> a XmlTree XmlTree
逻辑baz
:提取属性值bar
并在地图中查找。如果M.lookup
返回Just x
,调用foo x
,否则不执行任何操作(箭头的输入不变)。
AFAIK 每个这样的箭头都用作过滤器,因此实际上ArrowXml a => a
XmlTree String
类型意味着它需要一个XmlTree
并返回(可能为空的)String
s 列表。这让我重新制定baz
. 对于给定的输入XmlTree
,可能有很多字符串,每个字符串都应该用于查找一个整数,并且首先找到的整数应该传递给foo
. 如果所有这些都导致Nothing
,请不要做任何事情。
这是我想出的:
baz :: ArrowXml a => M.Map String Int -> a XmlTree XmlTree
baz m = this &&& (bar >>> arr (`M.lookup` m)) >>> arr (uncurry f)
where f xml Nothing = xml
f xml (Just x) = foo x xml
-- compiler says: ^^^ not so fast, boy
Could not deduce (ArrowXml (->)) arising from a use of ‘foo’
from the context (ArrowXml a)
bound by the type signature for
baz :: ArrowXml a => M.Map String Int -> a XmlTree XmlTree
不仅编译器不喜欢它,而且也很难推理。