Raising an abstract data type

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.

+4

Source: https://habr.com/ru/post/1548578/


All Articles