{-# LANGUAGE TemplateHaskellQuotes #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
{-# HLINT ignore "Redundant <&>" #-}
module Data.Effect.HFunctor.TH where
import Data.Effect.HFunctor.TH.Internal (deriveHFunctor)
import Data.Effect.TH.Internal (analyzeData)
import Data.Functor ((<&>))
import Data.List.Infinite (Infinite)
import Language.Haskell.TH (Dec, Name, Q, reify)
import Language.Haskell.TH qualified as TH
import Language.Haskell.TH.Syntax (nameBase)
makeHFunctor :: Name -> Q [Dec]
makeHFunctor :: Name -> Q [Dec]
makeHFunctor Name
name = Name -> (Infinite (Q Type) -> Q Type) -> Q [Dec]
makeHFunctor' Name
name (forall a b. a -> b -> a
const [t|()|])
makeHFunctor' :: Name -> (Infinite (Q TH.Type) -> Q TH.Type) -> Q [Dec]
makeHFunctor' :: Name -> (Infinite (Q Type) -> Q Type) -> Q [Dec]
makeHFunctor' Name
name Infinite (Q Type) -> Q Type
manualCxt = do
Name -> Q Info
reify Name
name forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Info -> Maybe DataInfo
analyzeData forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just DataInfo
dat -> do
(Infinite (Q Type) -> Q Type) -> DataInfo -> Q [Dec]
deriveHFunctor Infinite (Q Type) -> Q Type
manualCxt DataInfo
dat
Maybe DataInfo
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"The specified name is not that of a data type: " forall a. [a] -> [a] -> [a]
++ Name -> String
nameBase Name
name