------------------------------------------------------------------------------- |-- Module : Data.COrdering-- Copyright : (c) Adrian Hey 2004-2008-- License : BSD3---- Maintainer : http://homepages.nildram.co.uk/~ahey/em.png-- Stability : stable-- Portability : portable---- This module defines a useful variant of the "Prelude" `Ordering` data type.---- Typically this data type is used as the result of a \"combining comparison\"-- which combines values that are deemed to be equal (somehow). Note that the-- functions defined here adhere to the same ordering convention as the overloaded-- 'compare' (from the 'Ord' class). That is..---- @-- a \`compare\` b -> LT (or Lt) implies a < b-- a \`compare\` b -> GT (or Gt) implies a > b-- @---- The combinators exported from this module have a \"CC\" suffix if they-- return a combining comparison (most of them) and a \"C\" suffix if they return-- an ordinary comparison. All the combinators defined here are INLINEd, in the hope-- that the compiler can avoid the overhead of using HOFs for frequently-- used comparisons (dunno if this does any good though :-)-----------------------------------------------------------------------------moduleData.COrdering(-- * TypesCOrdering(..),-- * Useful combinators-- ** Misc.unitCC,unitByCC,fstCC,fstByCC,sndCC,sndByCC,flipC,flipCC,-- ** For combining \"equal\" values with a user supplied function.withCC,withCC',withByCC,withByCC',)whereimportData.Typeable-- | Result of a combining comparison.dataCOrderinga=Lt|Eqa|Gtderiving(Eq,Ord,Read,Show)-- A name for the COrdering type constructor, fully qualifiedcOrderingTyConName::StringcOrderingTyConName="Data.COrdering.COrdering"-- A Typeable1 instanceinstanceTypeable1COrderingwheretypeOf1_=mkTyConApp(mkTyConcOrderingTyConName)[]#ifndef __GLASGOW_HASKELL__-- A Typeable instance (not needed by ghc, but Haddock fails to document this instance)instanceTypeablee=>Typeable(COrderinge)wheretypeOf=typeOfDefault#endif-- | A combining comparison for an instance of 'Ord' which returns unit () where appropriate.{-# INLINE unitCC #-}unitCC::Orda=>(a->a->COrdering())unitCCab=casecompareabofLT->LtEQ->Eq()GT->Gt-- | Create a combining comparison from an ordinary comparison by returning unit () where appropriate.{-# INLINE unitByCC #-}unitByCC::(a->b->Ordering)->(a->b->COrdering())unitByCCcmpab=casecmpabofLT->LtEQ->Eq()GT->Gt-- | A combining comparison for an instance of 'Ord' which keeps the first argument-- if they are deemed equal. The second argument is discarded in this case.{-# INLINE fstCC #-}fstCC::Orda=>(a->a->COrderinga)fstCCaa'=casecompareaa'ofLT->LtEQ->EqaGT->Gt-- | Create a combining comparison from an ordinary comparison by keeping the first argument-- if they are deemed equal. The second argument is discarded in this case.{-# INLINE fstByCC #-}fstByCC::(a->b->Ordering)->(a->b->COrderinga)fstByCCcmpab=casecmpabofLT->LtEQ->EqaGT->Gt-- | A combining comparison for an instance of 'Ord' which keeps the second argument-- if they are deemed equal. The first argument is discarded in this case.{-# INLINE sndCC #-}sndCC::Orda=>(a->a->COrderinga)sndCCaa'=casecompareaa'ofLT->LtEQ->Eqa'GT->Gt-- | Create a combining comparison from an ordinary comparison by keeping the second argument-- if they are deemed equal. The first argument is discarded in this case.{-# INLINE sndByCC #-}sndByCC::(a->b->Ordering)->(a->b->COrderingb)sndByCCcmpab=casecmpabofLT->LtEQ->EqbGT->Gt-- | Create a combining comparison using the supplied combining function, which is applied if-- 'compare' returns 'EQ'. See 'withCC'' for a stricter version of this function.{-# INLINE withCC #-}withCC::Orda=>(a->a->b)->(a->a->COrderingb)withCCfaa'=casecompareaa'ofLT->LtEQ->Eq(faa')GT->Gt-- | Same as 'withCC', except the combining function is applied strictly.{-# INLINE withCC' #-}withCC'::Orda=>(a->a->b)->(a->a->COrderingb)withCC'faa'=casecompareaa'ofLT->LtEQ->letb=faa'inb`seq`EqbGT->Gt-- | Create a combining comparison using the supplied comparison and combining function,-- which is applied if the comparison returns 'EQ'. See 'withByCC'' for a stricter version-- of this function.{-# INLINE withByCC #-}withByCC::(a->b->Ordering)->(a->b->c)->(a->b->COrderingc)withByCCcmpfab=casecmpabofLT->LtEQ->Eq(fab)GT->Gt-- | Same as 'withByCC', except the combining function is applied strictly.{-# INLINE withByCC' #-}withByCC'::(a->b->Ordering)->(a->b->c)->(a->b->COrderingc)withByCC'cmpfab=casecmpabofLT->LtEQ->letc=fabinc`seq`EqcGT->Gt-- | Converts a comparison to one which takes arguments in flipped order, but-- preserves the ordering that would be given by the \"unflipped\" version (disregarding type issues).-- So it's not the same as using the prelude 'flip' (which would reverse the ordering too).{-# INLINE flipC #-}flipC::(a->b->Ordering)->(b->a->Ordering)flipCcmpba=casecmpabofLT->GTEQ->EQGT->LT-- | Converts a combining comparison to one which takes arguments in flipped order, but-- preserves the ordering that would be given by the \"unflipped\" version (disregarding type issues).-- So it's not the same as using the prelude 'flip' (which would reverse the ordering too).{-# INLINE flipCC #-}flipCC::(a->b->COrderingc)->(b->a->COrderingc)flipCCcmpba=casecmpabofLt->Gte@(Eq_)->eGt->Lt