module Data.DimensionalHash
(
MortonNumber(..)
) where
import Data.Bits
import Data.Int
import Data.Word
takeBitAt :: (Bits a) => a -> Int -> a
takeBitAt x n = x .&. (shift 1 n)
shiftElements :: (Bits a) => [a] -> Int -> [a]
shiftElements [] n = []
shiftElements (x:xs) n = [(shift x n)] ++ (shiftElements xs (n+1))
concatBits :: (Bits a) => [a] -> Int -> a
concatBits list n = foldl (\acc x -> acc .|. x) 0 shiftedMap
where
shiftedMap = shiftElements mapList n
mapList = map (\x -> (takeBitAt x n)) list
hash :: (Bits a) => [a] -> Int -> Int -> a
hash list n precision
| n < precision = (concatBits list n) .|. (hash list (n + 1) precision)
| otherwise = concatBits list precision
class (Bits a) => (MortonNumber a) where
dimensionalHash :: (Bits a) => [a] -> a
dimensionalHash list = hash list 0 (bitSize (head list))
instance MortonNumber Integer where
dimensionalHash list = hash list 0 32
instance MortonNumber Int8
instance MortonNumber Int32
instance MortonNumber Int64
instance MortonNumber Word
instance MortonNumber Word8
instance MortonNumber Word16
instance MortonNumber Word32
instance MortonNumber Word64