content: 
  -- | Predicates on type expressions.
  module DDC.Type.Exp.Simple.Predicates
          ( -- * Binders
            isBNone
          , isBAnon
          , isBName
  
            -- * Atoms
          , isTVar
          , isBot
          , isAtomT
          , isTExists
  
            -- * Kinds
          , isDataKind
          , isRegionKind
          , isEffectKind
          , isClosureKind
          , isWitnessKind
  
            -- * Data Types
          , isWitnessType
          , isConstWitType
          , isMutableWitType
          , isDistinctWitType
          , isFunishTCon
  
            -- * Effect Types
          , isReadEffect
          , isWriteEffect
          , isAllocEffect
          , isSomeReadEffect
          , isSomeWriteEffect
          , isSomeAllocEffect)
  where
  import DDC.Type.Exp
  import DDC.Type.Exp.Simple.Compounds
  import Data.Maybe
  import qualified DDC.Type.Sum   as T
  
  
  -- Binders --------------------------------------------------------------------
  isBNone :: Bind n -> Bool
  isBNone bb
   = case bb of
          BNone{} -> True
          _       -> False
  
  isBAnon :: Bind n -> Bool
  isBAnon bb
   = case bb of
          BAnon{} -> True
          _       -> False
  
  isBName :: Bind n -> Bool
  isBName bb
   = case bb of
          BName{} -> True
          _       -> False
  
  
  -- Atoms ----------------------------------------------------------------------
  -- | Check whether a type is a `TVar`
  isTVar :: Type n -> Bool
  isTVar tt
   = case tt of
          TVar{}          -> True
          _               -> False
  
  -- | Test if some type is an empty TSum
  isBot :: Type n -> Bool
  isBot tt
          | TSum ss       <- tt
          , []            <- T.toList ss
          = True
  
          | otherwise     = False
  
  
  -- | Check whether a type is a `TVar`, `TCon` or is Bottom.
  isAtomT :: Type n -> Bool
  isAtomT tt
   = case tt of
          TVar{}          -> True
          TCon{}          -> True
          _               -> isBot tt
  
  
  -- | Check whether this type is an existential variable.
  isTExists :: Type n -> Bool
  isTExists tt
   = isJust $ takeTExists tt
  
  
  -- Kinds ----------------------------------------------------------------------
  -- | Check if some kind is the data kind.
  isDataKind :: Kind n -> Bool
  isDataKind tt
   = case tt of
          TCon (TyConKind KiConData)    -> True
          _                             -> False
  
  
  -- | Check if some kind is the region kind.
  isRegionKind :: Region n -> Bool
  isRegionKind tt
   = case tt of
          TCon (TyConKind KiConRegion)  -> True
          _                             -> False
  
  
  -- | Check if some kind is the effect kind.
  isEffectKind :: Kind n -> Bool
  isEffectKind tt
   = case tt of
          TCon (TyConKind KiConEffect)  -> True
          _                             -> False
  
  
  -- | Check if some kind is the closure kind.
  isClosureKind :: Kind n -> Bool
  isClosureKind tt
   = case tt of
          TCon (TyConKind KiConClosure) -> True
          _                             -> False
  
  
  -- | Check if some kind is the witness kind.
  isWitnessKind :: Kind n -> Bool
  isWitnessKind tt
   = case tt of
          TCon (TyConKind KiConWitness) -> True
          _                             -> False
  
  
  -- Data Types -----------------------------------------------------------------
  -- | Check whether type is a witness constructor
  isWitnessType :: Eq n => Type n -> Bool
  isWitnessType tt
   = case takeTyConApps tt of
          Just (TyConWitness _, _) -> True
          _                        -> False
  
  
  -- | Check whether this is the type of a @Const@ witness.
  isConstWitType :: Eq n => Type n -> Bool
  isConstWitType tt
   = case takeTyConApps tt of
          Just (TyConWitness TwConConst, _) -> True
          _                                 -> False
  
  
  -- | Check whether this is the type of a @Mutable@ witness.
  isMutableWitType :: Eq n => Type n -> Bool
  isMutableWitType tt
   = case takeTyConApps tt of
          Just (TyConWitness TwConMutable, _) -> True
          _                                   -> False
  
  
  -- | Check whether this is the type of a @Distinct@ witness.
  isDistinctWitType :: Eq n => Type n -> Bool
  isDistinctWitType tt
   = case takeTyConApps tt of
          Just (TyConWitness (TwConDistinct _), _) -> True
          _                                        -> False
  
  
  -- | Check if this is the TyFun or KiFun constructor.
  isFunishTCon :: Type n -> Bool
  isFunishTCon tt
   = case tt of
          TCon (TyConSpec TcConFunExplicit)       -> True
          TCon (TyConKind KiConFun)               -> True
          _                                       -> False
  
  
  -- Effects --------------------------------------------------------------------
  -- | Check whether this is an atomic read effect.
  isReadEffect :: Effect n -> Bool
  isReadEffect eff
   = case eff of
          TApp (TCon (TyConSpec TcConRead)) _     -> True
          _                                       -> False
  
  
  -- | Check whether this is an atomic write effect.
  isWriteEffect :: Effect n -> Bool
  isWriteEffect eff
   = case eff of
          TApp (TCon (TyConSpec TcConWrite)) _    -> True
          _                                       -> False
  
  
  -- | Check whether this is an atomic alloc effect.
  isAllocEffect :: Effect n -> Bool
  isAllocEffect eff
   = case eff of
          TApp (TCon (TyConSpec TcConAlloc)) _    -> True
          _                                       -> False
  
  
  -- | Check whether an effect is some sort of read effect.
  --   Matches @Read@ @HeadRead@ and @DeepRead@.
  isSomeReadEffect :: Effect n -> Bool
  isSomeReadEffect tt
   = case tt of
          TApp (TCon (TyConSpec con)) _
           -> case con of
                  TcConRead       -> True
                  _               -> False
  
          _                       -> False
  
  
  -- | Check whether an effect is some sort of allocation effect.
  --   Matches @Alloc@ and @DeepAlloc@
  isSomeWriteEffect :: Effect n -> Bool
  isSomeWriteEffect tt
   = case tt of
          TApp (TCon (TyConSpec con)) _
           -> case con of
                  TcConWrite      -> True
                  _               -> False
  
          _                       -> False
  
  
  -- | Check whether an effect is some sort of allocation effect.
  --   Matches @Alloc@ and @DeepAlloc@
  isSomeAllocEffect :: Effect n -> Bool
  isSomeAllocEffect tt
   = case tt of
          TApp (TCon (TyConSpec con)) _
           -> case con of
                  TcConAlloc      -> True
                  _               -> False
  
          _                       -> False
  
  