I'm trying out Hakyll and having trouble fitting in IO type into Hakyll compilation process. Here's an example Hakyll code from tutorial.
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
I want to look at the list of localized files (en.md, fr.md, ...) in matched directories and produce a list of available languages, which I will use to generate urls for redirecting to translations. I think this logic will have to be placed around $1.
It's file operation so it produces IO [FilePath]. But $1 is inside Hakyll.Compiler monad, which is computed inside Hakyll.Rules and IO monads. Somehow I need to deal with IO type to work within the type signatures set by the library author. What is a good way to do this?
There are a few other implementations I can think of that avoid accessing file system and producing IO type, but I want to do it this way if possible. Plus, I want to get down to the bottom of this as it looks like a kind of issue that I may face commonly while writing Haskell.
It might not be necessary to use
IO, and that should generally be avoided because it prevents Hakyll from tracking dependencies.There is a
loadAllfunction to get all items matching a pattern (in your case, possibly"posts/currentpost/*.md", that might need messing withgetResourceFilePathto construct). Then given all thoseItemyou can look at theiritemIdentifierand extract the basenames/languages (fr,en...).