{-# LANGUAGE FlexibleContexts , TypeFamilies , UnicodeSyntax #-} -- |Indirect equality comparison. module Data.Eq.Indirect ( Eq'(..) , (==:) , (/=:) , (≡:) , (≢:) , (≠:) ) where import Prelude.Unicode infix 4 ==:, /=:, ≡:, ≢:, ≠: -- |Type class for indirectly equality-comparable types. That is, any -- @α@ of @'Eq'' α@ has a monomorphism to some -- equality-comparable type @γ@ while @α@ itself isn't -- necessarily an instance of 'Eq'. This way we can generalise the -- '==' operator so that it can take two different types as long as -- they both have monomorphisms to the same 'Eq' type @γ@. -- -- Minimal complete definition: 'Unified' and 'unify'. class Eq (Unified α) ⇒ Eq' α where -- |The said equality-comparable type @γ@. type Unified α -- |Monomorphism from @α@ to @γ@. unify ∷ α → Unified α -- |FIXME: doc (==:) ∷ (Eq' α, Eq' β, Unified α ~ Unified β) ⇒ α → β → Bool {-# INLINE (==:) #-} (==:) = (∘ unify) ∘ (≡) ∘ unify -- |FIXME: doc (/=:) ∷ (Eq' α, Eq' β, Unified α ~ Unified β) ⇒ α → β → Bool {-# INLINE (/=:) #-} (/=:) = ((¬) ∘) ∘ (==:) -- |FIXME: doc (≡:) ∷ (Eq' α, Eq' β, Unified α ~ Unified β) ⇒ α → β → Bool {-# INLINE CONLIKE (≡:) #-} (≡:) = (==:) -- |FIXME: doc (≢:) ∷ (Eq' α, Eq' β, Unified α ~ Unified β) ⇒ α → β → Bool {-# INLINE CONLIKE (≢:) #-} (≢:) = (/=:) -- |FIXME: doc (≠:) ∷ (Eq' α, Eq' β, Unified α ~ Unified β) ⇒ α → β → Bool {-# INLINE CONLIKE (≠:) #-} (≠:) = (/=:)