{-# LANGUAGE CPP, NoImplicitPrelude #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,19,0))
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
#endif
module Data.Typeable.Compat (
  module Base
#if MIN_VERSION_base(4,10,0)
, heqT
, decT
, hdecT
#endif
) where

import Data.Typeable as Base

#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,19,0))
import Prelude.Compat

import Data.Void (Void)
import qualified Type.Reflection.Compat as TR
#endif

#if MIN_VERSION_base(4,10,0)
# if !(MIN_VERSION_base(4,18,0))
-- | Extract a witness of heterogeneous equality of two types
--
-- /Since: 4.18.0.0/
heqT :: forall a b. (Typeable a, Typeable b) => Maybe (a :~~: b)
heqT = ta `TR.eqTypeRep` tb
  where
    ta = TR.typeRep :: TR.TypeRep a
    tb = TR.typeRep :: TR.TypeRep b
# endif

# if !(MIN_VERSION_base(4,19,0))
-- | Decide an equality of two types
--
-- /Since: 4.19.0.0/
decT :: forall a b. (Typeable a, Typeable b) => Either (a :~: b -> Void) (a :~: b)
decT :: forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Either ((a :~: b) -> Void) (a :~: b)
decT = case forall (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Either ((a :~~: b) -> Void) (a :~~: b)
forall {k1} {k2} (a :: k1) (b :: k2).
(Typeable a, Typeable b) =>
Either ((a :~~: b) -> Void) (a :~~: b)
hdecT @a @b of
  Right a :~~: b
HRefl -> (a :~: b) -> Either ((a :~: b) -> Void) (a :~: b)
forall a b. b -> Either a b
Right a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
  Left (a :~~: b) -> Void
p      -> ((a :~: b) -> Void) -> Either ((a :~: b) -> Void) (a :~: b)
forall a b. a -> Either a b
Left (\a :~: b
Refl -> (a :~~: b) -> Void
p a :~~: a
a :~~: b
forall {k1} (a :: k1). a :~~: a
HRefl)

-- | Decide heterogeneous equality of two types.
--
-- /Since: 4.19.0.0/
hdecT :: forall a b. (Typeable a, Typeable b) => Either (a :~~: b -> Void) (a :~~: b)
hdecT :: forall {k1} {k2} (a :: k1) (b :: k2).
(Typeable a, Typeable b) =>
Either ((a :~~: b) -> Void) (a :~~: b)
hdecT = TypeRep a
ta TypeRep a -> TypeRep b -> Either ((a :~~: b) -> Void) (a :~~: b)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Either ((a :~~: b) -> Void) (a :~~: b)
`TR.decTypeRep` TypeRep b
tb
  where
    ta :: TypeRep a
ta = TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
TR.typeRep :: TR.TypeRep a
    tb :: TypeRep b
tb = TypeRep b
forall {k} (a :: k). Typeable a => TypeRep a
TR.typeRep :: TR.TypeRep b
# endif
#endif