{-# LANGUAGE StandaloneDeriving, UndecidableInstances #-} -- | Metadata about what a datatype looks like -- -- In @generics-sop@, the metadata is completely independent of the main -- universe. Many generic functions will use this metadata, but other don't, -- and yet others might need completely different metadata. -- -- This module defines a datatype to represent standard metadata, i.e., names -- of the datatype, its constructors, and possibly its record selectors. -- Metadata descriptions are in general GADTs indexed by the code of the -- datatype they're associated with, so matching on the metadata will reveal -- information about the shape of the datatype. -- module Generics.SOP.Metadata ( module Generics.SOP.Metadata -- * re-exports , Associativity(..) ) where import Data.Kind (Type) import GHC.Generics (Associativity(..)) import Generics.SOP.Constraint import Generics.SOP.NP -- | Metadata for a datatype. -- -- A value of type @'DatatypeInfo' c@ contains the information about a datatype -- that is not contained in @'Code' c@. This information consists -- primarily of the names of the datatype, its constructors, and possibly its -- record selectors. -- -- The constructor indicates whether the datatype has been declared using @newtype@ -- or not. -- data DatatypeInfo :: [[Type]] -> Type where -- Standard algebraic datatype ADT :: ModuleName -> DatatypeName -> NP ConstructorInfo xss -> DatatypeInfo xss -- Newtype Newtype :: ModuleName -> DatatypeName -> ConstructorInfo '[x] -> DatatypeInfo '[ '[x] ] -- | The module name where a datatype is defined. -- -- @since 0.2.3.0 -- moduleName :: DatatypeInfo xss -> ModuleName moduleName (ADT name _ _) = name moduleName (Newtype name _ _) = name -- | The name of a datatype (or newtype). -- -- @since 0.2.3.0 -- datatypeName :: DatatypeInfo xss -> DatatypeName datatypeName (ADT _ name _ ) = name datatypeName (Newtype _ name _) = name -- | The constructor info for a datatype (or newtype). -- -- @since 0.2.3.0 -- constructorInfo :: DatatypeInfo xss -> NP ConstructorInfo xss constructorInfo (ADT _ _ cs) = cs constructorInfo (Newtype _ _ c) = c :* Nil deriving instance All (Show `Compose` ConstructorInfo) xs => Show (DatatypeInfo xs) deriving instance All (Eq `Compose` ConstructorInfo) xs => Eq (DatatypeInfo xs) deriving instance (All (Eq `Compose` ConstructorInfo) xs, All (Ord `Compose` ConstructorInfo) xs) => Ord (DatatypeInfo xs) -- | Metadata for a single constructors. -- -- This is indexed by the product structure of the constructor components. -- data ConstructorInfo :: [Type] -> Type where -- Normal constructor Constructor :: SListI xs => ConstructorName -> ConstructorInfo xs -- Infix constructor Infix :: ConstructorName -> Associativity -> Fixity -> ConstructorInfo '[ x, y ] -- Record constructor Record :: SListI xs => ConstructorName -> NP FieldInfo xs -> ConstructorInfo xs -- | The name of a constructor. -- -- @since 0.2.3.0 -- constructorName :: ConstructorInfo xs -> ConstructorName constructorName (Constructor name) = name constructorName (Infix name _ _) = name constructorName (Record name _) = name deriving instance All (Show `Compose` FieldInfo) xs => Show (ConstructorInfo xs) deriving instance All (Eq `Compose` FieldInfo) xs => Eq (ConstructorInfo xs) deriving instance (All (Eq `Compose` FieldInfo) xs, All (Ord `Compose` FieldInfo) xs) => Ord (ConstructorInfo xs) -- | For records, this functor maps the component to its selector name. data FieldInfo :: Type -> Type where FieldInfo :: FieldName -> FieldInfo a deriving (Show, Eq, Ord, Functor) -- | The name of a field. -- -- @since 0.2.3.0 -- fieldName :: FieldInfo a -> FieldName fieldName (FieldInfo n) = n -- | The name of a datatype. type DatatypeName = String -- | The name of a module. type ModuleName = String -- | The name of a data constructor. type ConstructorName = String -- | The name of a field / record selector. type FieldName = String -- | The fixity of an infix constructor. type Fixity = Int