{-# LANGUAGE CPP #-}
#if (__GLASGOW_HASKELL__ < 709)
{-# LANGUAGE OverlappingInstances #-}
{-# OPTIONS_GHC -fno-warn-unrecognised-pragmas #-}
#endif

{- |
   The HList library

   (C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke

   Generic type equality predicate:
   The implementation based on overlapping instances
   The only place where overlapping instances are really used
   besides Label5

-}

module Data.HList.TypeEqO where

import Data.HList.FakePrelude

#if !NEW_TYPE_EQ
instance {-# OVERLAPPING #-} HEq x x True
instance {-# OVERLAPPABLE  #-} False ~ b => HEq x y b
-- instance TypeEq x y HFalse -- would violate functional dependency
#endif



class TupleType (t :: *) (b :: Bool) | t -> b
instance {-# OVERLAPPING #-} TupleType () True
instance {-# OVERLAPPING #-} TupleType (x,y) True
instance {-# OVERLAPPING #-} TupleType (x,y,z) True
-- Continue for a while
instance {-# OVERLAPPABLE #-} False ~ b => TupleType x b
-- instance TupleType x HFalse -- would violate functional dependency

-- overlaps an instance Show (Proxy t) for convenience
instance {-# OVERLAPPING #-} Show (Proxy True)  where show :: Proxy 'True -> String
show Proxy 'True
_ = String
"HTrue"
instance {-# OVERLAPPING #-} Show (Proxy False) where show :: Proxy 'False -> String
show Proxy 'False
_ = String
"HFalse"

instance {-# OVERLAPPING #-} HNat2Integral n => Show (Proxy (n :: HNat)) where
    show :: Proxy n -> String
show Proxy n
n = String
"H" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show (Proxy n -> Integer
forall (n :: HNat) i. (HNat2Integral n, Integral i) => Proxy n -> i
hNat2Integral Proxy n
n :: Integer)


instance {-# OVERLAPPABLE #-} hZero ~ HZero => ArityFwd f hZero
instance {-# OVERLAPPING #-} Arity f n => ArityFwd (x -> f) (HSucc n)


-- | All our keywords must be registered
class IsKeyFN (t :: *) (flag :: Bool) | t-> flag
-- | overlapping/fallback case
instance {-# OVERLAPPABLE #-} (False ~ flag) => IsKeyFN t flag