hakyll
hakyll copied to clipboard
Possible type consistencies between loadAll and Contexts should be detected by the type system
Suppose I use the following (buggy) code snippet.
match "images/*" $ do
route idRoute
compile copyFileCompiler
create ["images.html"] $ do
route idRoute
compile $ do
photos <- loadAll "images/*"
let imageCtx :: Context String
imageCtx = urlField "url"
<> pathField "path"
<> missingField
photosCtx :: Context String
photosCtx = constField "title" "images"
<> listField "photos" imageCtx (loadAll "images/*")
<> missingField
<> defaultContext
This code will happily compile but will produce an error at runtime, such as:
[ERROR] Hakyll.Core.Compiler.Require.load: images/IMG_6139.JPG (snapshot _final) was found in the cache, but does not have the right type: expected [Char] but got CopyFile
The fix consists in declaring imageCtx
as Context CopyFile
.
The reason seems to be that loadAll
can only items that have already been compiled by a match
rule (e.g. here). My understanding is that in the buggy example above, the images have been compiled by copyFileCompiler
of type Compile (Item CopyFile)
. Hence loadAll "images/*"
need to be typed as Compiler [Item CopyFile]
, and imageCtx
is Context CopyFile
.
This subtlety is not explicited by the type properties of Hakyll, nor by the documentation. I don't know what can be done to help hakyll users, but I wanted to share this because it took me a lot of time to understand what was happening here.
And.... thanks for this great library!!
That's a good point to add to the docs #904. In the beginning i tripped over that as well.