Copyright | (c) Milan Straka 2010 (c) Johan Tibell 2011 (c) Bryan O'Sullivan 2011 2012 |
---|---|
License | BSD-3-Clause |
Maintainer | johan.tibell@gmail.com |
Stability | provisional |
Portability | portable |
Safe Haskell | Trustworthy |
Language | Haskell2010 |
Lifting of the Hashable
class to unary and binary type constructors.
These classes are needed to express the constraints on arguments of
types that are parameterized by type constructors. Fixed-point data
types and monad transformers are such types.
Synopsis
- class Hashable1 t where
- liftHashWithSalt :: (Int -> a -> Int) -> Int -> t a -> Int
- class Hashable2 t where
- hashWithSalt1 :: (Hashable1 f, Hashable a) => Int -> f a -> Int
- hashWithSalt2 :: (Hashable2 f, Hashable a, Hashable b) => Int -> f a b -> Int
- defaultLiftHashWithSalt :: (Hashable2 f, Hashable a) => (Int -> b -> Int) -> Int -> f a b -> Int
Type Classes
Nothing
liftHashWithSalt :: (Int -> a -> Int) -> Int -> t a -> Int #
Lift a hashing function through the type constructor.
Instances
liftHashWithSalt2 :: (Int -> a -> Int) -> (Int -> b -> Int) -> Int -> t a b -> Int #
Lift a hashing function through the binary type constructor.
Instances
Hashable2 Either # | |
Defined in Data.Hashable.Class | |
Hashable2 (,) # | |
Defined in Data.Hashable.Class | |
Hashable a1 => Hashable2 ((,,) a1) # | |
Defined in Data.Hashable.Class | |
Hashable2 (Const :: Type -> Type -> Type) # | |
Defined in Data.Hashable.Class | |
(Hashable a1, Hashable a2) => Hashable2 ((,,,) a1 a2) # | |
Defined in Data.Hashable.Class | |
(Hashable a1, Hashable a2, Hashable a3) => Hashable2 ((,,,,) a1 a2 a3) # | |
Defined in Data.Hashable.Class | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4) => Hashable2 ((,,,,,) a1 a2 a3 a4) # | |
Defined in Data.Hashable.Class | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5) => Hashable2 ((,,,,,,) a1 a2 a3 a4 a5) # | |
Defined in Data.Hashable.Class |
Auxiliary Functions
hashWithSalt1 :: (Hashable1 f, Hashable a) => Int -> f a -> Int #
Lift the hashWithSalt
function through the type constructor.
hashWithSalt1 = liftHashWithSalt hashWithSalt
hashWithSalt2 :: (Hashable2 f, Hashable a, Hashable b) => Int -> f a b -> Int #
Lift the hashWithSalt
function through the type constructor.
hashWithSalt2 = liftHashWithSalt2 hashWithSalt hashWithSalt
defaultLiftHashWithSalt :: (Hashable2 f, Hashable a) => (Int -> b -> Int) -> Int -> f a b -> Int #
Lift the hashWithSalt
function halfway through the type constructor.
This function makes a suitable default implementation of liftHashWithSalt
,
given that the type constructor t
in question can unify with f a
.
Motivation
This type classes provided in this module are used to express constraints
on type constructors in a Haskell98-compatible fashion. As an example, consider
the following two types (Note that these instances are not actually provided
because hashable
does not have transformers
or free
as a dependency):
newtype WriterT w m a = WriterT { runWriterT :: m (a, w) } data Free f a = Pure a | Free (f (Free f a))
The Hashable1
instances for WriterT
and Free
could be written as:
instance (Hashable w, Hashable1 m) => Hashable1 (WriterT w m) where liftHashWithSalt h s (WriterT m) = liftHashWithSalt (liftHashWithSalt2 h hashWithSalt) s m instance Hashable1 f => Hashable1 (Free f) where liftHashWithSalt h = go where go s x = case x of Pure a -> h s a Free p -> liftHashWithSalt go s p
The Hashable
instances for these types can be trivially recovered with
hashWithSalt1
:
instance (Hashable w, Hashable1 m, Hashable a) => Hashable (WriterT w m a) where hashWithSalt = hashWithSalt1 instance (Hashable1 f, Hashable a) => Hashable (Free f a) where hashWithSalt = hashWithSalt1