使用外部库时如何适合IO类型

时间:2018-12-31 11:49:08

标签: haskell hakyll

我正在尝试Hakyll,并且无法将IO类型适配到Hakyll编译过程中。这是教程中的Hakyll代码示例。

main :: IO ()
main = hakyll $ do
    match "posts/*" $ do
        route $ setExtension "html"
        compile $ do
            let url = -- $1
                ctx = stringField "title" url `mappend` defaultCtx
                in
                pandocCompiler
                >>= loadAndApplyTemplate "templates/default.html" ctx
                >>= relativizeUrls

我想查看匹配目录中的本地化文件列表(en.md,fr.md,...),并生成可用语言的列表,我将使用这些列表来生成用于重定向到翻译的url。我认为这种逻辑必须放在$1周围。

这是文件操作,因此会产生IO [FilePath]。但是$1Hakyll.Compiler单子内部,它是在Hakyll.RulesIO单子内部计算的。我需要以某种方式处理IO类型,以在库作者设置的类型签名内工作。有什么好方法吗?

我可以想到其他一些实现,这些方法避免访问文件系统并产生IO类型,但是我想尽可能地做到这一点。另外,我想深入探讨这个问题,因为这似乎是我在撰写Haskell时可能经常遇到的问题。

1 个答案:

答案 0 :(得分:2)

可能不必使用IO,通常应避免使用它,因为这会阻止Hakyll跟踪依赖关系。

有一个loadAll函数来获取所有与模式匹配的项目(在您的情况下,可能是"posts/currentpost/*.md",可能需要与getResourceFilePath一起构造)。然后给定所有这些Item,您可以查看它们的itemIdentifier并提取基本名称/语言(fren ...)。

-- rough sketch

...
  compile $ do
    currentPath <- getResourceFilePath
    allItems <- loadAll ... :: Compiler [Item ()]  -- () ignores the contents
    let idens = map itemIdentifier allItems
        url = ... idens
    ...
相关问题