-- | Generic equality. -- -- This module contains a generic equality function defined using -- @generics-sop@. -- module Generics.SOP.Eq (geq) where import Data.Function import Generics.SOP -- | Generic equality. -- -- This function reimplements the built-in generic equality that -- you get by using @deriving Eq@. -- -- Assuming you have a 'Generics.SOP.Generic' instance for a -- datatype @T@, you can use 'geq' as follows: -- -- > instance Eq T where -- > (==) = geq -- geq :: (Generic a, All2 Eq (Code a)) => a -> a -> Bool geq = go `on` from where go :: forall xss. (All2 Eq xss, All SListI xss) => SOP I xss -> SOP I xss -> Bool go (SOP (Z xs)) (SOP (Z ys)) = and . hcollapse $ hcliftA2 p eq xs ys go (SOP (S xss)) (SOP (S yss)) = go (SOP xss) (SOP yss) go _ _ = False p :: Proxy Eq p = Proxy eq :: forall (a :: *). Eq a => I a -> I a -> K Bool a eq (I a) (I b) = K (a == b)