module Data.Record.HT.Private where

import Data.Monoid (mconcat, )
import Data.List.HT (switchL, )

{- |
Lexicographically compare a list of attributes of two records.

Example:

> compare [comparing fst, comparing snd]
-}
{-# INLINE compare #-}
compare :: [a -> a -> Ordering] -> a -> a -> Ordering
compare :: forall a. [a -> a -> Ordering] -> a -> a -> Ordering
compare [a -> a -> Ordering]
cs a
x a
y =
   [Ordering] -> Ordering
forall a. Monoid a => [a] -> a
mconcat ([Ordering] -> Ordering) -> [Ordering] -> Ordering
forall a b. (a -> b) -> a -> b
$ ((a -> a -> Ordering) -> Ordering)
-> [a -> a -> Ordering] -> [Ordering]
forall a b. (a -> b) -> [a] -> [b]
map (\a -> a -> Ordering
c -> a -> a -> Ordering
c a
x a
y) [a -> a -> Ordering]
cs

{-# INLINE compare1 #-}
compare1 :: [a -> a -> Ordering] -> a -> a -> Ordering
compare1 :: forall a. [a -> a -> Ordering] -> a -> a -> Ordering
compare1 [a -> a -> Ordering]
cs a
x a
y =
   Ordering
-> (Ordering -> [Ordering] -> Ordering) -> [Ordering] -> Ordering
forall b a. b -> (a -> [a] -> b) -> [a] -> b
switchL Ordering
EQ Ordering -> [Ordering] -> Ordering
forall a b. a -> b -> a
const ([Ordering] -> Ordering) -> [Ordering] -> Ordering
forall a b. (a -> b) -> a -> b
$ (Ordering -> Bool) -> [Ordering] -> [Ordering]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Ordering
EQOrdering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
==) ([Ordering] -> [Ordering]) -> [Ordering] -> [Ordering]
forall a b. (a -> b) -> a -> b
$ ((a -> a -> Ordering) -> Ordering)
-> [a -> a -> Ordering] -> [Ordering]
forall a b. (a -> b) -> [a] -> [b]
map (\a -> a -> Ordering
c -> a -> a -> Ordering
c a
x a
y) [a -> a -> Ordering]
cs

{-# INLINE compare2 #-}
compare2 :: [a -> a -> Ordering] -> a -> a -> Ordering
compare2 :: forall a. [a -> a -> Ordering] -> a -> a -> Ordering
compare2 [a -> a -> Ordering]
cs a
x a
y =
   [Ordering] -> Ordering
forall a. HasCallStack => [a] -> a
head ([Ordering] -> Ordering) -> [Ordering] -> Ordering
forall a b. (a -> b) -> a -> b
$ (Ordering -> Bool) -> [Ordering] -> [Ordering]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Ordering
EQOrdering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
==) (((a -> a -> Ordering) -> Ordering)
-> [a -> a -> Ordering] -> [Ordering]
forall a b. (a -> b) -> [a] -> [b]
map (\a -> a -> Ordering
c -> a -> a -> Ordering
c a
x a
y) [a -> a -> Ordering]
cs) [Ordering] -> [Ordering] -> [Ordering]
forall a. [a] -> [a] -> [a]
++ [Ordering
EQ]

{- |
Check whether a selected set of fields of two records is equal.

Example:

> equal [equating fst, equating snd]
-}
{-# INLINE equal #-}
equal :: [a -> a -> Bool] -> a -> a -> Bool
equal :: forall a. [a -> a -> Bool] -> a -> a -> Bool
equal [a -> a -> Bool]
cs a
x a
y = ((a -> a -> Bool) -> Bool) -> [a -> a -> Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\a -> a -> Bool
c -> a -> a -> Bool
c a
x a
y) [a -> a -> Bool]
cs