Why does Enum succ and pred functions throw exception

Hi everyone, Can anyone shed some light on why the succ and pred functions of the Enum typeclass throw exceptions if we go over the upper or lower boundary, and not return Maybe a? I was hoping to have some functions like: safeSucc :: (Enum a) => a -> Maybe a Because the succ and pred functions throw exceptions I can only catch them in the IO monad. This makes it hard to deal with this situation in pure code. Regards Rouan.

At Thu, 21 Jun 2012 10:11:24 +0100 (BST), Rouan van Dalen wrote:
Hi everyone,
Can anyone shed some light on why the succ and pred functions of the Enum typeclass throw exceptions if we go over the upper or lower boundary, and not return Maybe a?
I was hoping to have some functions like:
safeSucc :: (Enum a) => a -> Maybe a
Because the succ and pred functions throw exceptions I can only catch them in the IO monad. This makes it hard to deal with this situation in pure code.
Regards
Rouan.
That decision was most likely dictated by the convenience of now having the Maybe - and remember that many Enum data types are not bounded anyway, so they would never need that. In any case, you can easily roll your own safeSucc :: (Enum a, Bounded a) => a -> Maybe a safeSucc x | x == maxBound = Nothing | otherwise = Just (succ x) Francesco.

On Thu, Jun 21, 2012 at 5:11 AM, Rouan van Dalen
Can anyone shed some light on why the succ and pred functions of the Enum typeclass throw exceptions if we go over the upper or lower boundary, and not return Maybe a?
Enum and Bounded have a complicated and arguably incorrect[1] relationship. The whole thing should be overhauled, but this would break quite a lot of code, so is not likely to happen. [1] http://www.haskell.org/pipermail/haskell-cafe/2011-September/095431.htmlff. -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms

On 6/21/12 1:15 PM, Brandon Allbery wrote:
On Thu, Jun 21, 2012 at 5:11 AM, Rouan van Dalen
wrote: Can anyone shed some light on why the succ and pred functions of the Enum typeclass throw exceptions if we go over the upper or lower boundary, and not return Maybe a?
Enum and Bounded have a complicated and arguably incorrect[1] relationship. The whole thing should be overhauled,
Indeed. In light of the exception-throwing specification, it's not trivial to define a safe enumFromDownTo function satisfying the specification: enumFromDownTo x y == reverse (enumFromTo y x) with all the properties we'd like to have (e.g., list fusion). Essentially, we need access to whatever predicate decides to throw an error in the pred function, in order to use it to return the empty list when appropriate. The predicate can be reconstructed from Ord or from Bounded and Eq but both of those constructions make non-trivial assumptions about how the classes interact. Hence, the Enum class in incomplete, in addition to any correctness problems interacting with other classes. -- Live well, ~wren

On 21/06/2012, at 9:11 PM, Rouan van Dalen wrote:
I was hoping to have some functions like:
safeSucc :: (Enum a) => a -> Maybe a
Types that are instances of Enum don't necessarily have bounds. It always struck me as odd that Enum doesn't extend Ord. There's a reason given for not having Bounded extend Ord, which doesn't really apply to a class having fromEnum :: a -> Int. Testing whether an enum bound is at a limit is thus a bit tricky. isMaxBound, isMinBound :: (Enum t, Bounded t) => t -> Bool isMaxBound x = fromEnum x == fromEnum (maxBound `asTypeOf` x) isMinBound x = fromEnum x == fromEnum (minBound `asTypeOf` x) safeSucc, safePred :: (Enum t, Bounded t) => t -> Maybe t safeSucc x = if isMaxBound x then Nothing else Just (succ x) safePred x = if isMinBound x then Nothing else Just (pred x)

On Thu, Jun 21, 2012 at 5:36 PM, Richard O'Keefe
There's a reason given for not having Bounded extend Ord, which doesn't really apply to a class having fromEnum :: a -> Int. Testing whether an enum bound is at a limit is thus a bit tricky.
An ordering does not typically induce a computable enumeration. For example, there are infinitely many rationals between any pair of rationals.

An ordering does not typically induce a computable enumeration. For example, there are infinitely many rationals between any pair of rationals.
I didn't say it was odd that Ords weren't Enums, I said that it's odd that Enums aren't Ords. It makes little or no sense to make treat rationals as Enums; the intent of enums is generally to provide *exhaustive* enumeration of a *discrete* set.

I hit reply instead of reply all. Sorry Richard.
On Fri, Jun 22, 2012 at 4:35 PM,
An ordering does not typically induce a computable enumeration. For example, there are infinitely many rationals between any pair of rationals.
I didn't say it was odd that Ords weren't Enums, I said that it's odd that Enums aren't Ords.
You said: "It always struck me as odd that Enum doesn't extend Ord." Ambiguous, at best. In any case, the order induced by the enumeration of the rationals is not compatible with the magnitude/sign order either. This is typically true.
It makes little or no sense to make treat rationals as Enums; the intent of enums is generally to provide *exhaustive* enumeration of a *discrete* set.
I don't see that in the documentation anywhere, and "enumerable" is synonymous with countable/computable (depending on the context). The usual topology on the structure has nothing to do with its enumerability. The set of pairs of positive integers is "discrete" under the obvious product topology. Indeed, the "standard" enumeration is (almost) formally equivalent to that of the positive rationals. The only difference is we aren't skipping over the diagonal. Enumerating the rationals is straight-forward. http://www.cs.ox.ac.uk/jeremy.gibbons/publications/rationals.pdf
participants (7)
-
Alexander Solla
-
Brandon Allbery
-
Francesco Mazzoli
-
ok@cs.otago.ac.nz
-
Richard O'Keefe
-
Rouan van Dalen
-
wren ng thornton