Существует некая маленькая функция на С:
unsigned int str_hash(const char *p)
{
const unsigned char *s = (const unsigned char *)p;
unsigned int g, h = 0;
while (*s != '\0') {
h = (h << 4) + *s;
if ((g = h & 0xf0000000UL)) {
h = h ^ (g >> 24);
h = h ^ g;
}
s++;
}
return h;
}
с целью обучения переписал её на Haskell:
import Data.Bits as DB
import Data.Word
import Data.List as DL (foldl')
simpleHash :: [Word8] -> Int
simpleHash warr = DL.foldl' shiftFunc 0 warr
where
shiftFunc h s = ((middleTransf h) `shiftL` 4) + (fromIntegral s :: Int)
middleTransf :: Int -> Int
middleTransf arg = case (bitAnd arg) of
0 -> arg
_ -> (xorShift arg) `xor` (bitAnd arg)
where
bitAnd a = a .&. 0xf0000000
xorShift b = b `xor` ((bitAnd b) `shiftR` 24)
Вопросы:
1. Правильно ли?
2. Возможно ли сделать эту реализацию короче/нагляднее/эффективнее?
3. Возможно ли использование Prelude.foldl вместо Data.List.foldl' ?