Hello,

Attached is my new and improved patch to add a Data instance to Data.Text. The patch just adds:

+-- This instance preserves data abstraction at the cost of inefficiency.
+-- We omit reflection services for the sake of data abstraction.
+
+instance Data Text where
+  gfoldl f z txt = z pack `f` (unpack txt)
+  toConstr _     = error "toConstr"
+  gunfold _ _    = error "gunfold"
+  dataTypeOf _   = mkNoRepType "Data.Text.Text"


Which is based on what the Data instances for Set and Map do:

http://www.haskell.org/ghc/docs/latest/html/libraries/containers-0.3.0.0/src/Data-Set.html
http://www.haskell.org/ghc/docs/latest/html/libraries/containers-0.3.0.0/src/Data-Map.html

Yay for cargo culting!

It seems like this is better than nothing, possibly the correct answer, and if someone does decide to add better instances for toConstr and gunfold in the future, nothing should break? For happstack-data, I think we only need dataTypeOf. 

The instance I posted before definitely did not have valid toConstr / gunfold instances, so I think we would have noticed if we were actually trying to use them..

- jeremy

On Fri, Jan 22, 2010 at 4:24 PM, Jeremy Shaw <jeremy@n-heptane.com> wrote:
Hello,

Would it be possible to get a Data instance for Data.Text.Text? This would allow us to create a Serialize instance of Text for use with happstack -- which would be extremely useful.

We (at seereason) are currently using this patch:

http://src.seereason.com/haskell-text-debian/debian/patches/add_Data_instance.patch

which basically adds:

+textType = mkStringType "Data.Text"
+
+instance Data Text where
+   toConstr x = mkStringConstr textType (unpack x)
+   gunfold _k z c = case constrRep c of
+                     (CharConstr x) -> z (pack [x])
+                     _ -> error "gunfold for Data.Text"
+   dataTypeOf _ = textType
+

This particular implementation avoids exposing the internals of the Data.Text type by casting it to a String in toConstr and gunfold. That is similar to how Data is implemented for some numeric types. However, the space usage of casting in Float to a Double is far less than casting a Text to a String, so maybe that is not a good idea?

Alternatively, Data.ByteString just does 'deriving Data'. However, bytestring also exports Data.ByteString.Internal, wheres Data.Text.Internal is not exported.

Any thoughts? I would like to get this handled upstream so that all happstack users can benefit from it.

- jeremy