Bit shifting limitations

Edward Kmett ekmett at
Mon Jul 14 05:53:12 UTC 2014

FWIW- this is actually the behavior for shiftL.

It should just 'do the right thing' for over-shifting, in that it just
keeps shifting, resulting in

For shiftR we work that way, but there is apparently a cut and paste error
in the haddocks that makes shiftR have the warning from unsafeShiftR that
its behavior on overflow is undefined.

>>> unsafeShiftR 1 1000000 :: Int


This stays put because 1000000 `mod` 64 = 0, while

>>> shiftR 1 1000000 :: Int


saturates as you'd expect from:

>>> unsafeShiftL 1 1000000 :: Int


>>> shiftL 1 1000000 :: Int

The fact that we work modulo the integer size for unsafeShiftL/unsafeShiftR
is very much platform specific though and its left deliberately
unspecified, as the current unsafeShiftL and unsafeShiftR are intended for
use in scenarios where the cost of the branch would be prohibitive, so
over-constraining their implementation would be quite bad.

The intention of the current specification should be that shiftR and shiftL
just shift and keep on shifting even if you give a number that is too big,
while unsafeShiftR and unsafeShiftL do undefined platform specific stuff
when you give them a number out of range, usually this will be the modular
shift that you get from the native instruction.

This way you can use unsafeShiftL and unsafeShiftR when you know the
argument is in range.

We should definitely fix the documentation for shiftR though. That it
claims to be undefined on over-shifting is just wrong.


On Sun, Jul 13, 2014 at 3:50 PM, David Feuer <david.feuer at> wrote:

> That may be reasonable. I think it likely makes more sense than making the
> type of shift depend on the type of number, anyway.
> On Jul 13, 2014 3:43 PM, "Henning Thielemann" <
> schlepptop at> wrote:
>> Am 13.07.2014 20:36, schrieb David Feuer:
>>  3. I would like to add explicit arithmetic and logical shifts to
>>> Data.Bits. When fiddling bits, it's often easier to think about that
>>> distinction explicitly, rather than in terms of whether the type is
>>> signed or unsigned, and more convenient to have an explicit operation
>>> rather than casting around.
>> What kind of data do you have in mind, where both signed and unsigned
>> shifts make sense?
>> So far, I'd say, that calling "asr" on Word and "lsr" on Int should be a
>> type error.
> _______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list