The composite design pattern implemented using record types,
where the named elements are the interface to the object

Overall, I think I agree with Tim that the record types are simpler to code.


I'm not sure, though, what would happen if I tried to add state to the
types. With the previous example, using existentials to create a reference
type that holds elements of a type class that matches the interface, I think
that it would be natural to hold state by having that element stored in a
mutable state variable, and replacing the held values.

In any case:

Two methods, add and draw

data Component = Component {
    draw :: String,
    add ::  Component -> Component
    }

A constructor for the leaf type, which holds a string

leaf :: String -> Component
leaf s =
    Component draw1 add1
              where draw1 = show s
                    add1 _ = leaf s

the draw method for the composite type
(because I was having trouble with layout and formating for 72 cols)

compositeDraw :: [Component] -> String
compositeDraw []  = "()"
compositeDraw leaves  = "(" ++ (foldr1 (++) $ map draw leaves) ++ ")"


A constructor for the composite type, which holds a list of components
and dispatches to the contained elements

composite :: [Component] -> Component
composite cs =
    Component draw1 add1
              where draw1 = compositeDraw cs
                    add1 c = composite $ c:cs



On 2/27/07, Tim Docker <[EMAIL PROTECTED]> wrote:

Steve Downey wrote:
> interesting. it leads to something that feels much more like an object
based, as opposed to a class based, system.
> as far as haskell is concerned, everything has the same type, even
though different instances have very different behavior.
> ....
> the question is, which plays nicer with the rest of haskell? that is, if
i'm not committing to a closed dsl, which style is more likely to be
reusable against other libraries.

I suspect there's no right answer - it's a case of choosing the
best approach for the problem. As an example, my charting library
(http://dockerz.net/software/chart.html) uses the record of functions
approach for composing drawings:

data Renderable = Renderable {
    minsize :: (Render RectSize)
    render :: (Rect -> Render ())
}

Tim





_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to