-- | Partially ordered data types. The standard 'Prelude.Ord' class is for -- total orders and therefore not suitable for floating point. -- However, we can still define meaningful 'max' and 'sort' functions for these types. -- -- We define our own 'Ord' class which is intended as a replacement for -- 'Prelude.Ord'. However, in order to take advantage of existing libraries -- which use 'Prelude.Ord', we make every instance of 'Ord' an instance of -- 'Prelude.Ord'. This is done using the OVERLAPS and UndecidableInstances -- extensions -- it remains to be seen if problems occur as a result of this. module Data.Poset ( Poset(..), Sortable(..), Ordering(..), Ord, module Data.Poset ) where import qualified Prelude import Prelude hiding (Ord(..), Ordering(..)) import qualified Data.List as List import Data.Poset.Instances import Data.Poset.Internal import Data.Function import Data.Monoid instance Poset a => Poset (Maybe a) where Just x <= Just y = x <= y Nothing <= _ = True _ <= _ = False instance Poset a => Poset [a] where compare = (mconcat .) . zipWith compare -- | Sort a list using the default comparison function. sort :: Sortable a => [a] -> [a] sort = sortBy compare -- | Sort a list using (isOrder, compare). sortBy' :: ((a -> Bool), (a -> a -> Ordering)) -> [a] -> [a] sortBy' (p, f) = List.sortBy ((totalOrder.).f) . filter p -- | Apply a function to values before comparing. comparing :: Poset b => (a -> b) -> a -> a -> Ordering comparing = on compare