Skip to content

Commit

Permalink
Use 0 and 0x55555555 to distinguish constructors of Maybe and Either.
Browse files Browse the repository at this point in the history
Previously, 0 and 1 was used. The constant 0x55555555 is in binary
01010101010101010101010101010101.

It is simple to see that 0x55555555 = 0xFFFFFFFF `quot` 3. Therefore,
the constant is computed as (maxBound :: Word) `quot` 3, so it is 64-bit
wide on 64-bit architectures.
  • Loading branch information
foxik committed May 21, 2012
1 parent e83ab4e commit 903a0bb
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions Data/Hashable.hs
Expand Up @@ -212,17 +212,24 @@ instance Hashable Double where

instance Hashable Char where hash = fromEnum

-- | A value with bit pattern (01)* (or 5* in hexa), for any size of Int.
-- It is used as data constructor distinguisher. GHC computes its value during
-- compilation.
distinguisher :: Int
distinguisher = fromIntegral $ (maxBound :: Word) `quot` 3
{-# INLINE distinguisher #-}

instance Hashable a => Hashable (Maybe a) where
hash Nothing = 0
hash (Just a) = 1 `hashWithSalt` a
hash (Just a) = distinguisher `hashWithSalt` a
hashWithSalt s Nothing = s `combine` 0
hashWithSalt s (Just a) = s `combine` 1 `hashWithSalt` a
hashWithSalt s (Just a) = s `combine` distinguisher `hashWithSalt` a

instance (Hashable a, Hashable b) => Hashable (Either a b) where
hash (Left a) = 0 `hashWithSalt` a
hash (Right b) = 1 `hashWithSalt` b
hash (Right b) = distinguisher `hashWithSalt` b
hashWithSalt s (Left a) = s `combine` 0 `hashWithSalt` a
hashWithSalt s (Right b) = s `combine` 1 `hashWithSalt` b
hashWithSalt s (Right b) = s `combine` distinguisher `hashWithSalt` b

instance (Hashable a1, Hashable a2) => Hashable (a1, a2) where
hash (a1, a2) = hash a1 `hashWithSalt` a2
Expand Down

0 comments on commit 903a0bb

Please sign in to comment.