Enum class

Jan-Willem Maessen jmaessen@mit.edu
Tue, 23 Oct 2001 15:06:42 -0400


Alas, it seems to me Enum is really two classes rather unfortunately
lumped together:

Correspondence with Int:

> class  Enum a  where
>   succ, pred          :: a -> a
>   toEnum              :: Int -> a
>   fromEnum            :: a -> Int

Arithmetic series-like enumeration:

> class  Enum a  where
>   enumFrom            :: a -> [a]	        -- [n..]
>   enumFromThen        :: a -> a -> [a]	-- [n,n'..]
>   enumFromTo          :: a -> a -> [a]	-- [n..m]
>   enumFromThenTo      :: a -> a -> a -> [a]	-- [n,n'..m]

Having recently had to tweak prelude definitions of all of the above,
I can personally testify that the situation is not a happy one: We
can't meaningfully define correspondence with Int for type Integer,
much less Float, Double, etc.  The default enumFrom... use toEnum on
Int sequences, and as far as I can tell are no use to anyone; Bounded
types must close off the ends of the enumeration at minBound and
maxBound, and unbounded types won't fit into an Int.  

So, what's to be done?

* In the report, give clear and explicit definitions of
  enumFrom... for Float and Double.  This could be done right now.
  The toughest part is deciding what the behavior at extremes should
  be; any behavior is bad, and so picking one with appropriate caveats
  should be just fine.  I don't foresee agreement on which bad
  behavior is appropriate.

  Definitions for the methods in the first category might be nice,
  too.  Perhaps they should signal an error.  I'm clueless as to
  whether pred and succ just add/subtract 1 or whether they ought to
  round as well.  

* Get rid of the useless (and in truth actively dangerous) default
  methods for enumFrom... and kin.  This could be done now, I think.

* Definitions of enumFrom... for Int which deal gracefully with
  overflow might be a nice addition to the report as people get them
  wrong.  The Feb. 2000 release of hugs, for example:

  Prelude> [(maxBound::Int)-2..maxBound]
  [2147483645,2147483646,2147483647,-2147483648,-2147483647,-2147483646,-2147483645,
  etc...

  [GHC appears to do it right, I have no idea about current hugs or
  nhc versions.]

* Add definitions for boundedEnumFrom... to the Prelude, or perhaps to
  a library.  This might or might not be a big change for Haskell 98;
  I forget where Simon PJ's drawn the line.  It does reflect reality,
  though.

* Split the Enum class into two.  Possibly "correspondence with Int"
  belongs in "Bounded"---but it depends what you think "Bounded"
  means.  Int64 and Word probably don't fit the model too well.  In any
  case, this can't really be a revision to Haskell 98; it needs to be
  thought about in future Haskell versions.

What say others?  Is this sensible?  Or have I let my recent
frustrations take hold?

-Jan-Willem Maessen
Eager Haskell Project
jmaessen@mit.edu