Suppose there is a convenient library for parsing things. It exports a function parseThingalong with some types and helpers:
module Text.Thing.Parser
( Thing ()
, parseThing
, ParseError
-- ...
) where
-- ...
data Thing = {- implementation -}
parseThing :: String -> Either ParseError Thing
parseThing = {- implementation -}
I decided to write a wrapper library that allows me to analyze things at compile time.
{-# LANGUAGE TemplateHaskell #-}
module Text.Thing.Parser.TH where
import Text.Thing.Parser
import Language.Haskell.TH
import Language.Haskell.TH.Quote
thingExpr :: String -> Q Exp
thingExpr src = do
case parseThing src of
Left err -> fail $ show err
Right thing -> [| thing |]
thing :: QuasiQuoter
thing = QuasiQuoter { quoteExp = thingExpr
, quoteDec = undefined
, quotePat = undefined
, quoteType = undefined
}
A compilation error with an error No instance (Lift Thing), but I cannot add an instance declaration because it Thingis an abstract data type that I do not have access to: it is defined elsewhere, and no constructors are exported. And since I'm new to Template Haskell, I can't come up with a solution other than canceling a local variable (if any).
So how do I determine thingExpr? Thank.