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



我正在尝试 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 monad内部,它是在Hakyll.RulesIO monad内部计算的。不知何故,我需要处理IO类型才能在库作者设置的类型签名中工作。这样做的好方法是什么?

我能想到的其他一些实现可以避免访问文件系统并生成IO类型,但如果可能的话,我想这样做。另外,我想深入了解这一点,因为它看起来像是我在写 Haskell 时可能经常遇到的一种问题。

可能没有必要使用 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
    ...

最新更新