I have a really simple use-case where I have a basic type but for the purposes of my various record types in my data model, I want each record to have wrapped version of this type:
type UID = Integer
-- specialised version
newtype MyRecordID = MyRecordID UID
-- constructor which can take any integral type because I get
-- Int32 from the database and it's a lot of annoying
-- boilerplate each time
myRecordID :: Integral a => a -> MyRecordID
myRecordID = MyRecordID . fromInteger
There are a few records like this, and instead of writing these constructors by hand each time I thought this might be an ideal way to use TH.
From this answer I managed to make the newtype
declaration (although it really bothers me that there is a lot I don't understand in this):
wrapUID :: String -> Q [Dec]
wrapUID n = (:[]) <$> dataD (cxt [])
name
[]
Nothing
[normalC name
[bangType (bang noSourceUnpackedness noSourceStrictness)
[t| UID |]]]
[]
where name = mkName n
I don't know how to go about then creating the "constructor" declaration.