module NewtypeDeriving.Reification where
import BasePrelude
import Language.Haskell.TH
data Newtype =
Newtype {
newtypeTypeName :: Name,
newtypeConstructorName :: Name,
newtypeInnerType :: Type
}
deriving (Show)
reifyNewtype :: Name -> Q (Either String Newtype)
reifyNewtype =
fmap parseInfo . reify
where
parseInfo =
\case
TyConI (NewtypeD _ typeName _ con derivations) -> do
(conName, innerType) <-
case con of
NormalC n [(_, t)] -> Right (n, t)
RecC n [(_, _, t)] -> Right (n, t)
_ -> Left $ "Invalid constructor: " <> show con
return $ Newtype typeName conName innerType
i ->
Left $ "Invalid type of a name"
peelTransformer :: Type -> Maybe (Type, Type)
peelTransformer =
\case
AppT t m -> Just (t, m)
_ -> Nothing