我有一个复杂的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]
类型时会发生什么情况。
答案 0 :(得分:2)
当f
为Block -> [Block]
时,正如您所注意到的,walk f
将不会输入检查。但toJSONFilter f
会。要了解原因,请查看ToJSONFilter
中Text.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
的函数)正在幕后使用,而不是walk
。 bottomUp
在Text.Pandoc.Generic
中定义为
bottomUp :: (Data a, Data b) => (a -> a) -> b -> b
bottomUp f = everywhere (mkT f)
由于Block
是Data
的实例,我们可以使用bottomUp
将[Block] -> [Block]
函数提升为Pandoc -> Pandoc
。 f
为Block -> [Block]
,但concatMap f
为[Block] -> [Block]
,因此我们使用该版本。
希望能回答你的问题。请注意,由于使用syb
泛型,此方法的效果不如使用Walk
的方法。因此pandoc API还有一些改进空间。