Skip to content

Instantly share code, notes, and snippets.

@LSLeary
Created July 17, 2023 13:36
Show Gist options
  • Save LSLeary/5e181568bdf7a7fba72d243e15e5b632 to your computer and use it in GitHub Desktop.
Save LSLeary/5e181568bdf7a7fba72d243e15e5b632 to your computer and use it in GitHub Desktop.
A "local" quasiquoter, such that [local|<name>|] = Current.Module.<name>.
module Local (local) where
import Data.Char (isUpper)
import Data.Functor ((<&>))
import Language.Haskell.TH.Syntax
( Q, Exp(VarE, ConE), Type(ConT)
, Module(..), Name(..), OccName(..), NameFlavour(NameQ)
)
import Language.Haskell.TH.Lib (thisModule)
import Language.Haskell.TH.Quote (QuasiQuoter(..))
localName :: String -> Q Name
localName name = thisModule <&> \(Module _ modName) ->
Name (OccName name) (NameQ modName)
localVarOrCon :: String -> Q Exp
localVarOrCon name = do
l:_ <- pure name
(if isUpper l || l == ':' then ConE else VarE) <$> localName name
local :: QuasiQuoter
local = QuasiQuoter
{ quoteExp = localVarOrCon
, quotePat = error "local does not support patterns"
, quoteType = fmap ConT . localName
, quoteDec = error "local does not support declarations"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment