There's been quite a bit of mail about the Int vs Integer thing.
Here's what I conclude:

* Integer should be the *default* integral type.  That is, if you
say (length xs > length ys), where the type at which length is computed
is ambiguous, then that type should default to Integer.

* The Int type should continue to exist, unchanged.  It is efficient, but 
silently overflows.  Haskell 2 might well introduce Int32 etc
to be more specific about precision, but that's for the future.

* But note that since length is (proposed to be) overloaded, you can
still compute length at type Int if you want.

* It's possible to implement Haskell's Integer type considerably
more efficiently than (e.g.) GHC does.


I am completely un-worried about the efficiency issue, partly
because you can still use Int if you want, and partly because
Integer will be much more efficient than now.  


Overloading
~~~~~~~~~~~
I think there is one powerful argument for retaining the status quo,
but it is one no one has commented on: overloaded types can give
rise to strange error messages that bite beginners.  After all,
we have just *un-overloaded* map and friends for just this reason.

I don't know how to evaluate this issue.  But I have looked through
past Haskell mail.  length used to have an overloaded type, and the
reason we changed it to an Int result was (completely-unquantified)
efficiency worries, not that people were getting confusing error messages.


What to generalise
~~~~~~~~~~~~~~~~~~
Simon Thompson points out, correctly, that there are other uses
of Int in the Prelude that should arguably be overloaded too, if we
are to be consistent.  The complete list is this:

        length           :: [a] -> Int
        splitAt                  :: Int -> [a] -> ([a],[a])
        drop                   :: Int -> [a] -> [a]
        take                   :: Int -> [a] -> [a]
        replicate        :: Int -> a -> [a]

        (!!)                :: [a] -> Int -> a

        class  Enum a  where
            toEnum           :: Int -> a
            fromEnum         :: a -> Int
                ...

        class  (RealFrac a, Floating a) => RealFloat a  where
            floatRadix       :: a -> Integer
            floatDigits      :: a -> Int
            floatRange       :: a -> (Int,Int)
            decodeFloat      :: a -> (Integer,Int)
            encodeFloat      :: Integer -> Int -> a
            exponent         :: a -> Int
            scaleFloat       :: Int -> a -> a
                ...

I think we should

        - generalise length, splitAt, drop, take, replicate
        - generalise toEnum, fromEnum
        - leave (!!) alone (arrays must fit in an address space)

I don't know what to do about RealFloat. Sigh

Simon


Reply via email to