Haskell 98: Enum class
| > i_succ' = succ i' | > -- ghc : 2147483648 | > -- hugs: -2147483648 | -- nhc98: -2147483648 | -- hbc: -2147483648 | | > I think Hugs is wrong. Integer shouldn't wrap. | | (Actually, ghc is `wrong': hbc, hugs and nhc98 match the Report's | specification here: succ = toEnum . (+1) . fromEnum | This is confirmed by the description of the semantics in | section 3.10.) Lies, all lies. The default methods do not constitute a specification; in this case at least, they only approximate the truth. The Report is quite specific about what enumFrom and friends should do for Integer (Section 3.10). Admittedly, that's a funny place to have to look. Maybe I should move that stuff from 3.10 to 6.3.4. The Report is (regrettably) silent about what the Integer instances for succ and pred should be, but they should definitely simply add 1 (resp subtract 1). They should emphatically not use the default methods. I will add something to that effect in 6.3.4. However Section 6.3.4 is silent on the question of what succ and pred do at the end of the range. What is (succ maxInt)? Bizarrely, Appendix D.2 (derived instances of Enum) tells us that that's an error. (Bizarre because this fact belongs in 6.3.4 not in D.2.) In summary, I propose the following (presentational) changes to the Report. 1. Move specification of enumFrom and friends from 3.10 to 6.3.4 2. Specify that for bounded types, (succ maxBound) and (pred minBound) are errors. 3. Specify that succ and pred on numeric types just add/subtract 1 (subject to (2) above. 4. Rewrite D.2 to talk about deriving only, not about Enum in general. 5. In Appendix A, the Enum class defn, add comments to explain that the default methods only work for types whose fromEnum/toEnum range fits inside Int. Would that at least make the present sitation clear. Acknowledging that Enum has warty features. Simon
On Wed, Oct 24, 2001 at 07:51:12AM -0700, Simon Peyton-Jones wrote:
The Report is (regrettably) silent about what the Integer instances for succ and pred should be, but they should definitely simply add 1 (resp subtract 1). They should emphatically not use the default methods. I will add something to that effect in 6.3.4. ... 3. Specify that succ and pred on numeric types just add/subtract 1 (subject to (2) above).
Can you write some code people can cut&paste for instance of Enum on ordered numeric types, just so this is crystal clear? You might even put in some bounds checking: succ x = let y = x+1 in if y > x then y else error "succ overflowed" --Dylan
| | (Actually, ghc is `wrong': hbc, hugs and nhc98 match the Report's | | specification here: succ = toEnum . (+1) . fromEnum | | This is confirmed by the description of the semantics in | | section 3.10.) | | Lies, all lies. The default methods do not constitute a specification; | in this case at least, they only approximate the truth. But the Report is emphatic that Appendix A _does_ constitute a specification for the Prelude, and I had always assumed that the default definitions given there are "safe" for all types, though not necessarily efficient. If the default methods are semantically incorrect (for some types) then they must be changed or removed. | The Report is (regrettably) silent about what the Integer | instances for succ and pred should be, but they should definitely simply | add 1 (resp subtract 1). Admittedly section 3.10 does not mention succ and pred explicitly, but it does otherwise confirm the semantics of the current default definitions, namely that: "For other discrete Prelude types t that are instances of Enum, namely ... Integer, the semantics is given by mapping ... to Int using fromEnum, ... , and then mapping back to t with toEnum." However I agree that succ = (+1) pred = (\x-> x-1) would make better sense.
5. In Appendix A, the Enum class defn, add comments to explain that the default methods only work for types whose fromEnum/toEnum range fits inside Int.
I would rather have correct default definitions. Regards, Malcolm
Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> writes:
5. In Appendix A, the Enum class defn, add comments to explain that the default methods only work for types whose fromEnum/toEnum range fits inside Int.
I would rather have correct default definitions.
Somebody raised the issue why to/fromEnum doesn't use Integer instead of Int. This would, it would seem, solve at least some of the Enum problems that arise from (integral) types with more than 4G values. So, again, why not? -kzm -- If I haven't seen further, it is by standing in the footprints of giants
participants (4)
-
Dylan Thurston -
Ketil Malde -
Malcolm Wallace -
Simon Peyton-Jones