{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Clash.Core.TyCon
( TyCon (..)
, TyConName
, TyConMap
, AlgTyConRhs (..)
, mkKindTyCon
, isTupleTyConLike
, isNewTypeTc
, tyConDataCons
)
where
import Control.DeepSeq
import Data.Binary (Binary)
import qualified Data.Text as T
import GHC.Generics
import Clash.Core.DataCon (DataCon)
import Clash.Core.Name
import {-# SOURCE #-} Clash.Core.Type (Kind, Type)
import Clash.Core.Var (TyVar)
import Clash.Unique
import Clash.Util
data TyCon
= AlgTyCon
{ tyConUniq :: {-# UNPACK #-} !Unique
, tyConName :: !TyConName
, tyConKind :: !Kind
, tyConArity :: !Int
, algTcRhs :: !AlgTyConRhs
, isClassTc :: !Bool
}
| FunTyCon
{ tyConUniq :: {-# UNPACK #-} !Unique
, tyConName :: !TyConName
, tyConKind :: !Kind
, tyConArity :: !Int
, tyConSubst :: [([Type],Type)]
}
| PrimTyCon
{ tyConUniq :: {-# UNPACK #-} !Unique
, tyConName :: !TyConName
, tyConKind :: !Kind
, tyConArity :: !Int
}
| SuperKindTyCon
{ tyConUniq :: {-# UNPACK #-} !Unique
, tyConName :: !TyConName
}
deriving (Generic,NFData,Binary)
instance Show TyCon where
show (AlgTyCon {tyConName = n}) = "AlgTyCon: " ++ show n
show (FunTyCon {tyConName = n}) = "FunTyCon: " ++ show n
show (PrimTyCon {tyConName = n}) = "PrimTyCon: " ++ show n
show (SuperKindTyCon {tyConName = n}) = "SuperKindTyCon: " ++ show n
instance Eq TyCon where
(==) = (==) `on` tyConUniq
(/=) = (/=) `on` tyConUniq
instance Uniquable TyCon where
getUnique = tyConUniq
setUnique tyCon u = tyCon {tyConUniq=u}
type TyConName = Name TyCon
type TyConMap = UniqMap TyCon
data AlgTyConRhs
= DataTyCon
{ dataCons :: [DataCon]
}
| NewTyCon
{ dataCon :: !DataCon
, ntEtadRhs :: ([TyVar],Type)
}
deriving (Show,Generic,NFData,Binary)
mkKindTyCon :: TyConName
-> Kind
-> TyCon
mkKindTyCon name kind
= PrimTyCon (nameUniq name) name kind 0
isTupleTyConLike :: TyConName -> Bool
isTupleTyConLike nm = tupleName (nameOcc nm)
where
tupleName nm'
| '(' <- T.head nm'
, ')' <- T.last nm'
= T.all (== ',') (T.init $ T.tail nm')
tupleName _ = False
tyConDataCons :: TyCon -> [DataCon]
tyConDataCons (AlgTyCon {algTcRhs = DataTyCon { dataCons = cons}}) = cons
tyConDataCons (AlgTyCon {algTcRhs = NewTyCon { dataCon = con }}) = [con]
tyConDataCons _ = []
isNewTypeTc
:: TyCon
-> Bool
isNewTypeTc (AlgTyCon {algTcRhs = NewTyCon {}}) = True
isNewTypeTc _ = False