    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