我正在尝试 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]
.但是$1
在Hakyll.Compiler
monad内部,它是在Hakyll.Rules
和IO
monad内部计算的。不知何故,我需要处理IO
类型才能在库作者设置的类型签名中工作。这样做的好方法是什么?
我能想到的其他一些实现可以避免访问文件系统并生成IO
类型,但如果可能的话,我想这样做。另外,我想深入了解这一点,因为它看起来像是我在写 Haskell 时可能经常遇到的一种问题。
可能没有必要使用 IO
,通常应该避免这样做,因为它会阻止 Hakyll 跟踪依赖关系。
有一个loadAll
函数来获取与模式匹配的所有项目(在您的情况下,可能是"posts/currentpost/*.md"
,可能需要弄乱getResourceFilePath
才能构造)。然后给定所有这些Item
您可以查看它们itemIdentifier
并提取基本名称/语言(fr
,en
...)。
-- rough sketch
...
compile $ do
currentPath <- getResourceFilePath
allItems <- loadAll ... :: Compiler [Item ()] -- () ignores the contents
let idens = map itemIdentifier allItems
url = ... idens
...