Enum and bounded instances for (,) and Either

Sandy Maguire sandy at sandymaguire.me
Wed May 12 17:52:56 UTC 2021

Hi all,

Found myself puzzled the other day when I wanted an (Enum a, Enum b) =>
Enum (a, b) instance, and was distraught that it didn't exist.

The following is a reasonable implementation:

instance (Bounded b, Enum a, Enum b) => Enum (a, b) where
  fromEnum (a, b) = (fromEnum (maxBound @b) + 1) * fromEnum a + fromEnum b
  toEnum n =
    let bound = fromEnum (maxBound @b) + 1
        b = n `rem` bound
        a = n `div` bound
     in (toEnum a, toEnum b)

And, while we're at it, might as well add canonical instances for Either:

instance (Bounded a, Bounded b) => Bounded (Either a b) where
  minBound = Left minBound
  maxBound = Right maxBound

instance (Bounded a, Enum a, Enum b) => Enum (Either a b) where
  toEnum i =
    let bound = fromEnum (maxBound @a) + 1
     in case i < bound of
          True -> Left $ toEnum i
          False -> Right $ toEnum $ i - bound
  fromEnum (Left a) = fromEnum a
  fromEnum (Right b) = fromEnum b + fromEnum (maxBound @a) + 1

Are there any reasons these instances are missing from base?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20210512/f66b5dd9/attachment.html>

More information about the Libraries mailing list