Copyright | (c) Milan Straka 2010 (c) Johan Tibell 2011 (c) Bryan O'Sullivan 2011 2012 |
---|---|
License | BSD-style |
Maintainer | johan.tibell@gmail.com |
Stability | provisional |
Portability | portable |
Safe Haskell | None |
Language | Haskell98 |
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.
Type Classes
liftHashWithSalt :: (Int -> a -> Int) -> Int -> t a -> Int #
Lift a hashing function through the type constructor.
liftHashWithSalt :: (Generic1 t, GHashable One (Rep1 t)) => (Int -> a -> Int) -> Int -> t a -> Int #
Lift a hashing function through the type constructor.
Hashable1 [] # | |
Hashable1 Maybe # | |
Hashable1 Identity # | |
Hashable1 Fixed # | |
Hashable1 Hashed # | |
Hashable a => Hashable1 (Either a) # | |
Hashable a1 => Hashable1 ((,) a1) # | |
Hashable1 (Proxy *) # | |
(Hashable a1, Hashable a2) => Hashable1 ((,,) a1 a2) # | |
Hashable a => Hashable1 (Const * a) # | |
(Hashable a1, Hashable a2, Hashable a3) => Hashable1 ((,,,) a1 a2 a3) # | |
(Hashable1 f, Hashable1 g) => Hashable1 (Sum * f g) # | |
(Hashable1 f, Hashable1 g) => Hashable1 (Product * f g) # | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4) => Hashable1 ((,,,,) a1 a2 a3 a4) # | |
(Hashable1 f, Hashable1 g) => Hashable1 (Compose * * f g) # | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5) => Hashable1 ((,,,,,) a1 a2 a3 a4 a5) # | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5, Hashable a6) => Hashable1 ((,,,,,,) a1 a2 a3 a4 a5 a6) # | |
liftHashWithSalt2 :: (Int -> a -> Int) -> (Int -> b -> Int) -> Int -> t a b -> Int #
Lift a hashing function through the binary type constructor.
Hashable2 Either # | |
Hashable2 (,) # | |
Hashable a1 => Hashable2 ((,,) a1) # | |
Hashable2 (Const *) # | |
(Hashable a1, Hashable a2) => Hashable2 ((,,,) a1 a2) # | |
(Hashable a1, Hashable a2, Hashable a3) => Hashable2 ((,,,,) a1 a2 a3) # | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4) => Hashable2 ((,,,,,) a1 a2 a3 a4) # | |
(Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5) => Hashable2 ((,,,,,,) a1 a2 a3 a4 a5) # | |
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