[Haskell-cafe] Re: [Haskell] ANN: Uniplate 1.0

Neil Mitchell ndmitchell at gmail.com
Mon Jun 18 20:58:42 EDT 2007


> The draft paper feels more readable and up-to-date than the manual.

That's very true! Originally there was a manual, now there is a paper
- perhaps I should take the manual down if people think that the paper
is sufficiently readable?

> However I have one comment about it.
> In the section on DERIVE for Uniplate instances, the type appearing
> directly in one of its own constructors is demonstrated being
> recognized, as is the type appearing in a list in one of its own
> constructors.  But no mention is made of just what powers the deriving
> has.

The scheme outlined in the paper is very powerful - it will work for
all data structures which don't contain a forall in the declaration.
It can only derive instances for entirely concrete data types, i.e.
you can't write an instance Maybe x, but you can write one instance
Maybe Bool. (PlateData/PlateTypeable do not have this restriction).

>  I presume lists are a special case (how else would it be
> possible),

For the implementation, Data.Derive has a special case for lists,
tuples and Maybe. Its a shame that only a restricted number of types
are supported - things like Data.Map/Data.Set can be supported
perfectly, apart from restrictions in Template Haskell. At derivation
time, if Data.Derive comes across Data.Set it cannot get at Data.Set's
internal structure, so it can't figure out how the instance should
look. This means that the number of data types within the constructor
is fixed, but can be easily extended.

I'm currently deciding what to do about this. One option is to look at
using SYB's reflection capabilities which do allow this, and saving
the result as an instance. Another option is to add special cases for
many more data types (Set/Map are both candidates). Perhaps template
haskell can even be persuaded to do some of what I want - I'm still
learning its power.

> Also is there any
> restriction on the placement of lists in the constructor? I can't see how
> data Foo = CFoo Foo [Foo] Foo [Foo] Foo
> could be translated. Does putting the list somewhere other than last work?

The list can come anywhere. Consider the simplest example:

data Foo = CFoo [Foo] [Foo]

The instance would have the same effect as:

instance Uniplate Foo where
    uniplate (CFoo x y) = (x ++ y, \z -> let (x2,y2) = splitAt (length
x) z in CFoo x2 y2)

(the actual instance would be a continuation passing variant of this,
and be more efficient, but still have the same meaning)

The key observation is that the length of the x field before and after
is the same, so the multiple lists can be split back into their
original sizes.



More information about the Haskell-Cafe mailing list