{-# LANGUAGE CPP #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeOperators #-}
#if __GLASGOW_HASKELL__ >= 810
{-# LANGUAGE StandaloneKindSignatures #-}
#endif
module Data.EqP (
EqP (..),
) where
import Control.Applicative (Const (..))
import Data.Kind (Type)
import Data.Proxy (Proxy (..))
import Data.Type.Equality ((:~:) (..), (:~~:) (..))
import GHC.Generics ((:*:) (..), (:+:) (..))
import System.Mem.StableName (StableName, eqStableName)
#if MIN_VERSION_base(4,18,0)
import Data.Functor.Product (Product (..))
import Data.Functor.Sum (Sum (..))
import qualified GHC.TypeLits as TL
import qualified GHC.TypeNats as TN
#endif
#if !MIN_VERSION_base(4,19,0)
import Data.Orphans ()
#endif
import qualified Type.Reflection as TR
#if __GLASGOW_HASKELL__ >= 810
import Data.Kind (Constraint)
#endif
#if __GLASGOW_HASKELL__ >= 810
type EqP :: (k -> Type) -> Constraint
#endif
class (forall a. Eq (f a)) => EqP (f :: k -> Type) where
eqp :: f a -> f b -> Bool
instance EqP ((:~:) a) where
eqp :: forall (a :: k) (b :: k). (a :~: a) -> (a :~: b) -> Bool
eqp a :~: a
_ a :~: b
_ = Bool
True
instance EqP ((:~~:) a) where
eqp :: forall (a :: k) (b :: k). (a :~~: a) -> (a :~~: b) -> Bool
eqp a :~~: a
_ a :~~: b
_ = Bool
True
#if MIN_VERSION_base(4,18,0)
instance (EqP a, EqP b) => EqP (Sum a b) where
eqp (InL x) (InL y) = eqp x y
eqp (InR x) (InR y) = eqp x y
eqp _ _ = False
instance (EqP a, EqP b) => EqP (Product a b) where
eqp (Pair x y) (Pair x' y') = eqp x x' && eqp y y'
#endif
instance (EqP f, EqP g) => EqP (f :+: g) where
eqp :: forall (a :: k) (b :: k). (:+:) f g a -> (:+:) f g b -> Bool
eqp (L1 f a
x) (L1 f b
y) = forall k (f :: k -> *) (a :: k) (b :: k).
EqP f =>
f a -> f b -> Bool
eqp f a
x f b
y
eqp (R1 g a
x) (R1 g b
y) = forall k (f :: k -> *) (a :: k) (b :: k).
EqP f =>
f a -> f b -> Bool
eqp g a
x g b
y
eqp (:+:) f g a
_ (:+:) f g b
_ = Bool
False
instance (EqP a, EqP b) => EqP (a :*: b) where
eqp :: forall (a :: k) (b :: k). (:*:) a b a -> (:*:) a b b -> Bool
eqp (a a
x :*: b a
y) (a b
x' :*: b b
y') = forall k (f :: k -> *) (a :: k) (b :: k).
EqP f =>
f a -> f b -> Bool
eqp a a
x a b
x' Bool -> Bool -> Bool
&& forall k (f :: k -> *) (a :: k) (b :: k).
EqP f =>
f a -> f b -> Bool
eqp b a
y b b
y'
instance EqP TR.TypeRep where
eqp :: forall (a :: k) (b :: k). TypeRep a -> TypeRep b -> Bool
eqp TypeRep a
x TypeRep b
y = forall k (a :: k). TypeRep a -> SomeTypeRep
TR.SomeTypeRep TypeRep a
x forall a. Eq a => a -> a -> Bool
== forall k (a :: k). TypeRep a -> SomeTypeRep
TR.SomeTypeRep TypeRep b
y
#if MIN_VERSION_base(4,18,0)
instance EqP TL.SChar where
eqp x y = TL.fromSChar x == TL.fromSChar y
instance EqP TL.SSymbol where
eqp x y = TL.fromSSymbol x == TL.fromSSymbol y
instance EqP TN.SNat where
eqp x y = TN.fromSNat x == TN.fromSNat y
#endif
instance EqP Proxy where
eqp :: forall (a :: k) (b :: k). Proxy a -> Proxy b -> Bool
eqp Proxy a
_ Proxy b
_ = Bool
True
instance Eq a => EqP (Const a) where
eqp :: forall (a :: k) (b :: k). Const a a -> Const a b -> Bool
eqp (Const a
x) (Const a
y) = a
x forall a. Eq a => a -> a -> Bool
== a
y
instance EqP StableName where
eqp :: forall a b. StableName a -> StableName b -> Bool
eqp = forall a b. StableName a -> StableName b -> Bool
eqStableName