[Haskell-cafe] A new form of newtype

Richard O'Keefe ok at cs.otago.ac.nz
Tue Dec 8 16:09:02 EST 2009


Haskell is very nearly a high level language.
One rather unpleasant way in which it lets the
the underlying machine show through is integral types.

Aside from the unbounded Integer type, which is fine,
there are integral types bounded by machine sizes:
Int, size unspecified, Data.Int.Int{8,16,32,64},
and Data.Word.Word{8,16,32,64}.

There are a number of problems with these.
The principal one is that in order to figure out which
size is needed, a programmer must do arithmetic.
I still remember a student's bitter complaint about
being required to find the base 2 logarithm of 32 in
an examination where calculators were forbidden...

I propose a small addition to 'newtype' syntax:

	'newtype' id '=' '[' expr {',' expr}... ']'
                          [deriving-part]

The expressions are Integral expressions made from
constants and suitable Prelude functions.  Each Haskell
implementation supports some sublist of the types
  [Int1,Word1,Int2,Word2,Int3,Word3,...,Int64,Word64,
   ...,Int256,Word256,...,Integral, _except
(It's almost interesting that the Natural type missing
  from Haskell would go after Integral in this list, and
  so would never be used.)
The effect of the declaration would be to make "id"
a copy of the first type in the list of supported types
that is big enough to include the value of every expression
on the right hand side, except that
	minBound = the smallest value on the right hand side
	maxBound = the largest value on the right hand side
rather than being the bounds for the underlying type.

The instances that could be derived would include
Bits, Bounded, Data, Enum, Eq, Integral, Ix, Num, Ord,
PrintfArg, Read, Real, Show, Storable, Typable.

I'd actually prefer that the default list of derived
instances be short, but it's hard to draw an arbitrary line,
so the default instances should be the same as the default
instances for Int in the same Haskell system.

Suppose I knew that I had a 2TB disc (I don't, and wish I
did) and wanted to be able to hold not only any file size
but the sums and differences of up to 10,000,000 file sizes.
(There could be one giant file, and all the file sizes
could be the size of that file.)

newtype FileSize = [-10000000*2^41,10000000*2^41]

I don't see any simple way to get named values into the
expressions defining a new integral type, but the use of cpp
with Haskell has been common practice for a long time, so

#define Tera 2^40
#define Many 10000000
newtype FileSize = [-Many*2*Tera,Many*2*Tera]

In this case, FileSize would be a copy of Integer.



More information about the Haskell-Cafe mailing list