-- -- Morton number generator -- Can be used for n-dimensional hash 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