
Sometime back on one of the other Haskell lists, there was a proposal to not have the floating types instances of Enum and instead have some other class to which [a, b..c] desugars. That is, rename enumFromThen and friends and put them in another class. Put simply, Float and Double should not support succ and pred (unless, perhaps, they map to the next greater/lesser representable number, which would also be confusing). I can even see an argument for not allowing Float or Double to be used for ranges either, as the steps may not be exact, which in practice turns out to be very confusing. This is a wart I would really like to see get fixed. -- Aaron Denney -><-

On Fri, Mar 17, 2006 at 04:48:52PM +0000, Aaron Denney wrote:
Sometime back on one of the other Haskell lists, there was a proposal to not have the floating types instances of Enum and instead have some other class to which [a, b..c] desugars. That is, rename enumFromThen and friends and put them in another class. Put simply, Float and Double should not support succ and pred (unless, perhaps, they map to the next greater/lesser representable number, which would also be confusing). I can even see an argument for not allowing Float or Double to be used for ranges either, as the steps may not be exact, which in practice turns out to be very confusing.
Speaking of confusing, try [0, 0.3 .. 2]::[Rational] Also, toEnum and fromEnum would make more sense mapping from and to Integer. It seems that succ and pred are unused.

On 2006-03-17, Ross Paterson wrote:
Speaking of confusing, try
[0, 0.3 .. 2]::[Rational]
Right. I had forgotten that -- Rational is exact, yet has the weird "closest endpoint" behavior of Float and Double.
Also, toEnum and fromEnum would make more sense mapping from and to Integer. It seems that succ and pred are unused.
So, I think I'll put together a proposal, well two. Okay, three. First, change toEnum and fromEnum to Integer. Then there is a choice between: (1): Remove Double, Float, and Rational from Enum. They're no longer usable in arithmetic sequences. Pro: Very easy to do. Sequences can still be constructed by starting with integers, and scaling to convert. Con: Loses some functionality (though it's questionable functionality given rounding). (2): Split Enum into the classes Enum and ArithmeticSequence and change what the various [..] desugars to. class Enum a where succ, pred :: a -> a toEnum :: Integer -> a fromEnum :: a -> Integer I believe succ and pred aren't used directly by anything else, but I do like having them. instance Integer, Int Rational _could_ be added here by the diagonal representation, but probably sohuldn't. class ArithmeticSequence a where stepFrom :: a -> [a] -- [n..] stepFromBy :: a -> a -> [a] -- [n,n'..] stepFromTo :: a -> a -> [a] -- [n..m] stepFromByTo :: a -> a -> a -> [a] -- [n,n'..m] instance Int, Integer, Float, Double, Rational. (a) Make all of them have the "closest endpoint" behavior. (b) Make all of them have strict "no more than" behavior. Pros: Clearly divides two seperate uses, while keeping functionality. Can re-introduce relationship between Ix and Enum? Cons: Yet another typeclass. Slightly misleading name, as non-arithmetic structures _should_ be supported. Also a bit long. But doing so automatically is tricky, as toEnum and fromEnum are no longer accessible Keeps questionable functionality of non-exact arithmetic sequences. Personally, I'm for 2(a), but I think even (1) is an improvement. It's a pity we can't make Enum a subclass of ArithmeticSequence that provides the methods of its superclass. Would it be possible to have "data ... (deriving ArithmeticSequence)" check if (Num a, Ord a) is defined and use (+), else if Enum a is defined, use fromEnum/toEnum to go through Integer, else fail. Where I suppose defined must mean "defined in this module". Hmm. That's kind of ugly. I can see why these were combined, but it's still really ugly. Steppable might be a better name. Comments anyone? -- Aaron Denney -><-

On 3/18/06, Aaron Denney
Rational _could_ be added here by the diagonal representation, but probably sohuldn't.
We could also add an actual enumeration of rationals, as in http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/rationals.p... It would be quite confusing to write, say, [1%2 .. 3%2] and get 2%1 and 1%3 in the middle! Jim

On 2006-03-18, Jim Apple
On 3/18/06, Aaron Denney
wrote: Rational _could_ be added here by the diagonal representation, but probably sohuldn't.
We could also add an actual enumeration of rationals, as in http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/rationals.p...
It would be quite confusing to write, say, [1%2 .. 3%2] and get 2%1 and 1%3 in the middle!
Right, hence my desire to make it a sequence, but not Enumerable, since it has quite a few different quasi-natural ways of doing so. -- Aaron Denney -><-

On 2006-03-18, Aaron Denney
class ArithmeticSequence a where stepFrom :: a -> [a] -- [n..] stepFromBy :: a -> a -> [a] -- [n,n'..] stepFromTo :: a -> a -> [a] -- [n..m] stepFromByTo :: a -> a -> a -> [a] -- [n,n'..m]
Whoops, it was a big thinko to change "Then" to "By" here. These should be stepFromThenTo, etc. -- Aaron Denney -><-

Am Freitag, 17. März 2006 18:49 schrieb Ross Paterson:
[...]
Also, toEnum and fromEnum would make more sense mapping from and to Integer.
Why do we need toEnum and fromEnum at all? As far as I know, they are merely there to help people implement things like enumFrom. It's often not clear how toEnum and fromEnum should look like. How should they be implemented for Time.Day, for example? Should the days corresponds to the integers 0 to 6 or 1 to 7?
It seems that succ and pred are unused.
No, I use them. In my opinion, it makes much more sense to write succ n than n + 1. Best wishes, Wolfgang

On 2006-03-20, Wolfgang Jeltsch
Am Freitag, 17. März 2006 18:49 schrieb Ross Paterson:
[...]
Also, toEnum and fromEnum would make more sense mapping from and to Integer.
Why do we need toEnum and fromEnum at all? As far as I know, they are merely there to help people implement things like enumFrom.
Which could still be useful.
It's often not clear how toEnum and fromEnum should look like. How should they be implemented for Time.Day, for example? Should the days corresponds to the integers 0 to 6 or 1 to 7?
I believe that 0 to n-1 is the standard representation that deriving Enum currently uses.
It seems that succ and pred are unused.
No, I use them. In my opinion, it makes much more sense to write succ n than n + 1.
Agreed, for non-arithmetical types. -- Aaron Denney -><-

Am Dienstag, 21. März 2006 02:47 schrieb Aaron Denney:
[...]
No, I use them. In my opinion, it makes much more sense to write succ n than n + 1.
Agreed, for non-arithmetical types.
I think, it's perfectly sensible for arithmetical types like Integer. If you mean “the next integer” then succ n is the most logical thing to write. If you write n + 1 instead, you invoke a more complex operation (addition) with a special constant as one of its parameters, and this obfuscates what you actually mean, in my opinion. Best wishes, Wolfgang

Wolfgang Jeltsch
Also, toEnum and fromEnum would make more sense mapping from and to Integer.
Why do we need toEnum and fromEnum at all? As far as I know, they are merely there to help people implement things like enumFrom.
They are often useful for writing serialisation routines, and they see occasional use for other kinds of safe type coercion as well (toEnum . fromEnum) Regards, Malcolm

Am Dienstag, 21. März 2006 10:08 schrieb Malcolm Wallace:
Wolfgang Jeltsch
writes: [...]
Why do we need toEnum and fromEnum at all? As far as I know, they are merely there to help people implement things like enumFrom.
They are often useful for writing serialisation routines, and they see occasional use for other kinds of safe type coercion as well (toEnum . fromEnum)
Regards, Malcolm
Maybe they should be in a separate class. Enum should be about enumerating, not “indexing”. Best wishes, Wolfgang
participants (5)
-
Aaron Denney
-
Jim Apple
-
Malcolm Wallace
-
Ross Paterson
-
Wolfgang Jeltsch