fjh at cs.mu.oz.au
Fri Sep 26 14:04:04 AEST 1997
Tomas By, you wrote:
> I'm writing an XML library. The interface consists of a
> document type and procedures to read/write/validate etc.
> The problem with XML documents is that apps might want to
> treat them either as a stream of elements or as a tree
> structure, and that you sometimes want to preserve
> whitespace and sometimes not.
> So you need four different types:
> stream with whitespace [ stream(byte) ]
> stream without whitespace [ stream(word) ]
> tree with whitespace [ tree(byte) ]
> tree without whitespace [ tree(word) ]
> "Fergus Henderson" <fjh at cs.mu.oz.au> wrote:
> > Why don't you want p/1 to handle things of other types?
> I want a procedure 'dump' for example that can handle all the
> four types above. The reason I don't want it to handle other
> things is I don't want to write the code. :-)
Well, one way to handle this is to have `dump' take a couple of
of predicates `DumpToken' and `DumpV' as additional arguments.
:- pred dump(item(V, T)::in,
pred(V, io__state, io__state)::(pred(in, di, uo) is det)
pred(T, io__state, io__state)::(pred(in, di, uo) is det)
io__state::di, io__state::uo) is det.
dump(v(V), DumpV, _DumpToken) --> DumpV(V).
dump(token(Token), _DumpV, DumpToken) --> DumpToken(Token).
dump(spec(Spec), _DumpV, _DumpToken) --> ...
Then if you want to dump a variable of type stream(byte), you call
`dump(ByteStream, dump_stream, dump_byte)':
dump(ByteStream, dump_stream, dump_byte).
This is basically the type-class approach, except that since we don't
yet support type classes, you simulate them using higher-order preds.
The other alternative is that you could just define `item' as a type
that can be either a tree or a stream, of either bytes or words:
:- type item
:- type token
You could then use insts as subtypes:
:- inst stream(I) == list_skel(stream(I)).
:- inst stream_item(I)
:- inst tree(I) == list_skel(tree(I)).
:- inst tree_item(I)
:- inst word_token
:- inst byte_token
Another approach is to use the item/0 type defined above,
but not bother with using insts as subtypes -- subtype errors
would then be detected at runtime (via calls to error/1) rather
than at compile time.
I'm really not sure which approach would be better;
I think any of these three approaches could work well.
Probably I'd be inclined to go with the simulate-type-classes approach.
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 18.104.22.168 | -- the last words of T. S. Garp.
More information about the users