
Tim Docker wrote:
Steve Downey wrote:
So, I've been working on a Composite example. I've used existential types to have a generic proxy to the base type, rather than a simple algebraic type, since adding new leaves to the algebraic type means modifying the whole type, a violation of the Open-Closed principle (open for extension, closed for modification)
Rather than using existential types, a simple record of functions can be often be useful. ie:
data Component = Component { draw :: String add :: Component -> Component }
It might be worth comparing this approach with the (more complex) one you have described.
The point about existential types is that every class like IComponent that allow as useful existential like data Component = forall e.(IComponent e) => Component e can be put into the record form Tim mentions. See the old wiki pages at http://haskell.org/hawiki/ExistentialTypes This is because every such IComponent has to look like class IComponent e where foo1 :: e -> ... -> e ... bar1 :: e -> ... ... where the dots in "-> ..." must not contain the type variable e. Regards, apfelmus