[Haskell-cafe] Data.Binary questions

Lauri Pesonen lauri.pesonen at iki.fi
Mon Jan 21 11:18:55 EST 2008


Hi Derek,

Thanks for the reply.

On 20/01/2008, Derek Elkins <derek.a.elkins at gmail.com> wrote:

> You may want to consider using the other side of Data.Binary rather than
> the Binary class.  The -class- Binary is intended for de/serialization
> when you don't care about the format.  From the documentation:
>
> "For parsing and generating simple external binary formats (e.g. C
> structures), Binary may be used, but in general is not suitable for
> complex protocols. Instead use the Put and Get primitives directly."

Yes, you are right. I read that bit of the documentation, but didn't
understand how to use the Get and Put primitives. So I started by
using the Binary class and after getting quick results carried on with
it. I'll rewrite what I have with Get and Put once I figure out how
they actually work.

> Nevertheless, one way to solve your problem is with a phantom type.
> Change MyList to,
> newtype MyList t e = MkList [e] deriving Show
>
> getLengthType :: MyList t e -> t
> getLengthType = undefined
>
...
>
> The asTypeOfs are just to propagate the type information around.  GHC's
> extension for scoped type variables would make this code simpler and
> more direct.  At any rate, now the code will use the Binary instance for
> whatever type t is to serialize the length.

Ah, very clever. Is this a common idiom in Haskell?

> If you mean that you there references to the constant table in e.g. the
> fields table then the problem here is that you need to the class methods
> to use that monad transformer (in this case, ReaderT is all you should
> need and not even that), but you can't change their type.  These are the
> kind of issues that make the Binary class unsuitable for this type of
> work.  If that is the case, the only way to use this is to explicitly
> write out the deserialization code rather than relying on get, i.e.
> you'll have to write a function 'getTable constantTable' that will
> deserialize the table.

As an example, a method is serialised in the class file as the
following structure:

  method_info {
    	u2 access_flags;
    	u2 name_index;
    	u2 descriptor_index;
    	u2 attributes_count;
    	attribute_info attributes[attributes_count];
    }

Both the name_index and the descriptor_index are indices that point
into the constants pool. In Haskell I would represent this as the type

data Method = Method Access String String [Attribute]

So I want to replace the indices with the actual strings that they
point to. I guess in the final deserialised version of the class file
the constant pool would not exist at all and it would be recreated
when the class file is serialised again.

So, AFAICT, I should be able to first deserialise the constants table
as part of deserialising the whole class file and then pass the
constant pool into the functions that deserialise fields, methods etc.
so that they are able to look up the constants from the pool.

I have to stare at the Get and Put primitives as well as ReaderT to
figure out how all this will work together. Let's call it a learning
experience.

-- 
  ! Lauri


More information about the Haskell-Cafe mailing list