diff options
Diffstat (limited to 'libraries/base/Data/Ord.hs')
-rw-r--r-- | libraries/base/Data/Ord.hs | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/libraries/base/Data/Ord.hs b/libraries/base/Data/Ord.hs index b21acb8e33..779e1b69d0 100644 --- a/libraries/base/Data/Ord.hs +++ b/libraries/base/Data/Ord.hs @@ -24,11 +24,11 @@ module Data.Ord ( clamp, ) where -import Data.Bits (Bits, FiniteBits) +import Data.Bits (Bits, FiniteBits, complement) import Foreign.Storable (Storable) import GHC.Ix (Ix) import GHC.Base -import GHC.Enum (Bounded(..)) +import GHC.Enum (Bounded(..), Enum(..)) import GHC.Float (Floating, RealFloat) import GHC.Num import GHC.Read @@ -146,6 +146,26 @@ instance Bounded a => Bounded (Down a) where minBound = Down maxBound maxBound = Down minBound +-- | Swaps @'succ'@ and @'pred'@ of the underlying type. +-- +-- @since 4.18.0.0 +instance (Enum a, Bounded a, Eq a) => Enum (Down a) where + succ = fmap pred + pred = fmap succ + + -- Here we use the fact that 'comparing (complement @Int)' behaves + -- as an order-swapping `compare @Int`. + fromEnum = complement . fromEnum . getDown + toEnum = Down . toEnum . complement + + enumFrom (Down x) + | x == minBound + = [Down x] -- We can't rely on 'enumFromThen _ (pred @a minBound)` behaving nicely, + -- since 'enumFromThen _' might be strict and 'pred minBound' might throw + | otherwise + = coerce $ enumFromThen x (pred x) + enumFromThen (Down x) (Down y) = coerce $ enumFromThen x y + -- | @since 4.11.0.0 instance Functor Down where fmap = coerce |