module SafeWildCards (fields, fieldsPrefixed, fieldsNamed) where
import Language.Haskell.TH (Name, PatQ, mkName, conP, varP, nameBase, recover)
import Language.Haskell.TH.Datatype
fields :: Name -> PatQ
fields :: Name -> PatQ
fields = (String -> String) -> Name -> PatQ
fieldsNamed String -> String
forall a. a -> a
id
fieldsPrefixed :: String -> Name -> PatQ
fieldsPrefixed :: String -> Name -> PatQ
fieldsPrefixed String
prefix = (String -> String) -> Name -> PatQ
fieldsNamed (String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++)
fieldsNamed :: (String -> String) -> Name -> PatQ
fieldsNamed :: (String -> String) -> Name -> PatQ
fieldsNamed String -> String
f Name
recordConstructor = do
ConstructorInfo
cons <-
Q ConstructorInfo -> Q ConstructorInfo -> Q ConstructorInfo
forall a. Q a -> Q a -> Q a
recover
(String -> Q ConstructorInfo
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q ConstructorInfo) -> String -> Q ConstructorInfo
forall a b. (a -> b) -> a -> b
$
String
"Could not find " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
nameBase Name
recordConstructor String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
". If it is defined in the same module where you are using\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" 'safe-wild-cards', you need to break the declaration group like this:\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" data ... = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
nameBase Name
recordConstructor String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ...\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" $(pure [])\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" Read the 'SafeWildCards' module documentation for more details.\n"
)
(Name -> Q ConstructorInfo
reifyConstructor Name
recordConstructor)
case ConstructorInfo -> ConstructorVariant
constructorVariant ConstructorInfo
cons of
RecordConstructor [Name]
recordFields ->
Name -> [PatQ] -> PatQ
conP Name
recordConstructor ((Name -> PatQ) -> [Name] -> [PatQ]
forall a b. (a -> b) -> [a] -> [b]
map (Name -> PatQ
varP (Name -> PatQ) -> (Name -> Name) -> Name -> PatQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
mkName (String -> Name) -> (Name -> String) -> Name -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
f (String -> String) -> (Name -> String) -> Name -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> String
nameBase) [Name]
recordFields)
ConstructorVariant
_ -> String -> PatQ
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> PatQ) -> String -> PatQ
forall a b. (a -> b) -> a -> b
$
String
"Expected " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
forall a. Show a => a -> String
show Name
recordConstructor String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" to be a record constructor"