0

I have a data type like this:

module My.Module

data A = A { aFoo :: Integer } deriving (Generic, Show)

And I have generic option for Aeson

import Data.Char ( toUpper, toLower )

genericOptions :: String -> Options
genericOptions prefix = defaultOptions
  { fieldLabelModifier = dropPrefix $ length prefix
  , constructorTagModifier = addPrefix prefix
  , omitNothingFields = True
  }
  where
    dropPrefix l s = let remainder = drop l s
                     in  (toLower . head) remainder : tail remainder
    addPrefix p s  = p ++ toUpper (head s) : tail s

So I can use it like this

instance A.FromJSON A where 
  parseJSON = A.genericParseJSON $ genericOptions "A"

instance A.ToJSON A where 
  toJSON = A.genericToJSON $ genericOptions "A"

But I realize I could use some template haskell

import Data.Aeson.TH ( deriveJSON )
import Language.Haskell.TH.Syntax ( Dec, Name, Q )

genericDeriveJSON :: Name -> Q [Dec]
genericDeriveJSON name =
  deriveJSON (genericOptions (show name)) name 

$(genericDeriveJSON ''A)

It throws an error:

Exception when trying to run 
compile-time code:
      Prelude.tail: empty list
    Code: A.genericDeriveJSON ''A

It seems drop l s on dropPrefix returned an empty string meaning the value of show name is not string "A". Since I don't think I could inspect the value, anybody knows what is the value?

autumn322
  • 447
  • 3
  • 10

1 Answers1

0

Try to use nameBase instead of show (which is meant for debugging and not core logic).

To see what show is doing you can look at the implementation of show which is defined as showName which is itself defined as showName' Alone, to see roughly that it constructs the fully qualified name of your type.

Li-yao Xia
  • 31,896
  • 2
  • 33
  • 56