z :: client -> Label client
z client = undefined
ok :: (B.Label client ~ A.Label client) =>
client -> [A.Label client].
ok client = [ A.z client, B.z client]
This technique relies on the explicit management of the identities of
modules both at compile-time (type annotation of D.ok) and run-time
(creation of (D client) in the body of D.ok). While explicit management
of modules at compile time is the point of the exercise, it would be
better to avoid the passing of reified module identities at runtime.
In particular, this variant requires all bindings in the module to take
an explicit parameter, instead of having a single parameter for the
whole module. Having a single module-identifier parameter for each
binding is better than having lots of individual parameters for each
binding, but the idea of a parameterized module is to avoid these
extra per-binding parameters alltogether.
Of course, my variant cheated a little, using the TF "feature" that
TF applications hide implicit parameters from contexts, so instead
of 'Label a~type=>type', we write 'Label a'. (which meant I had
to fix the 'a' to something concrete to avoid ambiguous types, as
I needed to use type families, not data families, to get the sharing)
Nevertheless, interesting possibilities.
Claus
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe