:+: and all that and problems with existentials.

Nick Kallen nkallen@uclink4.berkeley.edu
Thu, 4 Mar 1999 14:14:12 -0800


It occurred to me last night that there was a simple way to do this. A
nonstandard (but nevertheless frequently used) Haskell trick:

:: MenuElement = E.a: MenuElement a | MenuElements a

instance MenuElements MenuElement where
	menuElementToHandles (MenuElement a) = menuElementToHandles a
	getMenuElementType (MenuElement a) = getMenuElementType a

When to my dismay it wouldn't type. I wanted to express (in (nonstandard)
Haskell):

data MenuElement = MenuElements a => MenuElement a

Evidently, Clean's overloaded use of the vertical pipe (|) is confusing in
algebraic types; It is my (not humble) opinion that this issue needs to be
addressed immediately. It is VERY useful to specify that type variables
(specifically existentially quantified ones) are instances of classes.

Now, that being said, you could use the (imo ugly) record-packing approach
used by the "OO Drawing Program" of the Clean book to similar effect
(although obviously not as powerful as type classes since you can't inherit
interfaces), but I'm not going to bother.

> It seems to me that this is the wrong direction. Here are some
> suggestions that might help:
>
> * use the dynamic properties of the object I/O library:
> every object in the object I/O library can be constructed at
> run-time (open and
> close menus, menu elements, and so on). Use the IODEVICE type and
> object I/O functions that create the proper elements. This might
> also fit better to your dynamic setting of a visual editor.
>
> * use overloading all the way:
> declare IODEVICE as an instance of the proper object I/O classes.
> (It should have two additional type variables, and probably also
> some more details).

This last provides the best insight into how to do this. Let's call AST the
result type of your parser (parseMenu, etc.). Make AST an instance of
MenuElements, and voila! (right?)