Don't require users to use undefined
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:
- Add module
Data.Tagged
. - Modify the
sizeOf
andalignment
methods of theStorable
class. - Modify the
HasResolution
class.
What follows are more detailed explanations of the proposals:
Data.Tagged
Add module My proposal is to move the Data.Tagged
module from Edward A. Kmett's tagged package to base
.
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.
sizeOf
and alignment
methods of the Storable
class
Modify the 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.
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.)
HasResolution
class
Modify the 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.
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
.
bitSize
?
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.
Patches
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.
Deadline
3 weeks from now (Tuesday 16 November 2010) but I will shift it when the discussion demands it.
Trac metadata
Trac field | Value |
---|---|
Version | 6.12.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/base |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |