    -- |
    -- Module      :  Test.ChasingBottoms.IsType
    -- Copyright   :  (c) Nils Anders Danielsson 2004-2022
    -- License     :  See the file LICENCE.
    --
    -- Maintainer  :  http://www.cse.chalmers.se/~nad/
    -- Stability   :  experimental
    -- Portability :  non-portable (GHC-specific)
    --
    -- Internal helper functions.

    module Test.ChasingBottoms.IsType
      ( isFunction
      , isTuple
      , isList
      , isString
      ) where

    import Data.List
    import Data.Typeable

    -- | '@isFunction@ f' returns 'True' iff the top level \"constructor\"
    -- of @f@ is a function arrow.
    isFunction :: Typeable a => a -> Bool
    isFunction :: forall a. Typeable a => a -> Bool
    isFunction a
    f = a -> TyCon
    forall a. Typeable a => a -> TyCon
    con a
    f TyCon -> TyCon -> Bool
    forall a. Eq a => a -> a -> Bool
    == (Bool -> Bool) -> TyCon
    forall a. Typeable a => a -> TyCon
    con Bool -> Bool
    not  -- TyCon is abstract.

    con :: Typeable a => a -> TyCon
    con :: forall a. Typeable a => a -> TyCon
    con = TypeRep -> TyCon
    typeRepTyCon (TypeRep -> TyCon) -> (a -> TypeRep) -> a -> TyCon
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> TypeRep
    forall a. Typeable a => a -> TypeRep
    typeOf

    -- | This function is rather fragile, but should be OK. It is only
    -- used by "Test.ChasingBottoms.ApproxShow", which should only be used
    -- for debugging purposes anyway. The unit type is not considered to
    -- be a tuple.
    isTuple :: Typeable a => a -> Bool
    isTuple :: forall a. Typeable a => a -> Bool
    isTuple a
    x = String
    "(," String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` TyCon -> String
    forall a. Show a => a -> String
    show (a -> TyCon
    forall a. Typeable a => a -> TyCon
    con a
    x)

    isString :: Typeable a => a -> Bool
    isString :: forall a. Typeable a => a -> Bool
    isString a
    x = a -> Bool
    forall a. Typeable a => a -> Bool
    isList a
    x Bool -> Bool -> Bool
    && TypeRep -> [TypeRep]
    typeRepArgs (a -> TypeRep
    forall a. Typeable a => a -> TypeRep
    typeOf a
    x) [TypeRep] -> [TypeRep] -> Bool
    forall a. Eq a => a -> a -> Bool
    == TypeRep -> [TypeRep]
    typeRepArgs (String -> TypeRep
    forall a. Typeable a => a -> TypeRep
    typeOf String
    "")

    isList :: Typeable a => a -> Bool
    isList :: forall a. Typeable a => a -> Bool
    isList a
    x = a -> TyCon
    forall a. Typeable a => a -> TyCon
    con a
    x TyCon -> TyCon -> Bool
    forall a. Eq a => a -> a -> Bool
    == String -> TyCon
    forall a. Typeable a => a -> TyCon
    con String
    ""