我正在尝试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
单子内部,它是在Hakyll.Rules
和IO
单子内部计算的。我需要以某种方式处理IO
类型,以在库作者设置的类型签名内工作。有什么好方法吗?
我可以想到其他一些实现,这些方法避免访问文件系统并产生IO
类型,但是我想尽可能地做到这一点。另外,我想深入探讨这个问题,因为这似乎是我在撰写Haskell时可能经常遇到的问题。
答案 0 :(得分:2)
可能不必使用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
...