```{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Ord
-- Copyright   :  (c) The University of Glasgow 2005
--
-- Maintainer  :  [email protected]
-- Stability   :  stable
-- Portability :  portable
--
-- Orderings
--
-----------------------------------------------------------------------------

module Data.Ord (
Ord(..),
Ordering(..),
Down(..),
comparing,
) where

import GHC.Base
import GHC.Show
import GHC.Num

-- |
-- > comparing p x y = compare (p x) (p y)
--
-- Useful combinator for use in conjunction with the @[email protected] family
-- of functions from "Data.List", for example:
--
-- >   ... sortBy (comparing fst) ...
comparing :: (Ord a) => (b -> a) -> b -> b -> Ordering
comparing p x y = compare (p x) (p y)

-- | The 'Down' type allows you to reverse sort order conveniently.  A value of type
-- @'Down' [email protected] contains a value of type @[email protected] (represented as @'Down' [email protected]).
-- If @[email protected] has an @'Ord'@ instance associated with it then comparing two
-- values thus wrapped will give you the opposite of their normal sort order.
-- This is particularly useful when sorting in generalised list comprehensions,
-- as in: @then sortWith by 'Down' [email protected]
--
-- @since 4.6.0.0
newtype Down a = Down a
deriving
( Eq
, Show -- ^ @since 4.7.0.0
, Read -- ^ @since 4.7.0.0
, Num -- ^ @since 4.11.0.0
, Semigroup -- ^ @since 4.11.0.0
, Monoid -- ^ @since 4.11.0.0
)

-- | @since 4.6.0.0
instance Ord a => Ord (Down a) where
compare (Down x) (Down y) = y `compare` x

-- | @since 4.11.0.0
instance Functor Down where
fmap = coerce

-- | @since 4.11.0.0
instance Applicative Down where
pure = Down
(<*>) = coerce

-- | @since 4.11.0.0