Consider this Haskell file:
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
module Text (main) where
import Test.Inspection
import Data.Text as T
import Data.Text.Encoding as E
import Data.ByteString (ByteString)
import Language.Haskell.TH
toUpperString :: String -> String
toUpperString = T.unpack . T.toUpper . T.pack
toUpperBytestring :: ByteString -> String
toUpperBytestring = T.unpack . T.toUpper . E.decodeUtf8
do Just n <- lookupValueName "toUpperString"
inspect $ n `hasNoType` ''T.Text
inspect $ 'toUpperBytestring `hasNoType` ''T.Text
main :: IO ()
main = return ()
It uses Template Haskell to define test obligations which are tested by the GHC plugin in inspection-testing.
Under the hood, inspection testing passes a Template Haskell name in an annotation, and converts it to to a Core name using thNameToGhcName
, and then tries to find this name in the current module.
This works fine if I create a template Haskell name using 'foo
, but it fails if I use lookupValueName
.
- Why are they different?
- How can I recreate the behavior of
'foo
when I have a string?
(Why do I not just use 'foo
? Because I want to dynamically create obligations, so I have Template Haskell code that defines many such functions and obligations.)