Proposal: Don't require users to use undefined
Bas van Dijk
v.dijk.bas at gmail.com
Tue Oct 26 12:15:11 EDT 2010
Dear all,
Users of the sizeOf or alignment methods (:: a -> Int) of the Storable
class are pushed to use 'undefined' in their programs. Take the
following function from Foreign.Marshal.Alloc as an example:
malloc :: Storable a => IO (Ptr a)
malloc = doMalloc undefined
where
doMalloc :: Storable b => b -> IO (Ptr b)
doMalloc dummy = mallocBytes (sizeOf dummy)
I find the use of 'undefined' ugly; its only purpose is to help the
type-checker by carrying around a type variable. It also makes the job
of an optimizing compiler harder because, in order to avoid generating
unnecessary code, the compiler needs to find out if undefined isn't
used. More importantly however, 'undefined' is dangerous; The
type-checker will never complain when you accidentally use 'undefined'
in the wrong place increasing the change that your program will crash.
Also, instance writers for the Storable class need to be careful not
to evaluate the argument of sizeOf because it may be undefined.
The use of 'undefined' is not only required by the Storable class.
Users of the HasResolution class from Data.Fixed also need to use
'undefined' in order to get the resolution of a fixed value:
class HasResolution a where
resolution :: p a -> Integer
I would like to propose solving this. My proposal consists of 3 sub-proposals:
1) Add module Data.Tagged.
2) Modify the sizeOf and alignment methods of the Storable class.
3) Modify the HasResolution class.
What follows are more detailed explanations of the proposals:
1) Add module Data.Tagged.
My proposal is to move the Data.Tagged module from Edward A. Kmett's
tagged package to base.
See: http://hackage.haskell.org/package/tagged
The only modification that needs to be done is to drop the Default
instance for Proxy because this will otherwise require that
Data.Default be moved to base as well which isn't my intention. When
this proposal is accepted Data.Default can provide the instance
instead.
2) Modify the sizeOf and alignment methods of the Storable class.
I would like to replace the following:
class Storable a where
sizeOf :: a -> Int
alignment :: a -> Int
with:
class Storable a where
sizeOf :: SizeOf a
alignment :: Alignment a
type SizeOf a = Tagged a Int
type Alignment a = Tagged a Int
To retrieve the actual size of type 'a' use:
untag (sizeOf :: SizeOf a)
where: untag :: Tagged s b -> b from Data.Tagged.
See the following for the haddock documentation:
http://code.haskell.org/~basvandijk/doc/ghc/html/libraries/base-4.3.0.0/Foreign-Storable.html
Here's the definition of the previous malloc function to give you an
impression how code looks when my proposals are accepted:
malloc :: forall a. Storable a => IO (Ptr a)
malloc = mallocBytes (untag (sizeOf :: SizeOf a))
(Note that this does require the ScopedTypeVariables language extension.)
3) Modify the HasResolution class.
I would like to modify the HasResolution class in the same way. So replacing:
class HasResolution a where
resolution :: p a -> Integer
with:
class HasResolution a where
resolution :: Resolution a
type Resolution a = Tagged a Integer
See the following for the haddock documentation:
http://code.haskell.org/~basvandijk/doc/ghc/html/libraries/base-4.3.0.0/Data-Fixed.html
Note that Fixed also gets a HasResolution instance:
instance HasResolution a => HasResolution (Fixed a) where
resolution = retag (resolution :: Resolution a)
where: retag :: Tagged s b -> Tagged t b from Data.Tagged.
There's a possible 4th proposal that I'm thinking about: The Bits
class from Data.Bits has the bitSize :: a -> Int method. Maybe it
would be a good idea to replace that as well with:
bitSize :: BitSize a; type BitSize a = Tagged a Int
However I think bitSize is more often applied to an actual value than
to 'undefined' so I need to investigate that a little further.
A patch for the base package is attached to the ticket. I also
attached patches for the ghc compiler, bytestring, binary, vector and
dph. The latter are just some packages that were inside my ghc
repository. This email is CCed to the maintainers of these packages.
Deadline: 3 weeks from now (Tuesday 16 November 2010) but I will shift
it when the discussion demands it.
Ticket: http://hackage.haskell.org/trac/ghc/ticket/4443
Regards,
Bas
More information about the Libraries
mailing list