g2-0.2.0.0: src/G2/Language/AlgDataTy.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module G2.Language.AlgDataTy ( AlgDataTy (..)
, dataCon
, dataConWithName) where
import GHC.Generics (Generic)
import Data.Data (Data, Typeable)
import Data.Hashable
import Data.List
import G2.Language.Syntax
-- | Algebraic data types are types constructed with parametrization of some
-- names over types, and a list of data constructors for said type.
data AlgDataTy =
-- | A type defined using the `data` keyword.
DataTyCon { bound_ids :: [Id] -- ^ Polymorphic type variables
, data_cons :: [DataCon] -- ^ Data constructors for the type
}
-- | A type defined using the `newtype` keyword.
| NewTyCon { bound_ids :: [Id] -- ^ Polymorphic type variables
, data_con :: DataCon -- ^ The data constructor for the newtype
, rep_type :: Type -- ^ The type being wrapped by the newtype
}
-- | A type defined using the `type` keyword.
| TypeSynonym { bound_ids :: [Id] -- ^ Polymorphic type variables
, synonym_of :: Type -- ^ What type is the type synonym equivalent to?
} deriving (Show, Eq, Read, Generic, Typeable, Data)
-- | Get the data constructors for the passed data type.
--
-- Warning: Does not "dig in" to type synonyms- a type synonym
-- will just give back an empty list.
dataCon :: AlgDataTy -> [DataCon]
dataCon (DataTyCon {data_cons = dc}) = dc
dataCon (NewTyCon {data_con = dc}) = [dc]
dataCon (TypeSynonym {}) = []
dataConWithName :: AlgDataTy -> Name -> Maybe DataCon
dataConWithName (DataTyCon _ dcs) n = find (`dataConHasName` n) dcs
dataConWithName _ _ = Nothing
dataConHasName :: DataCon -> Name -> Bool
dataConHasName (DataCon n _) n' = n == n'
instance Hashable AlgDataTy