{-# LANGUAGE Safe #-}

{- |
    Module      :  SDP.Comparing
    Copyright   :  (c) Andrey Mulik 2019
    License     :  BSD-style
    Maintainer  :  work.a.mulik@gmail.com
    Portability :  portable
    
    "SDP.Comparing" provide common comparators and combinators.
-}
module SDP.Comparing
(
  -- * Exports
  module Data.Ord,
  module Data.Eq,
  
  -- * Type synonyms
  Equal, Compare,
  
  -- * Common comparators
  (<=>), eqfst, eqsnd, cmpfst, cmpsnd, invertcmp
)
where

import Data.Function
import Data.Ord
import Data.Eq

default ()

infixl 4 <=>

--------------------------------------------------------------------------------

{- Type synonyms. -}

-- | 'Equal' is just synonym of @(e -> e -> Bool)@.
type Equal   e = e -> e -> Bool

-- | 'Compare' is just synonym of @(e -> e -> Ordering)@.
type Compare e = e -> e -> Ordering

--------------------------------------------------------------------------------

-- | Spaceship operator - infix version of compare.
(<=>) :: (Ord o) => Compare o
<=> :: Compare o
(<=>) = Compare o
forall a. Ord a => a -> a -> Ordering
compare

-- | Compare tuples by first elements.
eqfst :: (Eq e) => Equal (e, s)
eqfst :: Equal (e, s)
eqfst =  e -> e -> Bool
forall a. Eq a => a -> a -> Bool
(==) (e -> e -> Bool) -> ((e, s) -> e) -> Equal (e, s)
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (e, s) -> e
forall a b. (a, b) -> a
fst

-- | Compare tuples by second elements.
eqsnd :: (Eq e) => Equal (f, e)
eqsnd :: Equal (f, e)
eqsnd =  e -> e -> Bool
forall a. Eq a => a -> a -> Bool
(==) (e -> e -> Bool) -> ((f, e) -> e) -> Equal (f, e)
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (f, e) -> e
forall a b. (a, b) -> b
snd

-- | Compare tuples by first elements.
cmpfst :: (Ord o) => Compare (o, s)
cmpfst :: Compare (o, s)
cmpfst =  ((o, s) -> o) -> Compare (o, s)
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (o, s) -> o
forall a b. (a, b) -> a
fst

-- | Compare tuples by second elements.
cmpsnd :: (Ord o) => Compare (f, o)
cmpsnd :: Compare (f, o)
cmpsnd =  ((f, o) -> o) -> Compare (f, o)
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (f, o) -> o
forall a b. (a, b) -> b
snd

-- | Common compare combinator
invertcmp :: Compare e -> Compare e
invertcmp :: Compare e -> Compare e
invertcmp =  Compare e -> Compare e
forall a b c. (a -> b -> c) -> b -> a -> c
flip