{-# LANGUAGE Safe #-}
module Data.Universe.Instances.Ord (
  -- | An 'Ord' instance for functions, given the input is 'Finite' and the
  -- output is 'Ord'. Compares pointwise, with higher priority to inputs
  -- that appear earlier in 'universeF'.
  Ord(..)
  ) where

import qualified Data.Monoid as Mon
import Data.Universe.Class (Finite (..))
import Data.Universe.Instances.Eq

instance (Finite a, Ord b) => Ord (a -> b) where
  a -> b
f compare :: (a -> b) -> (a -> b) -> Ordering
`compare` a -> b
g = [Ordering] -> Ordering
forall a. Monoid a => [a] -> a
Mon.mconcat [a -> b
f a
x b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` a -> b
g a
x | a
x <- [a]
forall a. Finite a => [a]
universeF]

instance (Finite a, Ord a) => Ord (Mon.Endo a) where
  compare :: Endo a -> Endo a -> Ordering
compare (Mon.Endo a -> a
f) (Mon.Endo a -> a
g) = (a -> a) -> (a -> a) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a -> a
f a -> a
g