Haskell error references code that is not in the code?

Viewed 117

I'm trying to follow the Persistent tutorial, which has this code:

{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeFamilies               #-}
import Database.Persist
import Database.Persist.TH
import Database.Persist.Sqlite
import Control.Monad.IO.Class (liftIO)

mkPersist sqlSettings [persistLowerCase|
Person
    name String
    age Int
    deriving Show
|]

But when I try to run it, I get:

src/model.hs:31:1: error:
    • Illegal instance declaration for ‘ToBackendKey SqlBackend Post’
        (Only one type can be given in an instance head.
         Use MultiParamTypeClasses if you want to allow more, or zero.)
    • In the instance declaration for ‘ToBackendKey SqlBackend Post’

And those declarations (ToBackendKey etc) are not in my code, and not at line 31. What's going on? I have a feeling it's related to TemplateHaskell, but I don't know enough about it to figure this out. How can I debug this?

1 Answers

When GHC asks you to add an extension, it's usually a good idea to do so.

The trick here is that the [name|...|] notation is for quasi quotation, which uses Template Haskell to generate code at compile time, much like macros in other languages. So the error is not in your code, but in your code's code!

It's errors like this that make Template Haskell hard to debug, which is why the community is fairly split on its use.

Related