Proposal: Don't require users to use undefined

Bas van Dijk v.dijk.bas at gmail.com
Wed Oct 27 01:51:33 EDT 2010


On Tue, Oct 26, 2010 at 9:09 PM, Henning Thielemann
<lemming at henning-thielemann.de> wrote:
>
> On Tue, 26 Oct 2010, Bas van Dijk wrote:
>
>> malloc :: forall a. Storable a => IO (Ptr a)
>> malloc = mallocBytes (untag (sizeOf :: SizeOf a))
>>
>> (Note that this does require the ScopedTypeVariables language extension.)
>
> Haskell 98 solution would be nicer. Something like
>
>> malloc :: Storable a => IO (Ptr a)
>> malloc =
>
>     let aux :: Storable a => SizeOf a -> IO (Ptr a)
>         aux = mallocBytes . untag
>     in  aux sizeOf

Great! It's nice to know that this proposal doesn't require ScopedTypeVariables.


>> 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.
>
> RealFloat class also provides a lot of examples that could be adapted to the
> Tagged scheme.

I see if I can include them in this proposal as well.


> Since all of the affected modules are quite basic, this would break a lot of
> code. Thus I would propose a less invasive path:
>
> 1. Add functions that provide the Tagged interface and implement them using
> 'sizeOf' and 'alignment'.
>
> 2. Add functions that convert a sizeOfTagged and alignmentTagged function to
> 'sizeOf' and 'alignment' in order to allow Storable instance declaration,
> that not need to cope with undefined.

I agree that we should provide a comfortable upgrade path. With
respect to 1 and 2, what about putting them inside the Storable class
and defining them in terms of eachother:

-- | Minimal complete definition: either sizeOf or sizeOfTagged, ...
class Storable a where
  {-# DEPRECATE sizeOf "use sizeOfTagged instead" #-}
  sizeOf :: a -> Int
  sizeOf _ = untag (sizeOfTagged :: SizeOf a)

  sizeOfTagged :: SizeOf a
  sizeOfTagged = Tagged $ sizeOf (undefined :: a)

  {-# DEPRECATE alignment "use alignmentTagged instead" #-}
  alignment :: a -> Int
  alignment _ = untag (alignmentTagged :: SizeOf a)

  alignmentTagged :: SizeOf a
  alignmentTagged = Tagged $ alignment (undefined :: a)

I don't like the name 'sizeOfTagged' though. The name I like best is
just 'size :: SizeOf a'. However this is not going to work for
'alignmentTagged' because we already have 'alignment'. Any other
ideas?


> 3. Document how to use the Tagged types with Haskell 98.

Will do. Thanks for the example.


> 4. In the future you may deprecate the immediate use of 'sizeOf' and
> 'alignment'.

We could deprecate sizeOf immediately in favor of sizeOfTagged.
Deprecating it doesn't break any code but does gives warnings so that
users are encouraged to upgrade. I don't see a reason to wait.

Thanks,

Bas


More information about the Libraries mailing list