Pandoc过滤器中允许的函数类型

时间:2014-11-19 22:34:15

标签: haskell pandoc

我有一个复杂的html文档,我已经阅读了pandoc,我正在尝试编写过滤器来隔离我所追求的内容。这方面的一些例子是完全丢弃某些Div,或者只用行的内容替换Table。

told on the pandoc mailing list表示实例Walkable a b => Walkable a [b]的存在意味着你也可以编写Block -> [Block]类型的函数,并且重新省略元素[]。这有效,但我不明白为什么,这是我的问题:

我理解它的方式,the signature of walk(将函数转换为过滤器)(a -> a) -> b -> b,意味着使用类型Block -> [Block]的函数将无法编译,因为它不适合签名的(a -> a)位。同样在我的理解中,instance Walkable a b => Walkable a [b]的存在只描述了walk在面对列表而不是单个元素来应用f :: a -> a时的行为方式。我不知道当f是a -> [a]类型时会发生什么情况。

1 个答案:

答案 0 :(得分:2)

fBlock -> [Block]时,正如您所注意到的,walk f将不会输入检查。但toJSONFilter f会。要了解原因,请查看ToJSONFilterText.Pandoc.JSON的来源。它包含实例:

instance Data a => ToJSONFilter (a -> [a]) where
  toJSONFilter f = BL.getContents >>=
    BL.putStr . encode . (bottomUp (concatMap f) :: Pandoc -> Pandoc) .
    either error id . eitherDecode'

因此,我们可以将toJSONFilter应用于Block -> [Block]函数。

它是如何工作的?正如您所看到的,bottomUp(包含来自syb的函数)正在幕后使用,而不是walkbottomUpText.Pandoc.Generic中定义为

bottomUp :: (Data a, Data b) => (a -> a) -> b -> b
bottomUp f = everywhere (mkT f)

由于BlockData的实例,我们可以使用bottomUp[Block] -> [Block]函数提升为Pandoc -> PandocfBlock -> [Block],但concatMap f[Block] -> [Block],因此我们使用该版本。

希望能回答你的问题。请注意,由于使用syb泛型,此方法的效果不如使用Walk的方法。因此pandoc API还有一些改进空间。