packages feed

ddc-source-tetra-0.4.3.1: DDC/Source/Tetra/DataDef.hs

{-# LANGUAGE TypeFamilies, UndecidableInstances #-}

-- | Source Tetra data type definitions.
module DDC.Source.Tetra.DataDef
        ( -- * Data Type Definition.
          DataDef  (..)
        , envOfDataDef
          
          -- * Data Constructor Definition.
        , DataCtor (..)
        , typeOfDataCtor)
where
import DDC.Source.Tetra.Exp.Generic
import DDC.Source.Tetra.Exp.Source
import DDC.Source.Tetra.Env             (Env)
import qualified DDC.Source.Tetra.Env   as Env
import Control.DeepSeq


-- DataDef --------------------------------------------------------------------
-- | Data type definitions.
data DataDef l
        = DataDef
        { -- | Data type name.
          dataDefTypeName       :: !(GTBindCon l)

          -- | Type parameters and their kinds.
        , dataDefParams         :: [(GTBindVar l, GType l)]

          -- | Parameters and return type of each constructor.
        , dataDefCtors          :: [DataCtor l] }

deriving instance (ShowLanguage l, Show (DataCtor l))
 => Show (DataDef l)

instance NFData (DataDef n) where
 rnf !_ = ()


-- | Take the types of data constructors from a data type definition.
envOfDataDef 
        :: DataDef Source -> Env

envOfDataDef def 
        =  Env.unions
        $ [Env.singletonDaCon (dataCtorName ctor) (typeOfDataCtor def ctor)
                | ctor  <- dataDefCtors def]
              

-- DataCtor -------------------------------------------------------------------
-- | A data type constructor definition.
data DataCtor l
        = DataCtor
        { -- | Name of the data constructor.
          dataCtorName          :: !(GXBindCon l)

          -- | Types of each of the fields of the constructor.
        , dataCtorFieldTypes    :: ![GType l]

          -- | Result type of the constructor.
        , dataCtorResultType    :: !(GType l) }

deriving instance (ShowLanguage l) 
 => Show (DataCtor l)



instance NFData (DataCtor n) where
 rnf !_ = ()


-- | Get the type of a data constructor.
typeOfDataCtor :: DataDef l -> DataCtor l -> GType l
typeOfDataCtor def ctor
        = foldr (\(b, k) t -> TApp (TCon (TyConForall k)) (TAbs b k t))
                (foldr TFun (dataCtorResultType ctor)
                            (dataCtorFieldTypes ctor))
                (dataDefParams def)