除非我遗漏了一些东西,否则似乎只有两种方法可以“遍历”Pandoc数据结构:
Block和Inline构造函数Walkabletype-class和相关的效用函数使用Walkable类型类,是否有一种有效的方法来搜索第一个匹配元素(最好以广度优先的方式),并在找到后立即停止遍历?在我看来,无论如何,围绕Walkable类型类的所有函数都将遍历整个数据结构。
如果没有,我想唯一的方法是对Block和Inline构造函数进行模式匹配并自行构建。
类型类Walkable包含一个名为的函数query类包含一个使用以下类型签名
query :: Monoid c => (a -> c) -> b -> c
Run Code Online (Sandbox Code Playgroud)
在Data.Semigroup,有一个名为 的类型First,带有一个半群实例,其中累积行为是返回“最左边的值”。
Monoid这可以与on结合使用Maybe,将 anySemigroup变成Monoid of mempty,Nothing以提供您想要的行为。
例如,将函数从Inline -> Maybe String, 调整为Pandoc -> Maybe String, 可以像这样完成:
import Text.Pandoc
import Text.Pandoc.Walk (query)
import Data.Semigroup
findUrl :: Inline -> Maybe String
findUrl (Link _ _ target) = Just $ fst target
findUrl _ = Nothing
findFirstUrl :: Pandoc -> Maybe String
findFirstUrl = (fmap getFirst) . (query findUrl')
where
findUrl' :: Inline -> Maybe (First String)
findUrl' = (fmap First) . findUrl
Run Code Online (Sandbox Code Playgroud)
关于您担心这将遍历整个数据结构:Haskell 很懒;它不应超出其需要的范围。
正如评论中所指出的,也可以通过专门针对queryList Monoid 来编写此代码:
import Text.Pandoc
import Text.Pandoc.Walk (query)
import Data.Maybe (listToMaybe)
findUrl :: Inline -> [String]
findUrl (Link _ _ target) = [fst target]
findUrl _ = []
findFirstUrl :: Pandoc -> Maybe String
findFirstUrl = listToMaybe . (query findUrl)
Run Code Online (Sandbox Code Playgroud)