tags:

views:

134

answers:

2

I would like to add deriving (Data) to standard types. After enabling the StandaloneDeriving, FlexibleContexts, DeriveDataTypeable, and UndecidableInstances extensions, ghc accepts

deriving instance Data Day => Data (Day)

However, if I do the same thing for DiffTime I get

TemperatureRecord.hs:30:0:
    The data constructors of `DiffTime' are not all in scope
      so you cannot derive an instance for it
    In the stand-alone deriving instance for
      `(Data DiffTime) => Data (DiffTime)'

I am doing all this to help autogenerate binary instances of standard types. So I have two questions:

  1. How do I solve the error I am getting with DiffTime, and
  2. What is the right way to make standard library types binary serializable in Haskell?
+3  A: 

The time package does not expose MkDiffTime, DiffTime's constructor.

To create a Data instance, you would normally work with the type's constructors. Even if you are automatically deriving it, that's what the derived instance would do as well.

Luckily, this could be worked around, to some extent. You can extract the data from a DiffTime using toRational, and you can wrap a number in a DiffTime using fromRational. So it should be possible to "fake" a Data instance with a "fake" constructor. This would be done "manually" (no deriving).

As to why the constructor of DiffTime isn't exposed - this would be similar to the reasoning behind private in C++ et al. This gives the creators of DiffTime the freedom to change its implementation without breaking anything. Indeed, if they would change the structure, it won't break your "fake" Data instance and will not break your serialization format.

yairchu
A: 

I am a haskell newb, but I think you can do this to expose the constructor (and thus automatically derived Data)

cabal unpack time

change

newtype DiffTime = MkDiffTime Pico deriving (Eq,Ord

to

data DiffTime = MkDiffTime Pico deriving (Eq,Ord

and cabal install seems to work

Greg