{-# OPTIONS_GHC -Wno-orphans #-}

{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}

-- | Orphan instances. They should probably be upstreamed.

module Generic.Data.Orphans where

import Data.Functor.Classes
import Data.Orphans ()
import Data.Semigroup
import GHC.Generics

instance Eq1 V1 where
  liftEq :: (a -> b -> Bool) -> V1 a -> V1 b -> Bool
liftEq a -> b -> Bool
_ V1 a
v V1 b
_ = case V1 a
v of {}

instance Ord1 V1 where
  liftCompare :: (a -> b -> Ordering) -> V1 a -> V1 b -> Ordering
liftCompare a -> b -> Ordering
_ V1 a
v V1 b
_ = case V1 a
v of {}

instance Eq1 U1 where
  liftEq :: (a -> b -> Bool) -> U1 a -> U1 b -> Bool
liftEq a -> b -> Bool
_ U1 a
_ U1 b
_ = Bool
True

instance Ord1 U1 where
  liftCompare :: (a -> b -> Ordering) -> U1 a -> U1 b -> Ordering
liftCompare a -> b -> Ordering
_ U1 a
_ U1 b
_ = Ordering
EQ

instance Eq c => Eq1 (K1 i c) where
  liftEq :: (a -> b -> Bool) -> K1 i c a -> K1 i c b -> Bool
liftEq a -> b -> Bool
_ (K1 c
x1) (K1 c
x2) = c
x1 c -> c -> Bool
forall a. Eq a => a -> a -> Bool
== c
x2

instance Ord c => Ord1 (K1 i c) where
  liftCompare :: (a -> b -> Ordering) -> K1 i c a -> K1 i c b -> Ordering
liftCompare a -> b -> Ordering
_ (K1 c
x1) (K1 c
x2) = c -> c -> Ordering
forall a. Ord a => a -> a -> Ordering
compare c
x1 c
x2

deriving instance Eq1 f => Eq1 (M1 i c f)
deriving instance Ord1 f => Ord1 (M1 i c f)

instance (Eq1 f, Eq1 g) => Eq1 (f :*: g) where
  liftEq :: (a -> b -> Bool) -> (:*:) f g a -> (:*:) f g b -> Bool
liftEq a -> b -> Bool
(==.) (f a
x1 :*: g a
y1) (f b
x2 :*: g b
y2) = (a -> b -> Bool) -> f a -> f b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
(==.) f a
x1 f b
x2 Bool -> Bool -> Bool
&& (a -> b -> Bool) -> g a -> g b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
(==.) g a
y1 g b
y2

instance (Ord1 f, Ord1 g) => Ord1 (f :*: g) where
  liftCompare :: (a -> b -> Ordering) -> (:*:) f g a -> (:*:) f g b -> Ordering
liftCompare a -> b -> Ordering
compare' (f a
x1 :*: g a
y1) (f b
x2 :*: g b
y2) =
    (a -> b -> Ordering) -> f a -> f b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
compare' f a
x1 f b
x2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (a -> b -> Ordering) -> g a -> g b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
compare' g a
y1 g b
y2

instance (Eq1 f, Eq1 g) => Eq1 (f :+: g) where
  liftEq :: (a -> b -> Bool) -> (:+:) f g a -> (:+:) f g b -> Bool
liftEq a -> b -> Bool
(==.) (L1 f a
x1) (L1 f b
x2) = (a -> b -> Bool) -> f a -> f b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
(==.) f a
x1 f b
x2
  liftEq a -> b -> Bool
(==.) (R1 g a
y1) (R1 g b
y2) = (a -> b -> Bool) -> g a -> g b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
(==.) g a
y1 g b
y2
  liftEq a -> b -> Bool
_ (:+:) f g a
_ (:+:) f g b
_ = Bool
False

instance (Ord1 f, Ord1 g) => Ord1 (f :+: g) where
  liftCompare :: (a -> b -> Ordering) -> (:+:) f g a -> (:+:) f g b -> Ordering
liftCompare a -> b -> Ordering
compare' (L1 f a
x1) (L1 f b
x2) = (a -> b -> Ordering) -> f a -> f b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
compare' f a
x1 f b
x2
  liftCompare a -> b -> Ordering
compare' (R1 g a
y1) (R1 g b
y2) = (a -> b -> Ordering) -> g a -> g b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
compare' g a
y1 g b
y2
  liftCompare a -> b -> Ordering
_ (L1 f a
_) (R1 g b
_) = Ordering
LT
  liftCompare a -> b -> Ordering
_ (R1 g a
_) (L1 f b
_) = Ordering
GT

instance Eq1 f => Eq1 (Rec1 f) where
  liftEq :: (a -> b -> Bool) -> Rec1 f a -> Rec1 f b -> Bool
liftEq a -> b -> Bool
(==.) (Rec1 f a
r1) (Rec1 f b
r2) = (a -> b -> Bool) -> f a -> f b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
(==.) f a
r1 f b
r2

instance Ord1 f => Ord1 (Rec1 f) where
  liftCompare :: (a -> b -> Ordering) -> Rec1 f a -> Rec1 f b -> Ordering
liftCompare a -> b -> Ordering
compare' (Rec1 f a
r1) (Rec1 f b
r2) = (a -> b -> Ordering) -> f a -> f b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
compare' f a
r1 f b
r2

instance Eq1 Par1 where
  liftEq :: (a -> b -> Bool) -> Par1 a -> Par1 b -> Bool
liftEq a -> b -> Bool
(==.) (Par1 a
p1) (Par1 b
p2) = a
p1 a -> b -> Bool
==. b
p2

instance Ord1 Par1 where
  liftCompare :: (a -> b -> Ordering) -> Par1 a -> Par1 b -> Ordering
liftCompare a -> b -> Ordering
compare' (Par1 a
p1) (Par1 b
p2) = a -> b -> Ordering
compare' a
p1 b
p2

instance (Eq1 f, Eq1 g) => Eq1 (f :.: g) where
  liftEq :: (a -> b -> Bool) -> (:.:) f g a -> (:.:) f g b -> Bool
liftEq a -> b -> Bool
(==.) (Comp1 f (g a)
x1) (Comp1 f (g b)
x2) = ((g a -> g b -> Bool) -> f (g a) -> f (g b) -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq ((g a -> g b -> Bool) -> f (g a) -> f (g b) -> Bool)
-> ((a -> b -> Bool) -> g a -> g b -> Bool)
-> (a -> b -> Bool)
-> f (g a)
-> f (g b)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> Bool) -> g a -> g b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq) a -> b -> Bool
(==.) f (g a)
x1 f (g b)
x2

instance (Ord1 f, Ord1 g) => Ord1 (f :.: g) where
  liftCompare :: (a -> b -> Ordering) -> (:.:) f g a -> (:.:) f g b -> Ordering
liftCompare a -> b -> Ordering
compare' (Comp1 f (g a)
x1) (Comp1 f (g b)
x2) =
    ((g a -> g b -> Ordering) -> f (g a) -> f (g b) -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare ((g a -> g b -> Ordering) -> f (g a) -> f (g b) -> Ordering)
-> ((a -> b -> Ordering) -> g a -> g b -> Ordering)
-> (a -> b -> Ordering)
-> f (g a)
-> f (g b)
-> Ordering
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b -> Ordering) -> g a -> g b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare) a -> b -> Ordering
compare' f (g a)
x1 f (g b)
x2