module DDC.Core.Exp.DaCon ( DaCon (..) , DaConName (..) -- * Compounds , dcUnit , mkDaConAlg , mkDaConSolid , takeNameOfDaCon , typeOfDaCon) where import DDC.Type.Compounds import DDC.Type.Exp import Control.DeepSeq ------------------------------------------------------------------------------- -- | Data constructor names. data DaConName n -- | The unit data constructor is builtin. = DaConUnit -- | Data constructor name defined by the client. | DaConNamed n deriving (Eq, Show) instance NFData n => NFData (DaConName n) where rnf dcn = case dcn of DaConUnit -> () DaConNamed n -> rnf n ------------------------------------------------------------------------------- -- | Data constructors. data DaCon n = DaCon { -- | Name of the data constructor. daConName :: !(DaConName n) -- | Type of the data constructor. -- The type must be closed. , daConType :: !(Type n) -- | Algebraic constructors can be deconstructed with case-expressions, -- and must have a data type declaration. -- -- Non-algebraic types like 'Float' can't be inspected with -- case-expressions. , daConIsAlgebraic :: !Bool } deriving (Show, Eq) instance NFData n => NFData (DaCon n) where rnf !dc = rnf (daConName dc) `seq` rnf (daConType dc) `seq` rnf (daConIsAlgebraic dc) -- | Take the name of data constructor. takeNameOfDaCon :: DaCon n -> Maybe n takeNameOfDaCon dc = case daConName dc of DaConUnit -> Nothing DaConNamed n -> Just n -- | Take the type annotation of a data constructor. typeOfDaCon :: DaCon n -> Type n typeOfDaCon dc = daConType dc -- | The unit data constructor. dcUnit :: DaCon n dcUnit = DaCon { daConName = DaConUnit , daConType = tUnit , daConIsAlgebraic = True } -- | Make an algebraic data constructor. mkDaConAlg :: n -> Type n -> DaCon n mkDaConAlg n t = DaCon { daConName = DaConNamed n , daConType = t , daConIsAlgebraic = True } -- | Make a non-algebraic (solid) constructor. -- These are used for location values in the interpreter, -- and for floating point literals in the main compiler. mkDaConSolid :: n -> Type n -> DaCon n mkDaConSolid n t = DaCon { daConName = DaConNamed n , daConType = t , daConIsAlgebraic = False }