Equivalence.hs (2692B)
1 {-# LANGUAGE UndecidableInstances #-} 2 3 module Lude.Equivalence ( 4 Equivalential (..), 5 (==), 6 (/=), 7 (≠), 8 ) where 9 10 import Data.Coerce 11 import Numeric.Natural qualified as Base 12 import Prelude qualified as Base 13 14 import Lude.Bool 15 import Lude.Function 16 import Lude.Haskell 17 18 -------------------------------------------------------------------------------- 19 20 type Equivalential :: forall {r :: Repr}. Type# r -> Constraint 21 class Equivalential (a :: Type# r) where 22 {-# MINIMAL eq | ne #-} 23 24 eq :: a -> a -> Bool 25 default eq :: (Functional# r) => a -> a -> Bool 26 eq = lam2# \x y -> not (app2# ne x y) 27 {-# INLINE eq #-} 28 29 ne :: a -> a -> Bool 30 default ne :: (Functional# r) => a -> a -> Bool 31 ne = lam2# \x y -> not (app2# eq x y) 32 {-# INLINE ne #-} 33 34 (==), (/=), (≠) :: forall {r :: Repr} (a :: Type# r). (Equivalential a) => a -> a -> Bool 35 (==) = eq 36 (/=) = ne 37 (≠) = ne 38 infix 4 ==, /=, ≠ 39 40 -------------------------------------------------------------------------------- 41 -- Generics 42 43 instance Equivalential (GVoid p) where 44 eq = elimGVoid 45 ne = elimGVoid 46 47 instance Equivalential (GUnit p) where 48 eq MkGUnit MkGUnit = True 49 ne MkGUnit MkGUnit = False 50 51 instance (Equivalential a) => Equivalential (GConst i a p) where 52 eq = eq `on` unGConst 53 ne = ne `on` unGConst 54 55 instance (Equivalential (f p)) => Equivalential (GMeta i t f p) where 56 eq = eq `on` unGMeta 57 ne = ne `on` unGMeta 58 59 instance (Equivalential (f p), Equivalential (g p)) => Equivalential (GSum f g p) where 60 eq (GLeft x0) (GLeft x1) = eq x0 x1 61 eq (GRight y0) (GRight y1) = eq y0 y1 62 eq (GLeft _) (GRight _) = False 63 eq (GRight _) (GLeft _) = False 64 ne (GLeft x0) (GLeft x1) = ne x0 x1 65 ne (GRight y0) (GRight y1) = ne y0 y1 66 ne (GLeft _) (GRight _) = True 67 ne (GRight _) (GLeft _) = True 68 69 instance (Equivalential (f p), Equivalential (g p)) => Equivalential (GProd f g p) where 70 eq (GPair x0 y0) (GPair x1 y1) = eq x0 x1 && eq y0 y1 71 ne (GPair x0 y0) (GPair x1 y1) = ne x0 x1 || ne y0 y1 72 73 -- TODO: URec instances 74 75 instance (Generically Equivalential a) => Equivalential (Genericity a) where 76 eq = eq `on` grep 77 ne = ne `on` grep 78 79 -------------------------------------------------------------------------------- 80 -- Interop 81 82 instance (Base.Eq a) => Equivalential (BaseInterop a) where 83 eq = coerce (Base.==) 84 ne = coerce (Base./=) 85 86 deriving via BaseInterop Base.Ordering instance Equivalential Base.Ordering 87 deriving via BaseInterop Base.Natural instance Equivalential Base.Natural 88 deriving via BaseInterop Base.Integer instance Equivalential Base.Integer 89 deriving via BaseInterop Base.Rational instance Equivalential Base.Rational