
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
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