[Haskell] new "primitive" instances of Data?

Ralf Laemmel ralf at cwi.nl
Thu Jan 29 19:10:34 EST 2004

>I'm in the process of trying to write generic binary serialization code
>using the "Scrap Your Boilerplate" method.  One bump I've run into is that
>there are no instances of Data provided for the extended set of numeric
>types (the stuff in Data.Word, etc.) and it seems to be impossible to
>hand-write an instance that behaves similarly to the instances for other
>primitive types.  Any ideas for ways around this?

as a basis for disucssion I propose bit serialisation as in:

alternatively, the inner workings of normal read and show are inspiring too:

Your problem seems to refer to instances like the following:

-- Another basic datatype instance
instance Data Integer where
  toConstr x = IntegerConstr x
  fromConstr (IntegerConstr x) = x
  dataTypeOf _ = IntegerType

This GHC 6.2 library instance indeed relies on a CWA
as far as basic datatypes are conveniently supported.
This is your problem, isn't it.

Let me also show the CWA datatype here for convenience:

-- | Representation of constructors
data Constr =
	-- The prime case for proper datatype constructors
	       DataConstr ConIndex String Fixity

	-- Provision for built-in types
	    | IntConstr     Int
	    | IntegerConstr Integer
	    | FloatConstr   Float
	    | CharConstr    Char

	-- Provision for any type that can be read/shown as string
	    | StringConstr  String

	-- Provision for function types
	    | FunConstr

              deriving (Show, Typeable)

This CWA is there because it allows us to map types to constructors
and to go back without inefficient or imprecise conversion. It is basically
there for an optimisation. It can be bypassed without problems.

That is, there seem to be two ways to handle the problem you have:

a) Go via read and show for all the various types such as in:
(from Data.Generics.Basics again)

-- A basic datatype without a specific branch in Constr
instance Data Rational where
  toConstr x = StringConstr (show x)
  fromConstr (StringConstr x) = read x
  dataTypeOf _ = StringType

(You can also use other functions that show and read of course.)

b) Use type extension via mk? and ext? combinators as in generic read:
(from Data.Generics.Text again)

gread = readP_to_S gread'


  gread' :: Data a => ReadP a
  gread' = gdefault `extR` scase


    -- A specific case for strings
    scase :: ReadP String
    scase = readS_to_P reads

    -- The generic default for gread
    -- gdefault :: Data a => ReadP a
    gdefault = ...

Please let me know if you need further help.
Simon PJ and I have a draft which explains all this
but it is too clumsy to release yet :-)

All the best,

Ralf Laemmel
VU & CWI, Amsterdam, The Netherlands

More information about the Haskell mailing list