Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Instance of Data.Data needed #13

Closed
bos opened this Issue · 4 comments

3 participants

@bos

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.

@tibbe
Owner

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.

@hvr

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 #-}
+{-# 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
@tibbe
Owner

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.

@tibbe
Owner

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.