haskellhakyll

How to reconcile types between `hakyll` and `hakyll-images`


I am trying to use hakyll and hakyll-images to implement an example from the hakyll-images Readme which performs an image scaling as I will need to do. The types do not unify for the given example and I am seeking advice on how to proceed.

The failing example from the hakyll-images Readme is below.

import Hakyll
import Hakyll.Images        ( loadImage
                            , scaleImageCompiler
                            )
main = hakyll $ do
    -- Scale images to fit within a 600x400 box
    -- Aspect ratio will be preserved
    match "images/*" $ do
        route idRoute
        compile $ loadImage
            >>= scaleImageCompiler 600 400

Attempting to compile gives an error:

site.hs:12:9: error:
    • No instance for (Writable
                         hakyll-images-0.3.1:Hakyll.Images.Common.Image)
        arising from a use of ‘compile’
    • In a stmt of a 'do' block:
        compile $ loadImage >>= scaleImageCompiler 600 400
      In the second argument of ‘($)’, namely
        ‘do route idRoute
            compile $ loadImage >>= scaleImageCompiler 600 400’
      In a stmt of a 'do' block:
        match "images/*"
          $ do route idRoute
               compile $ loadImage >>= scaleImageCompiler 600 400
   |
12 |         compile $ loadImage >>= scaleImageCompiler 600 400
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The error is because type Image, defined by loadImage, is required by compile to be an instance of typeclass Writable. The types of the functions used from hakyll and hakyll-images, copied from the hackage documentation, are shown below.

    route :: Routes -> Rules ()
    idRoute :: Routes
    compile :: (Binary a, Typeable a, Writable a) => Compiler (Item a) -> Rules ()
    loadImage :: Compiler (Item Image)
    scaleImageCompiler :: Width -> Height -> Item Image -> Compiler (Item Image)

Image is defined in hakyll-images as type Image = Image_ ByteString. I am not sure what Image_ is; its definition is not linked in that documentation for the Hakyll.Images module.

In any case, it appears that the example from hakyll-images's Readme does not compile due to Image not being an instance of Writable. I'm wondering if perhaps the hakyll-images package became out-of-sync with hakyll at some point leading to the example no longer compiling.

Does this assessment seem correct? What do you suggest for how might I approach a solution?

I am considering:


Solution

  • This behavior is a bug that made its way into the hakyll-images 0.3.1 release. It was fixed subsequently in hakyll-images 0.4 and above. Simply update to the latest version to get rid of this problem.

    This was a gross oversight and tests have been added such that this will not happen again.

    If you wanted to implement the instances yourself, you can take a look at how it is done here.