2
votes

I'm trying to get my head wrapped around Persistent, and one of the things I'm trying to learn is it's derivePersistField template haskell function. Now, I realize there's a stage restriction, forcing GHC to render the rest of the code that the quasiquoter is supposed to generate, but mine just isn't getting it done. GHC keeps complaining that the function call is in the top-level, yet I don't know else to generate the actual datatypes + good bits. Here is my code (taken directly from the Yesod book on Persistent):

--Employment.hs----

module Employment where

import Database.Persist.TH

data Employment = Employed | Unemployed | Retired
    deriving (Show, Read, Eq)
derivePersistField "Employment"

--main.hs----------

{-# LANGUAGE QuasiQuotes, TypeFamilies, GeneralizedNewtypeDeriving, TemplateHaskell,
             OverloadedStrings, GADTs, FlexibleContexts #-}
import Database.Persist.Sqlite
import Database.Persist.TH
import Employment

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    employment Employment
|]

main = runSqlite ":memory:" $ do
    runMigration migrateAll

    insert $ Person "Bruce Wayne" Retired
    insert $ Person "Peter Parker" Unemployed
    insert $ Person "Michael" Employed

What else am I missing? Do I need to place the language extensions in the module as well? Any help would be greatly appreciated!

1
You need to put your top-level function calls in a TH expression: $( derivePersistField "Employment" ). Or maybe $( derivePersistField ''Employment ) (the double tick quotes a type) Same for the share call, I think.luqui

1 Answers

2
votes

The derivePersistField is a Template Haskell splice like share so in order to use it in a module you need to enable the TemplateHaskell language pragma. I.e.

{-# LANGUAGE TemplateHaskell #-}

module Employment where

import Database.Persist.TH

data Employment = Employed | Unemployed | Retired
    deriving (Show, Read, Eq)
derivePersistField "Employment"

You can also enable the extension for the whole project by putting

extensions: TemplateHaskell

in your project's .cabal-file but the recommended way is to enable the extensions you need on a per module basis.