isnt there also the issue that while we good provide newtypes for various choices of product of enum instance => enum of products, there literally quite easily 3 valid instances we could concoct (and  many more besides)

"row by row"
"column by column"
"diagonalization"
etc?
that is: each of these is just as valid?

On Wed, May 12, 2021 at 5:46 PM Edward Kmett <ekmett@gmail.com> wrote:
Nothing indicates that minBound is >= 0.

So if you want to deal with a modulus properly you need to deal with a modulus of something like maxBound - minBound + 1 (after appropriately upcasting intermediate results to a large enough type to contain that range). 

You also run into range issues pretty early on, and then scenarios like the instances for Float that are even wonkier.

If toEnum/fromEnum went to a larger type (Integer or Natural) and we didn't have the wonkier Float instances and the like this would be a much easier sell. As it is I find myself rather uncomfortable with the shakiness of the foundations this thing rests upon.

Sent from my iPhone

On May 12, 2021, at 10:53 AM, Sandy Maguire <sandy@sandymaguire.me> wrote:


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?

Cheers,
Sandy

_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries