Hi,

Continuing on my project I have hit another hurdle.

Summarizing this is what I have been tring to do. Using System.Directory.Tree to traverse a directory tree and build a DirTree of type Props where Props are

data Props = Prop { md5sum :: MD5Digest, modTime :: ClockTime, filenam::FilePath }
           | Blank        deriving (Show, Eq, Typeable)  -- , Data

I am trying to capture the md5sum and time. Next I wanted to serialize this structure to disk for comparison at a later invocation.

I got stuck trying to serialize DirTree using Data.Binary and encode because DirTree has a field of type Exception which does not derive from Binary/Data which is required for serialization. I felt that using "deriving instance " could solve the problem but I don't understand that mechanism well enough to solve my problem. How ever an alternative was suggested and this is what I did. It is in-elegant but sort of works.

I defined a alternate private DirTreeW which mirrors the DirTree except that the Exception is converted to a String. The data type is defined below

data DirTreeW a = DirW { name     :: FileName,
                       contents :: [DirTreeW a]  }
               | FileW { name :: FileName,
                        file :: a }
               | FailedW { name :: FileName,
                          err  :: String }
                 deriving (Show, Eq, Typeable, Data)

I then wrote a function to convert a DirTree to this type.

convert (Dir a b) = DirW a $ map convert b
convert (File a b) = FileW a b
convert (Failed a e) = FailedW a "some error"

This version of DirTree I can serialize. However a DirTreeW of type Props fails to serialize because of the MD5Digest and ClockTime. I tried deriving Props from  Data but that fails with the following error.

*BinaryDerive Data.Binary Data.Digest.Pure.MD5> :r
[2 of 2] Compiling Main             ( dir-recurse.hs, interpreted )
Ok, modules loaded: BinaryDerive, Main.
*Main Data.Binary Data.Digest.Pure.MD5> :r
[2 of 2] Compiling Main             ( dir-recurse.hs, interpreted )

dir-recurse.hs:16:56:
    No instances for (Data MD5Digest, Data ClockTime)
      arising from the 'deriving' clause of a data type declaration
                   at dir-recurse.hs:16:56-59
    Possible fix:
      add an instance declaration for (Data MD5Digest, Data ClockTime)
      or use a standalone 'deriving instance' declaration instead,
         so you can specify the instance context yourself
    When deriving the instance for (Data Props)
Failed, modules loaded: BinaryDerive.

It seems to suggest that md5 and clocktime are not derived from Data and hence I cannot derive Props from Data. Please suggest on a way forward. I would appreciate pointers on exactly what the purpose of "deriving instace" is. I found the relevant references in the ghc compiler reference but the are far too cryptic and I cannot understand it.

I am attaching the full source in the attachment if you need to examine it. Hoping to see useful suggestions soon.

regards
--
Anand Mitra


On Mon, Jun 14, 2010 at 1:26 PM, Stephen Tetley <stephen.tetley@gmail.com> wrote:
Hello Anand

System.Directory.Tree is not a good candidate for serializing directly
- as you have found out, one of the constructors - Failed - carries an
IOException which cannot be serialized (IOExceptions may contain file
handles which are inherently runtime values).

Data.Binary is usually the best option for serialization. In your
case, you wont be able to make a 1-1 mapping between a runtime DirTree
and its on disk representation as you'll have to work out what to do
about 'Failed' - maybe you would want to only serialize the good
constructors - Dir and File - instead.

As you will have to coerce the data type a bit, I'd recommend using
Data.Binary to write the serialization, but rather than make instances
of Put and Get for DirTree instead give the serialize and deserialize
functions characteristic names e.g.
 serializeGoodTree / deserializeGoodTree.

Best wishes

Stephen