[Haskell-cafe] instance Enum Double considered not entirely great?

Roman Leshchinskiy rl at cse.unsw.edu.au
Thu Sep 29 00:50:15 CEST 2011

On 28/09/2011, at 23:23, Ivan Lazar Miljenovic wrote:

> On 29 September 2011 07:56, Roman Leshchinskiy <rl at cse.unsw.edu.au> wrote:
>> On 25/09/2011, at 18:20, Chris Smith wrote:
>>> class Ord a => Range a where
>>>    rangeFromTo :: a -> a -> [a] -- subsumes Ix.range / Enum.enumFromTo
>>>    rangeFromThenTo :: a -> a -> a -> [a]
>>>    inRange   :: (a, a) -> a -> Bool
>>> -- Does have instances for Float/Double.  List ranges desugar to this.
>>> -- Also has instances for tuples
>>> class Range a => InfiniteRange a where -- [1]
>>>    rangeFrom :: a -> [a]
>>>    rangeFromThen :: a -> a -> [a]
>>> -- Has instances for Float/Double
>>> -- No instances for tuples
>> I realise I'm slightly late to the discussion but IMO, the rangeFrom* (or enumFrom*) functions shouldn't be methods. Rather, a redesign of Enum should ensure that they can be defined generically for all types. The rationale is that other data structures (like arrays) want to provide similar functions without having to go through lists.
> Wouldn't this require something like the ListLike class?

Not at all. You could have something like:

class Enum a where
  enumFromToSize :: a -> a -> Integer
  advance :: a -> Integer -> a

And then [x..y] would desugar to map (advance x) (enumFromTo_Integer 0 $ enumFromToSize x y) where enumFromTo_Integer would be primitive. Of course, it's possible to design a much more efficient interface but this should give a general idea. An added benefit would be that you could generate the sequence in parallel (which is quite crucial for, e.g., DPH). Basically, the requirements would be that you can get the size of a range and compute the nth element of a range (or, equivalently, split the range) in constant time. Are there any Enum instances which don't satisfy this (apart from the broken floating point instances which *could* satisfy this)?

As it stands, none of the array libraries that I've participated in designing and writing can use the Enum class properly (or, in the case of DPH, at all). For instance, vector has 230 lines of code (including comments) and 16 rules to implement enumFromTo (the vector version) halfway efficiently when the element type is known statically. I haven't bothered with enumFromThenTo so far. Interestingly, GHC's *list* library has to jump through similar hoops to make enumFromTo and enumFromThenTo work with foldr/build fusion (again, only when the element type is known statically). IMO, making enumFromThen and friends into methods just doesn't work, not even for lists really.


More information about the Haskell-Cafe mailing list