module DDC.Core.Exp.DaCon ( DaCon (..) -- * Compounds , dcUnit , takeNameOfDaCon , takeTypeOfDaCon) where import DDC.Type.Compounds import DDC.Type.Exp import Control.DeepSeq -- | Data constructors. data DaCon n -- | Baked in unit data constructor. = DaConUnit -- | Primitive data constructor used for literals and baked-in -- constructors. -- -- The type of the constructor needs to be attached to handle the -- case where there are too many constructors in the data type to list, -- like for Int literals. In this case we determine what data type -- it belongs to from the attached type of the data constructor. -- | DaConPrim { -- | Name of the data constructor. daConName :: !n -- | Type of the data constructor. , daConType :: !(Type n) } -- | Data constructor that has a data type declaration. | DaConBound { -- | Name of the data constructor. daConName :: !n } deriving (Show, Eq) instance NFData n => NFData (DaCon n) where rnf !dc = case dc of DaConUnit -> () DaConPrim n t -> rnf n `seq` rnf t DaConBound n -> rnf n -- | Take the name of data constructor, -- if there is one. takeNameOfDaCon :: DaCon n -> Maybe n takeNameOfDaCon dc = case dc of DaConUnit -> Nothing DaConPrim{} -> Just $ daConName dc DaConBound{} -> Just $ daConName dc -- | Take the type annotation of a data constructor, -- if we know it locally. takeTypeOfDaCon :: DaCon n -> Maybe (Type n) takeTypeOfDaCon dc = case dc of DaConUnit -> Just $ tUnit DaConPrim{} -> Just $ daConType dc DaConBound{} -> Nothing -- | The unit data constructor. dcUnit :: DaCon n dcUnit = DaConUnit