Skip to content

Template Haskell declaration splice causes subsequent declarations to fall out of scope

When using Template Haskell to splice in instance declarations, it is possible to cause identifiers following it to fall out of scope:

-- DeriveJSON.hs
{-# LANGUAGE TemplateHaskell #-}
module DeriveJSON where

import Data.Aeson.TH

data ADT = ADT

instance Show ADT
    where show = adtFun

$(deriveJSON defaultOptions ''ADT)

adtFun :: ADT -> String
adtFun = undefined

ghc DeriveJSON.hs gives the following error:

[1 of 1] Compiling DeriveJSON       ( DeriveJSON.hs, DeriveJSON.o )

DeriveJSON.hs:10:18: Not in scope: ‘adtFun’

Since deriveJSON simply returns a Q [Dec], I don't see why this code shouldn't compile as is.

I can find two workarounds at the moment:

  • Move the instance Show ADT declaration after the $(deriveJSON defaultOptions ''ADT) line.
  • Move the $(deriveJSON defaultOptions ''ADT) line after the adtFun function declaration.
Trac metadata
Trac field Value
Version 7.8.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Template Haskell
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information