I'm writing a routine to determine whether the high 16 bits of a 32-bit integer have more bits set, or the low bits.
In C, I would write this:
bool more_high_bits(int a) {
if ((a >> 16) == 0) return false; // no high bits
if ((a & 0xFFFF) == 0) return true; // no low bits
// clear one high bit and one low bit, and ask again
return more_high_bits(a&(a - 0x10001));
}
So in Haskell, I'm trying this:
more_high_bits a=if (a `shiftR` 16) /= 0 then 0 else
if ((.&.) a 65535) /= 0 then 1 else
more_high_bits((.&.) a (a-65537))
But it just times out.
What am I doing wrong? What's the more idiomatic way to do this? Please don't code away the shift or the & because I'd like to know how I "should" be using these.
Addendum: I tried this code out on an haskell compiler:
http://www.tutorialspoint.com/compile_haskell_online.php
import Data.Bits
g a=if (a `shiftR` 16) == 0 then 0 else
if ((.&.) a 65535) == 0 then 1 else
g((.&.) a (a-65537))
main = print (g(237))
But it tells me "No instance for (Bits a0) arising from a use of 'g' The type variable 'a0' is ambiguous"
What is "a0"??
Here's a pretty direct translation of your C code to Haskell:
import Data.Word
import Data.Bits
more_high_bits :: Word32 -> Bool
more_high_bits a
| (a `shiftR` 16) == 0 = False
| (a .&. 0xFFFF) == 0 = True
| otherwise = more_high_bits (a .&. (a - 0x10001))
Your attempt has /= where the C version has ==, which inverts the condition.
a0 is the type variable that the type checker automatically created for your use of g 237. It doesn't know which type you mean because 237 could be any numeric type at all, and g works with all numbers that support bitwise operations and equality. The list of types you could have meant includes (but is not limited to) Int, Integer, Word, ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With