
On Mon, 12 Feb 2001, William Lee Irwin III wrote:
It seems to me that some additional primitive types would be useful, most of all a natural number type corresponding to an arbitrary- precision unsigned integer. Apparently Integer is defined in terms of something else in the GHC Prelude, what else might be needed to define it?
It depends on the implementation and IMHO it would be bad to require a particular implementation for no reason. For example ghc uses the gmp library and does not implement Integers in terms of Naturals; gmp handles negative numbers natively.
Some of my other natural thoughts along these lines are positive reals and rationals, and nonzero integers.
You can define it yourself by wrapping not-necessarily-positive types if you feel the need. Most of the time there is no need because Haskell has no subtyping - they would be awkward to use together with present types which include negative numbers.
Further down this line, I've gone off and toyed with Bool, and discovered GHC doesn't like it much. Is there a particular place within GHC I should look to see how the primitive Boolean type, and perhaps other types are handled?
Modules with names beginning with Prel define approximately everything what Prelude includes and everything with magic support in the compiler. PrelGHC defines primops that are hardwired in the compiler, and PrelBase is a basic module from which most things begin. In particular Bool is defined there as a regular algebraic type data Bool = False | True Types like Int or Double are defined in terms of primitive unboxed types called Int# and Double#. They are always evaluated and are not like other Haskell types: they don't have the kind of the form * or k1->k2 but a special unboxed kind, their values don't include bottom. You can't have [Int#] or use Prelude.id :: Int# -> Int#. They can be present in data definitions and function arguments and results. There is more of primitive stuff: primops like +# :: Int# -> Int# -> Int#, primitive array types, unboxed tuples, unboxed constants. There is a paper about it but I don't have the URL here. They are also described in GHC User's Guide. They are not portable at all. Other Haskell implementations may use very different implementation techniques. In ghc they exist primarily to make it easy to express optimizations - these types occur all the time during internal transformations of the module being opzimized - laziness is optimized away when possible. They are often present in .hi files when a function has been split into worker and wrapper, so that code using the module can refer to the worker using primitive types directly instead of allocating every number on the heap. They are also exposed to the programmer (who imports GlaExts) who really wants to hack with them manualy. They don't have nice Haskell properties of other types (fully polymorphic operations don't work on these types) so I would not expect such thing to appear officially in the Haskell definition.
I'd also like to see where some of the magic behind the typing of various other built-in constructs happens, like list comprehensions, tuples, and derived classes.
Inside the compiler, not in libraries. -- Marcin 'Qrczak' Kowalczyk