Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Instance of Data.Data needed #13

bos opened this Issue · 4 comments

3 participants


In order to be able to do a generic fold over a HashMap, I need a Data instance.

instance (Data k, Data v, Eq k, Hashable k) => Data (HashMap k v) where
  gfoldl f z m   = z fromList `f` toList m
  toConstr _     = error "toConstr"
  gunfold _ _    = error "gunfold"
  dataTypeOf _   = mkNoRepType "Data.HashMap.HashMap"
  dataCast2 f    = gcast2 f

We'll have to move some code around in order to make this work: it's fine for the instance to be defined using the lazy version of fromList, but we need the instance definition to live in a place where it can be imported into, then exported from, both the Strict and Lazy modules.


I don't have time to work on this at the moment, but patches are welcome. So far I've put shared code in Data/HashMap/Common.hs.


Here are quick'n'dirty Data instance based on the Data instances from the containers package I hacked up some time ago...

But I'm not posting a pull-request, as I'm not sure whether these Data instances are actually correct; more specifically, I don't know what the semantics of Data instances for container data structures with internal invariants are supposed to be...

See also Neil's related blog posting

diff --git a/Data/HashMap/Lazy.hs b/Data/HashMap/Lazy.hs
index 2840553..2e595f4 100644
--- a/Data/HashMap/Lazy.hs
+++ b/Data/HashMap/Lazy.hs
@@ -79,12 +79,21 @@ module Data.HashMap.Lazy
     ) where

 import qualified Data.FullList.Lazy as FL
+import Data.Data (Data(..), gcast2, mkNoRepType)
 import Data.Hashable (Hashable(hash))
 import qualified Data.List as List
 import Prelude hiding (filter, foldr, lookup, map, null, pred)

 import Data.HashMap.Common

+-- copied from 'Data.Map.Map' instance -- n.b.: orphan instance
+instance (Data k, Data v, Hashable k, Eq k) => Data (HashMap k v) where
+    gfoldl f z m   = z fromList `f` toList m
+    toConstr _     = error "toConstr"
+    gunfold _ _    = error "gunfold"
+    dataTypeOf _   = mkNoRepType "Data.HashMap.Common.HashMap"
+    dataCast2 f    = gcast2 f
 -- * Basic interface

diff --git a/Data/HashSet.hs b/Data/HashSet.hs
index 2675b4a..8e5b03a 100644
--- a/Data/HashSet.hs
+++ b/Data/HashSet.hs
@@ -1,4 +1,4 @@
+{-# LANGUAGE CPP, DeriveDataTypeable #-}

 -- |
@@ -60,9 +60,11 @@ module Data.HashSet
     ) where

 import Control.DeepSeq (NFData(..))
+import Data.Data (Data(..), gcast1, mkNoRepType)
 import Data.HashMap.Common (HashMap, foldrWithKey)
 import Data.Hashable (Hashable)
 import Data.Monoid (Monoid(..))
+import Data.Typeable (Typeable)
 import Prelude hiding (filter, foldr, map, null)
 import qualified Data.Foldable as Foldable
 import qualified Data.HashMap.Lazy as H
@@ -75,7 +77,7 @@ import GHC.Exts (build)
 -- | A set of values.  A set cannot contain duplicate values.
 newtype HashSet a = HashSet {
       asMap :: HashMap a ()
-    }
+    } deriving (Typeable)

 instance (NFData a) => NFData (HashSet a) where
     rnf = rnf . asMap
@@ -101,6 +103,14 @@ instance (Show a) => Show (HashSet a) where
     showsPrec d m = showParen (d > 10) $
       showString "fromList " . shows (toList m)

+-- copied from 'Data.Set.Set' instance
+instance (Data a, Hashable a, Eq a) => Data (HashSet a) where
+  gfoldl f z set = z fromList `f` (toList set)
+  toConstr _     = error "toConstr"
+  gunfold _ _    = error "gunfold"
+  dataTypeOf _   = mkNoRepType "Data.HashSet.HashSet"
+  dataCast1 f    = gcast1 f
 -- | /O(1)/ Construct an empty set.
 empty :: HashSet a
 empty = HashSet H.empty

I've added a Data instance for HashMap and a Typeable instance for HashSet. I'm having issues adding a Data instance for HashSet that I don't quite understand.


Added one for HashSet as well.

@tibbe tibbe closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.