{-# LANGUAGE TypeOperators, DataKinds, PolyKinds, TypeFamilies,
RankNTypes, FlexibleContexts, TemplateHaskell,
UndecidableInstances, GADTs, DefaultSignatures,
ScopedTypeVariables, TypeApplications, StandaloneKindSignatures #-}
module Data.Singletons.Prelude.Eq (
PEq(..), SEq(..),
DefaultEq,
type (==@#@$), type (==@#@$$), type (==@#@$$$),
type (/=@#@$), type (/=@#@$$), type (/=@#@$$$),
DefaultEqSym0, DefaultEqSym1, DefaultEqSym2
) where
import Data.Kind
import Data.Singletons.Internal
import Data.Singletons.Prelude.Bool
import Data.Singletons.Single
import Data.Singletons.Prelude.Instances
import Data.Singletons.Util
import Data.Singletons.Promote
import qualified Data.Type.Equality as DTE ()
type PEq :: Type -> Constraint
class PEq a where
type (==) (x :: a) (y :: a) :: Bool
type (/=) (x :: a) (y :: a) :: Bool
type (x :: a) == (y :: a) = x `DefaultEq` y
type (x :: a) /= (y :: a) = Not (x == y)
infix 4 ==
infix 4 /=
type DefaultEq :: k -> k -> Bool
type family DefaultEq a b where
DefaultEq a a = 'True
DefaultEq a b = 'False
$(genDefunSymbols [''(==), ''(/=), ''DefaultEq])
type SEq :: Type -> Constraint
class SEq k where
(%==) :: forall (a :: k) (b :: k). Sing a -> Sing b -> Sing (a == b)
infix 4 %==
(%/=) :: forall (a :: k) (b :: k). Sing a -> Sing b -> Sing (a /= b)
default (%/=) :: forall (a :: k) (b :: k).
((a /= b) ~ Not (a == b))
=> Sing a -> Sing b -> Sing (a /= b)
Sing a
a %/= Sing b
b = Sing (a == b) -> Sing (Not (a == b))
forall (a :: Bool). Sing a -> Sing (Not a)
sNot (Sing a
a Sing a -> Sing b -> Sing (a == b)
forall k (a :: k) (b :: k).
SEq k =>
Sing a -> Sing b -> Sing (a == b)
%== Sing b
b)
infix 4 %/=
$(singEqInstances basicTypes)
instance SEq a => SingI ((==@#@$) :: a ~> a ~> Bool) where
sing :: Sing (==@#@$)
sing = SingFunction2 (==@#@$) -> Sing (==@#@$)
forall a1 a2 b (f :: a1 ~> (a2 ~> b)). SingFunction2 f -> Sing f
singFun2 SingFunction2 (==@#@$)
forall k (a :: k) (b :: k).
SEq k =>
Sing a -> Sing b -> Sing (a == b)
(%==)
instance (SEq a, SingI x) => SingI ((==@#@$$) x :: a ~> Bool) where
sing :: Sing ((==@#@$$) x)
sing = SingFunction1 ((==@#@$$) x) -> Sing ((==@#@$$) x)
forall a1 b (f :: a1 ~> b). SingFunction1 f -> Sing f
singFun1 (SingI x => Sing x
forall k (a :: k). SingI a => Sing a
sing @x Sing x -> Sing t -> Sing (x == t)
forall k (a :: k) (b :: k).
SEq k =>
Sing a -> Sing b -> Sing (a == b)
%==)
instance SEq a => SingI ((/=@#@$) :: a ~> a ~> Bool) where
sing :: Sing (/=@#@$)
sing = SingFunction2 (/=@#@$) -> Sing (/=@#@$)
forall a1 a2 b (f :: a1 ~> (a2 ~> b)). SingFunction2 f -> Sing f
singFun2 SingFunction2 (/=@#@$)
forall k (a :: k) (b :: k).
SEq k =>
Sing a -> Sing b -> Sing (a /= b)
(%/=)
instance (SEq a, SingI x) => SingI ((/=@#@$$) x :: a ~> Bool) where
sing :: Sing ((/=@#@$$) x)
sing = SingFunction1 ((/=@#@$$) x) -> Sing ((/=@#@$$) x)
forall a1 b (f :: a1 ~> b). SingFunction1 f -> Sing f
singFun1 (SingI x => Sing x
forall k (a :: k). SingI a => Sing a
sing @x Sing x -> Sing t -> Sing (x /= t)
forall k (a :: k) (b :: k).
SEq k =>
Sing a -> Sing b -> Sing (a /= b)
%/=)