【问题标题】:HXT: How to stop processing after the first successful transformation?HXT:第一次改造成功后如何停止处理?
【发布时间】:2012-04-22 02:44:12
【问题描述】:

我正在尝试使用 Control.Arrow.ArrowTree 构建一个 HTML 处理箭头,该箭头在给定树中的第一次成功转换(深度优先)后停止。 IE。具有类型的函数

processFirst :: (ArrowTree a, Tree t) => a (t b) (t b) -> a (t b) (t b)

例如,要将“first”类添加到 HTML 文档中的第一个列表项,可以构建箭头

processFirst (hasName "li" `guards` addAttr "class" "first")

我对 HXT 比较陌生,我已经阅读 API 文档几个小时了,并试图弄清楚如何实现 processFirst,但我无法将所有部分组合在一起. processTopDownUntil 起初听起来很有希望,但该函数仅停止对特定子树的处理,因此它仍将转换除嵌套元素之外的所有元素。

【问题讨论】:

    标签: haskell hxt


    【解决方案1】:

    我不确定我是否完全理解了这个问题,但我会尽力回答:)

    让我们尝试下一个:

    test = flip runLA undefined $ xshow $
      constA "<xml><x>X1</x><x>X2</x></xml>" >>> xread
      >>> processFirst (hasName "x" `guards` addAttr "class" "first")
    
    processFirst f = f `orElse` processChildren (processFirst f)
    

    processFirst 的定义与processTopDownUntil 的定义相同。此函数将输出如下内容:

    ["<xml><x class=\"first\">X1</x><x class=\"first\">X2</x></xml>"]
    

    问题应该很清楚——如果f 对顶部节点失败,那么processFirst 将为每个子节点调用。如果f 在某个子节点上成功,我们需要一种方法来中止对其他子节点的处理。

    可能的解决方案是使用状态箭头:

    processFirst f = fromSLA False process
      where
      process = (getState >>> isA not)
                `guards`
                (f >>> changeState (const $ const True))
                `orElse`
                processChildren process
    

    想法是在f成功时设置状态并在处理前检查它。

    注意:现在f 应该是SLA 箭头。如果这不是您想要的,您可以尝试收集所有孩子(使用例如listA)并纯粹处理它们。

    所以,这个解决方案并不理想,但我希望它可以帮助你作为一个起点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      相关资源
      最近更新 更多