module Data.Bits

Manuel M T Chakravarty chak@cse.unsw.edu.au
Tue, 10 Sep 2002 15:55:50 +1000 (EST)


Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> wrote,

> Alastair Reid <alastair@reid-consulting-uk.ltd.uk> writes:
> 
> > > The FFI spec says that the operations called 'shift' and 'rotate',
> > > shift and rotate their argument to the right.  However, the GHC
> > > implementation in CVS shifts and rotates to the left, and is
> > > documented to do so.
[..]
> > This makes the specification come out nice and clean - you're
> > multiplying the number by 2^n instead of 2^{-n}.
> 
> Errm, but then right shift comes out as dividing by 2^{-n}, instead
> of 2^n.  For a unified shift operation, I don't think there is any
> good reason to prefer one direction over the other, since there is
> no precedent in another language (AFAIK).

I have no idea why I did it other than in GHC's libs.  I
think, it is a typo, because my intention was to duplicate
the Bits interface of GHC's libs.  So, I would propose to
change the FFI spec.  The main reason being that there is
already plenty of code which relies on the current
definition in GHC's Bits and there is no good reason to
break that code.  Objections?

> However, while I'm on the subject, I'd like to request that the operations
> 
>     shiftL, shiftR,    -- :: a -> Int -> a
>     rotateL, rotateR,  -- :: a -> Int -> a
> 
> should become members of the class, with new default implementations
> 
>     x `shift`   i  | i<0  = x `shiftL` i
>                    | i==0 = x
>                    | i>0  = x `shiftR` i
>     x `rotate`  i  | i<0  = x `rotateL` i
>                    | i==0 = x
>                    | i>0  = x `rotateR` i
> 
>     x `shiftL`  i  = x `shift`  (-i)
>     x `shiftR`  i  = x `shift`  i
>     x `rotateL` i  = x `rotate` (-i)
>     x `rotateR` i  = x `rotate` i
> 
> (or with the directions the other way round if you insist.)
> 
> As I already noted, languages such as C provide only left and right
> shift (with no unified variant), and it would be nice to have the
> ability to override the default implementations of shiftL etc for
> specific types where we can call C directly.  At the moment, a right
> shift turns into two negations in Haskell followed by the primitive
> call, and I'd like to squeeze the extra efficiency in if I can.

The FFI Addendum actually doesn't commit to which operations
are in the class.  It just says defines all these ops to
have a context `Bits a', which is definitely the case.  In
other words, you proposed implementation is valid by the
spec and your argument for it makes sense to me.

Cheers,
Manuel