module Algebra.EqualityDecision where
import qualified NumericPrelude.Elementwise as Elem
import Control.Applicative (Applicative(pure, (<*>)), )
import Data.Tuple.HT (fst3, snd3, thd3, )
import Data.List (zipWith4, )
class C a where
(==?) :: a -> a -> a -> a -> a
{-# INLINE deflt #-}
deflt :: Eq a => a -> a -> a -> a -> a
deflt a b eq noteq =
if a==b then eq else noteq
instance C Int where
{-# INLINE (==?) #-}
(==?) = deflt
instance C Integer where
{-# INLINE (==?) #-}
(==?) = deflt
instance C Float where
{-# INLINE (==?) #-}
(==?) = deflt
instance C Double where
{-# INLINE (==?) #-}
(==?) = deflt
instance C Bool where
{-# INLINE (==?) #-}
(==?) = deflt
instance C Ordering where
{-# INLINE (==?) #-}
(==?) = deflt
{-# INLINE element #-}
element ::
(C x) =>
(v -> x) -> Elem.T (v,v,v,v) x
element f =
Elem.element (\(x,y,eq,noteq) -> (f x ==? f y) (f eq) (f noteq))
{-# INLINE (<*>.==?) #-}
(<*>.==?) ::
(C x) =>
Elem.T (v,v,v,v) (x -> a) -> (v -> x) -> Elem.T (v,v,v,v) a
(<*>.==?) f acc =
f <*> element acc
instance (C a, C b) => C (a,b) where
{-# INLINE (==?) #-}
(==?) = Elem.run4 $ pure (,) <*>.==? fst <*>.==? snd
instance (C a, C b, C c) => C (a,b,c) where
{-# INLINE (==?) #-}
(==?) = Elem.run4 $ pure (,,) <*>.==? fst3 <*>.==? snd3 <*>.==? thd3
instance C a => C [a] where
{-# INLINE (==?) #-}
(==?) = zipWith4 (==?)
instance (C a) => C (b -> a) where
{-# INLINE (==?) #-}
(==?) x y eq noteq c = (x c ==? y c) (eq c) (noteq c)